diff options
55 files changed, 899 insertions, 204 deletions
@@ -173,6 +173,7 @@ LOCAL_SRC_FILES += \ core/java/android/hardware/input/IInputManager.aidl \ core/java/android/hardware/input/IInputDevicesChangedListener.aidl \ core/java/android/hardware/location/IActivityRecognitionHardware.aidl \ + core/java/android/hardware/location/IActivityRecognitionHardwareClient.aidl \ core/java/android/hardware/location/IActivityRecognitionHardwareSink.aidl \ core/java/android/hardware/location/IActivityRecognitionHardwareWatcher.aidl \ core/java/android/hardware/location/IFusedLocationHardware.aidl \ diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java index 9f385fe..58c3a9c 100644 --- a/cmds/pm/src/com/android/commands/pm/Pm.java +++ b/cmds/pm/src/com/android/commands/pm/Pm.java @@ -983,6 +983,7 @@ public final class Pm { case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: return "ask"; case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS: return "always"; case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER: return "never"; + case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK : return "always ask"; } return "Unknown link state: " + state; } diff --git a/core/java/android/hardware/ICameraServiceProxy.aidl b/core/java/android/hardware/ICameraServiceProxy.aidl index 0bb24bc..0e654d5 100644 --- a/core/java/android/hardware/ICameraServiceProxy.aidl +++ b/core/java/android/hardware/ICameraServiceProxy.aidl @@ -19,6 +19,8 @@ package android.hardware; /** * Binder interface for the camera service proxy running in system_server. * + * Keep in sync with frameworks/av/include/camera/ICameraServiceProxy.h + * * @hide */ interface ICameraServiceProxy @@ -27,4 +29,9 @@ interface ICameraServiceProxy * Ping the service proxy to update the valid users for the camera service. */ oneway void pingForUserUpdate(); + + /** + * Update the status of a camera device + */ + oneway void notifyCameraState(String cameraId, int newCameraState); } diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java index 4a71aa0..20b0be1 100644 --- a/core/java/android/hardware/camera2/CameraDevice.java +++ b/core/java/android/hardware/camera2/CameraDevice.java @@ -480,8 +480,11 @@ public abstract class CameraDevice implements AutoCloseable { * the configurations in the tables below are also guaranteed for creating a reprocessable * capture session if the camera device supports YUV reprocessing or PRIVATE reprocessing. * However, not all output targets used to create a reprocessable session may be used in a - * {@link CaptureRequest} simultaneously. The guaranteed output targets that can be included - * in a {@link CaptureRequest} simultaneously are listed in the tables under + * {@link CaptureRequest} simultaneously. For devices that support only 1 output target in a + * reprocess {@link CaptureRequest}, submitting a reprocess {@link CaptureRequest} with multiple + * output targets will result in a {@link CaptureFailure}. For devices that support multiple + * output targets in a reprocess {@link CaptureRequest}, the guaranteed output targets that can + * be included in a {@link CaptureRequest} simultaneously are listed in the tables under * {@link #createCaptureSession createCaptureSession}. For example, with a FULL-capability * ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL} {@code == } * {@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_FULL FULL}) device that supports PRIVATE @@ -532,8 +535,6 @@ public abstract class CameraDevice implements AutoCloseable { * <tr> <td>{@code PRIV}/{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td>Same as input</td><td id="rb">{@code MAXIMUM}</td> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code YUV}</td><td id="rb">{@code RECORD}</td> <td></td><td id="rb"></td> <td>High-resolution ZSL in-app video processing with regular preview.</td> </tr> * <tr> <td>{@code PRIV}</td><td id="rb">{@code MAXIMUM}</td> <td>{@code PRIV}</td><td id="rb">{@code MAXIMUM}</td> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td></td><td id="rb"></td> <td>Maximum-resolution ZSL in-app processing with regular preview.</td> </tr> * <tr> <td>{@code PRIV}</td><td id="rb">{@code MAXIMUM}</td> <td>{@code PRIV}</td><td id="rb">{@code MAXIMUM}</td> <td>{@code YUV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td></td><td id="rb"></td> <td>Maximum-resolution two-input ZSL in-app processing.</td> </tr> - * <tr> <td>{@code PRIV}/{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td>Same as input</td><td id="rb">{@code MAXIMUM}</td> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code YUV}</td><td id="rb">{@code RECORD}</td> <td>{@code JPEG}</td><td id="rb">{@code RECORD}</td> <td>High-resolution ZSL in-app video processing and video snapshot with regular preview.</td> </tr> - * <tr> <td>{@code PRIV}</td><td id="rb">{@code MAXIMUM}</td> <td>{@code PRIV}</td><td id="rb">{@code MAXIMUM}</td> <td>{@code YUV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td>Maximum-resolution two-input ZSL in-app processing with regular preview.</td> </tr> * <tr> <td>{@code PRIV}/{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td>Same as input</td><td id="rb">{@code MAXIMUM}</td> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code YUV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code JPEG}</td><td id="rb">{@code MAXIMUM}</td> <td>ZSL still capture and in-app processing.</td> </tr> * </table><br> * </p> @@ -711,7 +712,9 @@ public abstract class CameraDevice implements AutoCloseable { * provide input images to camera device via {@link android.media.ImageWriter#queueInputImage}. * The application must use the capture result of one of those output images to create a * reprocess capture request so that the camera device can use the information to achieve - * optimal reprocess image quality. + * optimal reprocess image quality. For camera devices that support only 1 output + * {@link Surface}, submitting a reprocess {@link CaptureRequest} with multiple + * output targets will result in a {@link CaptureFailure}. * * @param inputResult The capture result of the output image or one of the output images used * to generate the reprocess input image for this capture request. diff --git a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java index e71e49f..b8d6960 100644 --- a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java +++ b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java @@ -1290,7 +1290,7 @@ public final class StreamConfigurationMap { for (StreamConfiguration config : configurations) { int fmt = config.getFormat(); if (fmt == format && config.isOutput() == output) { - if (output) { + if (output && mListHighResolution) { // Filter slow high-res output formats; include for // highRes, remove for !highRes long duration = 0; diff --git a/core/java/android/hardware/location/IActivityRecognitionHardwareClient.aidl b/core/java/android/hardware/location/IActivityRecognitionHardwareClient.aidl new file mode 100644 index 0000000..d2c3d75 --- /dev/null +++ b/core/java/android/hardware/location/IActivityRecognitionHardwareClient.aidl @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2015, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/license/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.location; + +import android.hardware.location.IActivityRecognitionHardware; + +/** + * Activity Recognition Hardware client interface. + * This interface can be used to receive interfaces to implementations of + * {@link IActivityRecognitionHardware}. + * + * @hide + */ +interface IActivityRecognitionHardwareClient { + /** + * Hardware Activity-Recognition availability event. + * + * @param isSupported whether the platform has hardware support for the feature + * @param instance the available instance to provide access to the feature + */ + void onAvailabilityChanged(in boolean isSupported, in IActivityRecognitionHardware instance); +} diff --git a/core/java/android/hardware/location/IActivityRecognitionHardwareWatcher.aidl b/core/java/android/hardware/location/IActivityRecognitionHardwareWatcher.aidl index 0507f52..12e3117 100644 --- a/core/java/android/hardware/location/IActivityRecognitionHardwareWatcher.aidl +++ b/core/java/android/hardware/location/IActivityRecognitionHardwareWatcher.aidl @@ -22,6 +22,8 @@ import android.hardware.location.IActivityRecognitionHardware; * Activity Recognition Hardware watcher. This interface can be used to receive interfaces to * implementations of {@link IActivityRecognitionHardware}. * + * @deprecated use {@link IActivityRecognitionHardwareClient} instead. + * @hide */ interface IActivityRecognitionHardwareWatcher { @@ -29,4 +31,4 @@ interface IActivityRecognitionHardwareWatcher { * Hardware Activity-Recognition availability event. */ void onInstanceChanged(in IActivityRecognitionHardware instance); -}
\ No newline at end of file +} diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java index 6962711..0cc1b25 100644 --- a/core/java/android/widget/AdapterView.java +++ b/core/java/android/widget/AdapterView.java @@ -612,7 +612,7 @@ public abstract class AdapterView<T extends Adapter> extends ViewGroup { View listItem = view; try { View v; - while (!(v = (View) listItem.getParent()).equals(this)) { + while ((v = (View) listItem.getParent()) != null && !v.equals(this)) { listItem = v; } } catch (ClassCastException e) { @@ -620,11 +620,13 @@ public abstract class AdapterView<T extends Adapter> extends ViewGroup { return INVALID_POSITION; } - // Search the children for the list item - final int childCount = getChildCount(); - for (int i = 0; i < childCount; i++) { - if (getChildAt(i).equals(listItem)) { - return mFirstPosition + i; + if (listItem != null) { + // Search the children for the list item + final int childCount = getChildCount(); + for (int i = 0; i < childCount; i++) { + if (getChildAt(i).equals(listItem)) { + return mFirstPosition + i; + } } } diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl index c1645c3..feed3903 100644 --- a/core/java/com/android/internal/statusbar/IStatusBar.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl @@ -69,5 +69,10 @@ oneway interface IStatusBar void showAssistDisclosure(); void startAssist(in Bundle args); + + /** + * Notifies the status bar that a camera launch gesture has been detected. + */ + void onCameraLaunchGestureDetected(); } diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index b3871f1..d24b10b 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -1275,6 +1275,12 @@ public class LockPatternUtils { */ public static final int SOME_AUTH_REQUIRED_AFTER_USER_REQUEST = 0x4; + /** + * Strong authentication is required because the user has been locked out after too many + * attempts. + */ + public static final int STRONG_AUTH_REQUIRED_AFTER_LOCKOUT = 0x8; + public static final int DEFAULT = STRONG_AUTH_REQUIRED_AFTER_BOOT; private static final int ALLOWING_FINGERPRINT = SOME_AUTH_REQUIRED_AFTER_USER_REQUEST; diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index b7eeb49..e0c4765 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -1042,7 +1042,7 @@ <string name="usb_ptp_notification_title" msgid="1347328437083192112">"USBを写真転送に使用"</string> <string name="usb_midi_notification_title" msgid="4850904915889144654">"USBをMIDIに使用"</string> <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USBアクセサリを接続しました"</string> - <string name="usb_notification_message" msgid="7347368030849048437">"タップするとその他のオプションが表示されます。"</string> + <string name="usb_notification_message" msgid="7347368030849048437">"タップしてその他のオプションを表示"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USBデバッグが接続されました"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"タップしてUSBデバッグを無効化"</string> <string name="select_input_method" msgid="8547250819326693584">"キーボードの変更"</string> diff --git a/core/res/res/values-mcc219-mnc02/config.xml b/core/res/res/values-mcc219-mnc02/config.xml new file mode 100644 index 0000000..2ac6ba6 --- /dev/null +++ b/core/res/res/values-mcc219-mnc02/config.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2015, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You my 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. +*/ +--> + +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- Don't use roaming icon for considered operators --> + <string-array translatable="false" name="config_operatorConsideredNonRoaming"> + <item>21901</item> + </string-array> +</resources> diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd index b57e6a7..39822e5 100644 --- a/docs/html/sdk/index.jd +++ b/docs/html/sdk/index.jd @@ -5,28 +5,28 @@ page.image=images/cards/android-studio_2x.png header.hide=1 page.metaDescription=Download the official Android IDE and developer tools to build apps for Android phones, tablets, wearables, TVs, and more. -studio.version=1.3.1.0 +studio.version=1.3.2.0 -studio.linux_bundle_download=android-studio-ide-141.2135290-linux.zip -studio.linux_bundle_bytes=351992670 -studio.linux_bundle_checksum=51e5f5de2b82883d87f85ee38cf7b7b8b2e7debf +studio.linux_bundle_download=android-studio-ide-141.2178183-linux.zip +studio.linux_bundle_bytes=352010593 +studio.linux_bundle_checksum=cf780413f8c8223eb348bd27c19a9c04b75eaeb2 -studio.mac_bundle_download=android-studio-ide-141.2135290-mac.dmg -studio.mac_bundle_bytes=368321249 -studio.mac_bundle_checksum=9fc12b5657ff52c761b7e7c115feade2a9728386 +studio.mac_bundle_download=android-studio-ide-141.2178183-mac.dmg +studio.mac_bundle_bytes=368335367 +studio.mac_bundle_checksum=75b67eb15a34a152a40e7189484ab0ebc375b877 -studio.win_bundle_download=android-studio-ide-141.2135290-windows.zip -studio.win_bundle_bytes=344406793 -studio.win_bundle_checksum=3b4c4924cb9495e56db61ca0e8c8d2bf588c4b97 +studio.win_bundle_download=android-studio-ide-141.2178183-windows.zip +studio.win_bundle_bytes=344424713 +studio.win_bundle_checksum=3134f226b5f3c3f74d4fc2d9cff03a4458f01d69 -studio.win_bundle_exe_download=android-studio-bundle-141.2135290-windows.exe -studio.win_bundle_exe_bytes=1008506096 -studio.win_bundle_exe_checksum=8cff590f2e08e339f8c2491b287a840ae87c7383 +studio.win_bundle_exe_download=android-studio-bundle-141.2178183-windows.exe +studio.win_bundle_exe_bytes=1136982712 +studio.win_bundle_exe_checksum=c7d39c529dd434489da9d086ff689d34dc791526 -studio.win_notools_exe_download=android-studio-ide-141.2135290-windows.exe -studio.win_notools_exe_bytes=321791312 -studio.win_notools_exe_checksum=d70fb49d03db9dded19c891a92452601e39272f4 +studio.win_notools_exe_download=android-studio-ide-141.2178183-windows.exe +studio.win_notools_exe_bytes=321810248 +studio.win_notools_exe_checksum=b5d1aaa000729c03a3cf980add79d1b93121c56d diff --git a/docs/html/tools/revisions/studio.jd b/docs/html/tools/revisions/studio.jd index c922b28..298b173 100644 --- a/docs/html/tools/revisions/studio.jd +++ b/docs/html/tools/revisions/studio.jd @@ -43,6 +43,29 @@ Android Studio, as denoted by revision number. </p> <div class="toggle-content opened"> <p><a href="#" onclick="return toggleContent(this)"> <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img" + alt=""/>Android Studio v1.3.2</a> <em>(August 2015)</em> + </p> + <div class="toggle-content-toggleme"> + <p>Fixes and enhancements:</p> + <ul> + <li>Added support for Android 6.0 (API level 23), including new icons and AVD Manager + support for creating devices with new screen densities.</li> + <li>Fixed an exception that was occuring during update checks. + <a href="http://b.android.com/183068">Issue: 183068</a></li> + <li>Fixed problem where unresolved view coordinates could cause the layout editor to crash. + <a href="http://b.android.com/178690">Issue: 178690</a></li> + <li>Fixed issue with invalid resource type warnings. + <a href="http://b.android.com/182433">Issue: 182433</a></li> + <li>Fixed lint check that was incorrectly flagging resources as private. + <a href="http://b.android.com/183120">Issue: 183120</a></li> + </ul> + </div> +</div> + + +<div class="toggle-content closed"> + <p><a href="#" onclick="return toggleContent(this)"> + <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img" alt=""/>Android Studio v1.3.1</a> <em>(August 2015)</em> </p> <div class="toggle-content-toggleme"> @@ -60,8 +83,6 @@ Android Studio, as denoted by revision number. </p> </div> - - <div class="toggle-content closed"> <p><a href="#" onclick="return toggleContent(this)"> <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img" @@ -100,7 +121,7 @@ Android Studio, as denoted by revision number. </p> <li>Added <a href="{@docRoot}tools/data-binding/guide.html">data binding</a> support to create declarative layouts that bind your application logic to layout elements. </li> <li>Added support for a separate - <a href="{@docRoot}tools/studio/studio-features.html#test-module">test APK module</a> + <a href="{@docRoot}tools/studio/studio-features.html#test-module">test APK module</a> to build test APKs in Android Studio. </li> <li>Updated the <a href="{@docRoot}tools/help/avd-manager.html">AVD Manager</a> with HAXM optimizations and improved notifications. </li> diff --git a/docs/html/tools/sdk/eclipse-adt.jd b/docs/html/tools/sdk/eclipse-adt.jd index 08634da..3c12a64 100644 --- a/docs/html/tools/sdk/eclipse-adt.jd +++ b/docs/html/tools/sdk/eclipse-adt.jd @@ -53,6 +53,39 @@ href="http://tools.android.com/knownissues">http://tools.android.com/knownissues <div class="toggle-content opened"> <p><a href="#" onclick="return toggleContent(this)"> <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img" + alt=""/>ADT 23.0.7</a> <em>(August 2015)</em> + </p> + + <div class="toggle-content-toggleme"> +<dl> + <dt>Dependencies:</dt> + + <dd> + <ul> + <li>Java 7 or higher is required if you are targeting Android 5.0 and higher.</li> + <li>Java 1.6 or higher is required if you are targeting other releases.</li> + <li>Eclipse Indigo (Version 3.7.2) or higher is required.</li> + <li>This version of ADT is designed for use with + <a href="{@docRoot}tools/sdk/tools-notes.html">SDK Tools r24.1.2</a>. + If you haven't already installed SDK Tools r24.1.2 into your SDK, use the + Android SDK Manager to do so.</li> + </ul> + </dd> + + <dt>General Notes:</dt> + <dd> + <ul> + <li>Fixed issues with the rendering library for the visual layout editor.</li> + </ul> + </dd> +</dl> +</div> +</div> + + +<div class="toggle-content closed"> + <p><a href="#" onclick="return toggleContent(this)"> + <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img" alt=""/>ADT 23.0.6</a> <em>(March 2015)</em> </p> @@ -75,7 +108,7 @@ href="http://tools.android.com/knownissues">http://tools.android.com/knownissues <dt>General Notes:</dt> <dd> <ul> - <li>Fixed issues with the rendering library.</li> + <li>Fixed issues with the rendering library for the visual layout editor.</li> </ul> </dd> </dl> diff --git a/graphics/java/android/graphics/drawable/RippleBackground.java b/graphics/java/android/graphics/drawable/RippleBackground.java index 1c14e2f..c7aa8c3 100644 --- a/graphics/java/android/graphics/drawable/RippleBackground.java +++ b/graphics/java/android/graphics/drawable/RippleBackground.java @@ -48,8 +48,8 @@ class RippleBackground extends RippleComponent { // Software rendering properties. private float mOpacity = 0; - public RippleBackground(RippleDrawable owner, Rect bounds) { - super(owner, bounds); + public RippleBackground(RippleDrawable owner, Rect bounds, boolean forceSoftware) { + super(owner, bounds, forceSoftware); } public boolean isVisible() { diff --git a/graphics/java/android/graphics/drawable/RippleComponent.java b/graphics/java/android/graphics/drawable/RippleComponent.java index 23a3ee3..2d378c6 100644 --- a/graphics/java/android/graphics/drawable/RippleComponent.java +++ b/graphics/java/android/graphics/drawable/RippleComponent.java @@ -52,9 +52,16 @@ abstract class RippleComponent { /** Screen density used to adjust pixel-based constants. */ protected float mDensity; - public RippleComponent(RippleDrawable owner, Rect bounds) { + /** + * If set, force all ripple animations to not run on RenderThread, even if it would be + * available. + */ + private final boolean mForceSoftware; + + public RippleComponent(RippleDrawable owner, Rect bounds, boolean forceSoftware) { mOwner = owner; mBounds = bounds; + mForceSoftware = forceSoftware; } public void onBoundsChange() { @@ -143,7 +150,7 @@ abstract class RippleComponent { * @return {@code true} if something was drawn, {@code false} otherwise */ public boolean draw(Canvas c, Paint p) { - final boolean hasDisplayListCanvas = c.isHardwareAccelerated() + final boolean hasDisplayListCanvas = !mForceSoftware && c.isHardwareAccelerated() && c instanceof DisplayListCanvas; if (mHasDisplayListCanvas != hasDisplayListCanvas) { mHasDisplayListCanvas = hasDisplayListCanvas; diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java index 464f3de..2690223 100644 --- a/graphics/java/android/graphics/drawable/RippleDrawable.java +++ b/graphics/java/android/graphics/drawable/RippleDrawable.java @@ -166,6 +166,12 @@ public class RippleDrawable extends LayerDrawable { private boolean mOverrideBounds; /** + * If set, force all ripple animations to not run on RenderThread, even if it would be + * available. + */ + private boolean mForceSoftware; + + /** * Constructor used for drawable inflation. */ RippleDrawable() { @@ -546,7 +552,7 @@ public class RippleDrawable extends LayerDrawable { */ private void tryBackgroundEnter(boolean focused) { if (mBackground == null) { - mBackground = new RippleBackground(this, mHotspotBounds); + mBackground = new RippleBackground(this, mHotspotBounds, mForceSoftware); } mBackground.setup(mState.mMaxRadius, mDensity); @@ -584,7 +590,7 @@ public class RippleDrawable extends LayerDrawable { } final boolean isBounded = isBounded(); - mRipple = new RippleForeground(this, mHotspotBounds, x, y, isBounded); + mRipple = new RippleForeground(this, mHotspotBounds, x, y, isBounded, mForceSoftware); } mRipple.setup(mState.mMaxRadius, mDensity); @@ -949,6 +955,16 @@ public class RippleDrawable extends LayerDrawable { } } + /** + * Sets whether to disable RenderThread animations for this ripple. + * + * @param forceSoftware true if RenderThread animations should be disabled, false otherwise + * @hide + */ + public void setForceSoftware(boolean forceSoftware) { + mForceSoftware = forceSoftware; + } + @Override public ConstantState getConstantState() { return mState; diff --git a/graphics/java/android/graphics/drawable/RippleForeground.java b/graphics/java/android/graphics/drawable/RippleForeground.java index 4853b04..c660846 100644 --- a/graphics/java/android/graphics/drawable/RippleForeground.java +++ b/graphics/java/android/graphics/drawable/RippleForeground.java @@ -87,8 +87,8 @@ class RippleForeground extends RippleComponent { private boolean mHasFinishedExit; public RippleForeground(RippleDrawable owner, Rect bounds, float startingX, float startingY, - boolean isBounded) { - super(owner, bounds); + boolean isBounded, boolean forceSoftware) { + super(owner, bounds, forceSoftware); mIsBounded = isBounded; mStartingX = startingX; diff --git a/location/lib/java/com/android/location/provider/ActivityRecognitionProvider.java b/location/lib/java/com/android/location/provider/ActivityRecognitionProvider.java index 25f9fa2..bc2dae1 100644 --- a/location/lib/java/com/android/location/provider/ActivityRecognitionProvider.java +++ b/location/lib/java/com/android/location/provider/ActivityRecognitionProvider.java @@ -31,8 +31,7 @@ import java.util.HashSet; */ public final class ActivityRecognitionProvider { private final IActivityRecognitionHardware mService; - private final HashSet<Sink> mSinkSet = new HashSet<Sink>(); - private final SinkTransport mSinkTransport = new SinkTransport(); + private final HashSet<Sink> mSinkSet = new HashSet<>(); // the following constants must remain in sync with activity_recognition.h @@ -62,7 +61,7 @@ public final class ActivityRecognitionProvider { throws RemoteException { Preconditions.checkNotNull(service); mService = service; - mService.registerSink(mSinkTransport); + mService.registerSink(new SinkTransport()); } public String[] getSupportedActivities() throws RemoteException { @@ -104,26 +103,23 @@ public final class ActivityRecognitionProvider { private final class SinkTransport extends IActivityRecognitionHardwareSink.Stub { @Override - public void onActivityChanged( - android.hardware.location.ActivityChangedEvent activityChangedEvent) { + public void onActivityChanged(android.hardware.location.ActivityChangedEvent event) { Collection<Sink> sinks; synchronized (mSinkSet) { if (mSinkSet.isEmpty()) { return; } - - sinks = new ArrayList<Sink>(mSinkSet); + sinks = new ArrayList<>(mSinkSet); } // translate the event from platform internal and GmsCore types - ArrayList<ActivityRecognitionEvent> gmsEvents = - new ArrayList<ActivityRecognitionEvent>(); - for (android.hardware.location.ActivityRecognitionEvent event - : activityChangedEvent.getActivityRecognitionEvents()) { + ArrayList<ActivityRecognitionEvent> gmsEvents = new ArrayList<>(); + for (android.hardware.location.ActivityRecognitionEvent reportingEvent + : event.getActivityRecognitionEvents()) { ActivityRecognitionEvent gmsEvent = new ActivityRecognitionEvent( - event.getActivity(), - event.getEventType(), - event.getTimestampNs()); + reportingEvent.getActivity(), + reportingEvent.getEventType(), + reportingEvent.getTimestampNs()); gmsEvents.add(gmsEvent); } ActivityChangedEvent gmsEvent = new ActivityChangedEvent(gmsEvents); diff --git a/location/lib/java/com/android/location/provider/ActivityRecognitionProviderClient.java b/location/lib/java/com/android/location/provider/ActivityRecognitionProviderClient.java new file mode 100644 index 0000000..0b878d7 --- /dev/null +++ b/location/lib/java/com/android/location/provider/ActivityRecognitionProviderClient.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.location.provider; + +import android.annotation.NonNull; +import android.hardware.location.IActivityRecognitionHardware; +import android.hardware.location.IActivityRecognitionHardwareClient; +import android.os.Binder; +import android.os.IBinder; +import android.os.Process; +import android.os.RemoteException; +import android.util.Log; + +/** + * A client class for interaction with an Activity-Recognition provider. + */ +public abstract class ActivityRecognitionProviderClient { + private static final String TAG = "ArProviderClient"; + + protected ActivityRecognitionProviderClient() {} + + private IActivityRecognitionHardwareClient.Stub mClient = + new IActivityRecognitionHardwareClient.Stub() { + @Override + public void onAvailabilityChanged( + boolean isSupported, + IActivityRecognitionHardware instance) { + int callingUid = Binder.getCallingUid(); + if (callingUid != Process.SYSTEM_UID) { + Log.d(TAG, "Ignoring calls from non-system server. Uid: " + callingUid); + return; + } + ActivityRecognitionProvider provider; + try { + provider = isSupported ? new ActivityRecognitionProvider(instance) : null; + } catch (RemoteException e) { + Log.e(TAG, "Error creating Hardware Activity-Recognition Provider.", e); + return; + } + onProviderChanged(isSupported, provider); + } + }; + + /** + * Gets the binder needed to interact with proxy provider in the platform. + */ + @NonNull + public IBinder getBinder() { + return mClient; + } + + /** + * Called when a change in the availability of {@link ActivityRecognitionProvider} is detected. + * + * @param isSupported whether the platform supports the provider natively + * @param instance the available provider's instance + */ + public abstract void onProviderChanged( + boolean isSupported, + ActivityRecognitionProvider instance); +} diff --git a/location/lib/java/com/android/location/provider/ActivityRecognitionProviderWatcher.java b/location/lib/java/com/android/location/provider/ActivityRecognitionProviderWatcher.java index 03dd042..7139025 100644 --- a/location/lib/java/com/android/location/provider/ActivityRecognitionProviderWatcher.java +++ b/location/lib/java/com/android/location/provider/ActivityRecognitionProviderWatcher.java @@ -28,7 +28,10 @@ import android.util.Log; /** * A watcher class for Activity-Recognition instances. + * + * @deprecated use {@link ActivityRecognitionProviderClient} instead. */ +@Deprecated public class ActivityRecognitionProviderWatcher { private static final String TAG = "ActivityRecognitionProviderWatcher"; diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index c00fdf3..37e0db0 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -104,6 +104,7 @@ <uses-permission android:name="android.permission.REGISTER_CALL_PROVIDER" /> <uses-permission android:name="android.permission.REGISTER_CONNECTION_MANAGER" /> <uses-permission android:name="android.permission.REGISTER_SIM_SUBSCRIPTION" /> + <uses-permission android:name="android.permission.GET_APP_OPS_STATS" /> <application android:label="@string/app_label"> <provider diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java index 2a84362..adc9b36 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java +++ b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java @@ -22,6 +22,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; +import android.graphics.Typeface; import android.media.projection.MediaProjectionManager; import android.media.projection.IMediaProjectionManager; import android.media.projection.IMediaProjection; @@ -29,7 +30,14 @@ import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; +import android.text.BidiFormatter; +import android.text.Spannable; +import android.text.SpannableString; +import android.text.TextPaint; +import android.text.TextUtils; +import android.text.style.StyleSpan; import android.util.Log; +import android.util.TypedValue; import android.view.WindowManager; import android.widget.CheckBox; import android.widget.CompoundButton; @@ -39,6 +47,8 @@ public class MediaProjectionPermissionActivity extends Activity implements DialogInterface.OnClickListener, CheckBox.OnCheckedChangeListener, DialogInterface.OnCancelListener { private static final String TAG = "MediaProjectionPermissionActivity"; + private static final float MAX_APP_NAME_SIZE_PX = 500f; + private static final String ELLIPSIS = "\u2026"; private boolean mPermanentGrant; private String mPackageName; @@ -84,11 +94,49 @@ public class MediaProjectionPermissionActivity extends Activity return; } - String appName = aInfo.loadLabel(packageManager).toString(); + TextPaint paint = new TextPaint(); + paint.setTextSize(42); + + String label = aInfo.loadLabel(packageManager).toString(); + + // If the label contains new line characters it may push the security + // message below the fold of the dialog. Labels shouldn't have new line + // characters anyways, so just truncate the message the first time one + // is seen. + final int labelLength = label.length(); + int offset = 0; + while (offset < labelLength) { + final int codePoint = label.codePointAt(offset); + final int type = Character.getType(codePoint); + if (type == Character.LINE_SEPARATOR + || type == Character.CONTROL + || type == Character.PARAGRAPH_SEPARATOR) { + label = label.substring(0, offset) + ELLIPSIS; + break; + } + offset += Character.charCount(codePoint); + } + + if (label.isEmpty()) { + label = mPackageName; + } + + String unsanitizedAppName = TextUtils.ellipsize(label, + paint, MAX_APP_NAME_SIZE_PX, TextUtils.TruncateAt.END).toString(); + String appName = BidiFormatter.getInstance().unicodeWrap(unsanitizedAppName); + + String actionText = getString(R.string.media_projection_dialog_text, appName); + SpannableString message = new SpannableString(actionText); + + int appNameIndex = actionText.indexOf(appName); + if (appNameIndex >= 0) { + message.setSpan(new StyleSpan(Typeface.BOLD), + appNameIndex, appNameIndex + appName.length(), 0); + } mDialog = new AlertDialog.Builder(this) .setIcon(aInfo.loadIcon(packageManager)) - .setMessage(getString(R.string.media_projection_dialog_text, appName)) + .setMessage(message) .setPositiveButton(R.string.media_projection_action_text, this) .setNegativeButton(android.R.string.cancel, this) .setView(R.layout.remember_permission_checkbox) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java index a1b07b5..025451d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java @@ -64,6 +64,7 @@ public class CommandQueue extends IStatusBar.Stub { private static final int MSG_APP_TRANSITION_STARTING = 21 << MSG_SHIFT; private static final int MSG_ASSIST_DISCLOSURE = 22 << MSG_SHIFT; private static final int MSG_START_ASSIST = 23 << MSG_SHIFT; + private static final int MSG_CAMERA_LAUNCH_GESTURE = 24 << MSG_SHIFT; public static final int FLAG_EXCLUDE_NONE = 0; public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0; @@ -109,6 +110,7 @@ public class CommandQueue extends IStatusBar.Stub { public void appTransitionStarting(long startTime, long duration); public void showAssistDisclosure(); public void startAssist(Bundle args); + public void onCameraLaunchGestureDetected(); } public CommandQueue(Callbacks callbacks, StatusBarIconList list) { @@ -293,6 +295,14 @@ public class CommandQueue extends IStatusBar.Stub { } } + @Override + public void onCameraLaunchGestureDetected() { + synchronized (mList) { + mHandler.removeMessages(MSG_CAMERA_LAUNCH_GESTURE); + mHandler.obtainMessage(MSG_CAMERA_LAUNCH_GESTURE).sendToTarget(); + } + } + private final class H extends Handler { public void handleMessage(Message msg) { final int what = msg.what & MSG_MASK; @@ -391,6 +401,9 @@ public class CommandQueue extends IStatusBar.Stub { case MSG_START_ASSIST: mCallbacks.startAssist((Bundle) msg.obj); break; + case MSG_CAMERA_LAUNCH_GESTURE: + mCallbacks.onCameraLaunchGestureDetected(); + break; } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java index 0aa4f6c..5f01306 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java @@ -24,6 +24,7 @@ import android.graphics.drawable.AnimatedVectorDrawable; import android.graphics.drawable.AnimationDrawable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; +import android.graphics.drawable.RippleDrawable; import android.service.notification.StatusBarNotification; import android.util.AttributeSet; import android.view.MotionEvent; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java index 164c496..8058933 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java @@ -36,6 +36,7 @@ import android.view.ViewAnimationUtils; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; import android.widget.ImageView; + import com.android.systemui.R; import com.android.systemui.statusbar.phone.KeyguardAffordanceHelper; import com.android.systemui.statusbar.phone.PhoneStatusBar; @@ -79,6 +80,7 @@ public class KeyguardAffordanceView extends ImageView { private float mRestingAlpha = KeyguardAffordanceHelper.SWIPE_RESTING_ALPHA_AMOUNT; private boolean mSupportHardware; private boolean mFinishing; + private boolean mLaunchingAffordance; private CanvasProperty<Float> mHwCircleRadius; private CanvasProperty<Float> mHwCenterX; @@ -152,7 +154,7 @@ public class KeyguardAffordanceView extends ImageView { @Override protected void onDraw(Canvas canvas) { - mSupportHardware = canvas.isHardwareAccelerated(); + mSupportHardware = false;//canvas.isHardwareAccelerated(); drawBackgroundCircle(canvas); canvas.save(); canvas.scale(mImageScale, mImageScale, getWidth() / 2, getHeight() / 2); @@ -161,9 +163,11 @@ public class KeyguardAffordanceView extends ImageView { } public void setPreviewView(View v) { + View oldPreviewView = mPreviewView; mPreviewView = v; if (mPreviewView != null) { - mPreviewView.setVisibility(INVISIBLE); + mPreviewView.setVisibility(mLaunchingAffordance + ? oldPreviewView.getVisibility() : INVISIBLE); } } @@ -176,7 +180,7 @@ public class KeyguardAffordanceView extends ImageView { } private void drawBackgroundCircle(Canvas canvas) { - if (mCircleRadius > 0) { + if (mCircleRadius > 0 || mFinishing) { if (mFinishing && mSupportHardware) { DisplayListCanvas displayListCanvas = (DisplayListCanvas) canvas; displayListCanvas.drawCircle(mHwCenterX, mHwCenterY, mHwCircleRadius, @@ -207,11 +211,12 @@ public class KeyguardAffordanceView extends ImageView { cancelAnimator(mPreviewClipper); mFinishing = true; mCircleStartRadius = mCircleRadius; - float maxCircleSize = getMaxCircleSize(); + final float maxCircleSize = getMaxCircleSize(); Animator animatorToRadius; if (mSupportHardware) { initHwProperties(); animatorToRadius = getRtAnimatorToRadius(maxCircleSize); + startRtAlphaFadeIn(); } else { animatorToRadius = getAnimatorToRadius(maxCircleSize); } @@ -222,6 +227,8 @@ public class KeyguardAffordanceView extends ImageView { public void onAnimationEnd(Animator animation) { mAnimationEndRunnable.run(); mFinishing = false; + mCircleRadius = maxCircleSize; + invalidate(); } }); animatorToRadius.start(); @@ -241,6 +248,36 @@ public class KeyguardAffordanceView extends ImageView { } } + /** + * Fades in the Circle on the RenderThread. It's used when finishing the circle when it had + * alpha 0 in the beginning. + */ + private void startRtAlphaFadeIn() { + if (mCircleRadius == 0 && mPreviewView == null) { + Paint modifiedPaint = new Paint(mCirclePaint); + modifiedPaint.setColor(mCircleColor); + modifiedPaint.setAlpha(0); + mHwCirclePaint = CanvasProperty.createPaint(modifiedPaint); + RenderNodeAnimator animator = new RenderNodeAnimator(mHwCirclePaint, + RenderNodeAnimator.PAINT_ALPHA, 255); + animator.setTarget(this); + animator.setInterpolator(PhoneStatusBar.ALPHA_IN); + animator.setDuration(250); + animator.start(); + } + } + + public void instantFinishAnimation() { + cancelAnimator(mPreviewClipper); + if (mPreviewView != null) { + mPreviewView.setClipBounds(null); + mPreviewView.setVisibility(View.VISIBLE); + } + mCircleRadius = getMaxCircleSize(); + setImageAlpha(0, false); + invalidate(); + } + private void startRtCircleFadeOut(long duration) { RenderNodeAnimator animator = new RenderNodeAnimator(mHwCirclePaint, RenderNodeAnimator.PAINT_ALPHA, 0); @@ -443,6 +480,7 @@ public class KeyguardAffordanceView extends ImageView { public void setImageAlpha(float alpha, boolean animate, long duration, Interpolator interpolator, Runnable runnable) { cancelAnimator(mAlphaAnimator); + alpha = mLaunchingAffordance ? 0 : alpha; int endAlpha = (int) (alpha * 255); final Drawable background = getBackground(); if (!animate) { @@ -509,4 +547,8 @@ public class KeyguardAffordanceView extends ImageView { return false; } } + + public void setLaunchingAffordance(boolean launchingAffordance) { + mLaunchingAffordance = launchingAffordance; + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java index 01aa8d1..8688c28 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java @@ -86,6 +86,9 @@ public class NotificationBackgroundView extends View { if (mBackground != null) { mBackground.setCallback(this); } + if (mBackground instanceof RippleDrawable) { + ((RippleDrawable) mBackground).setForceSoftware(true); + } invalidate(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java index 28d4a42..4e69999 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java @@ -183,8 +183,11 @@ public class FingerprintUnlockController extends KeyguardUpdateMonitorCallback { mStatusBarKeyguardViewManager.animateCollapsePanels( FINGERPRINT_COLLAPSE_SPEEDUP_FACTOR); break; - case MODE_WAKE_AND_UNLOCK: case MODE_WAKE_AND_UNLOCK_PULSING: + mPhoneStatusBar.updateMediaMetaData(false /* metaDataChanged */); + // Fall through. + case MODE_WAKE_AND_UNLOCK: + mStatusBarWindowManager.setStatusBarFocusable(false); mDozeScrimController.abortPulsing(); mKeyguardViewMediator.onWakeAndUnlocking(); mScrimController.setWakeAndUnlocking(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java index 10019f9..60ebfdf 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java @@ -86,9 +86,9 @@ public class KeyguardAffordanceHelper { mContext = context; mCallback = callback; initIcons(); - updateIcon(mLeftIcon, 0.0f, mLeftIcon.getRestingAlpha(), false, false, true); - updateIcon(mCenterIcon, 0.0f, mCenterIcon.getRestingAlpha(), false, false, true); - updateIcon(mRightIcon, 0.0f, mRightIcon.getRestingAlpha(), false, false, true); + updateIcon(mLeftIcon, 0.0f, mLeftIcon.getRestingAlpha(), false, false, true, false); + updateIcon(mCenterIcon, 0.0f, mCenterIcon.getRestingAlpha(), false, false, true, false); + updateIcon(mRightIcon, 0.0f, mRightIcon.getRestingAlpha(), false, false, true, false); initDimens(); } @@ -144,9 +144,7 @@ public class KeyguardAffordanceHelper { } else { mTouchSlopExeeded = false; } - mCallback.onSwipingStarted(targetView == mRightIcon); - mSwipingInProgress = true; - mTargetedView = targetView; + startSwiping(targetView); mInitialTouchX = x; mInitialTouchY = y; mTranslationOnDown = mTranslation; @@ -192,6 +190,12 @@ public class KeyguardAffordanceHelper { return true; } + private void startSwiping(View targetView) { + mCallback.onSwipingStarted(targetView == mRightIcon); + mSwipingInProgress = true; + mTargetedView = targetView; + } + private View getIconAtPosition(float x, float y) { if (leftSwipePossible() && isOnIcon(mLeftIcon, x, y)) { return mLeftIcon; @@ -324,7 +328,7 @@ public class KeyguardAffordanceHelper { boolean velIsInWrongDirection = vel * mTranslation < 0; snapBack |= Math.abs(vel) > mMinFlingVelocity && velIsInWrongDirection; vel = snapBack ^ velIsInWrongDirection ? 0 : vel; - fling(vel, snapBack || forceSnapBack); + fling(vel, snapBack || forceSnapBack, mTranslation < 0); } private boolean isBelowFalsingThreshold() { @@ -336,9 +340,8 @@ public class KeyguardAffordanceHelper { return (int) (mMinTranslationAmount * factor); } - private void fling(float vel, final boolean snapBack) { - float target = mTranslation < 0 - ? -mCallback.getMaxTranslationDistance() + private void fling(float vel, final boolean snapBack, boolean right) { + float target = right ? -mCallback.getMaxTranslationDistance() : mCallback.getMaxTranslationDistance(); target = snapBack ? 0 : target; @@ -352,8 +355,8 @@ public class KeyguardAffordanceHelper { }); animator.addListener(mFlingEndListener); if (!snapBack) { - startFinishingCircleAnimation(vel * 0.375f, mAnimationEndRunnable); - mCallback.onAnimationToSideStarted(mTranslation < 0, mTranslation, vel); + startFinishingCircleAnimation(vel * 0.375f, mAnimationEndRunnable, right); + mCallback.onAnimationToSideStarted(right, mTranslation, vel); } else { reset(true); } @@ -364,8 +367,9 @@ public class KeyguardAffordanceHelper { } } - private void startFinishingCircleAnimation(float velocity, Runnable mAnimationEndRunnable) { - KeyguardAffordanceView targetView = mTranslation > 0 ? mLeftIcon : mRightIcon; + private void startFinishingCircleAnimation(float velocity, Runnable mAnimationEndRunnable, + boolean right) { + KeyguardAffordanceView targetView = right ? mRightIcon : mLeftIcon; targetView.finishAnimation(velocity, mAnimationEndRunnable); } @@ -383,19 +387,20 @@ public class KeyguardAffordanceHelper { fadeOutAlpha = Math.max(fadeOutAlpha, 0.0f); boolean animateIcons = isReset && animateReset; + boolean forceNoCircleAnimation = isReset && !animateReset; float radius = getRadiusFromTranslation(absTranslation); boolean slowAnimation = isReset && isBelowFalsingThreshold(); if (!isReset) { updateIcon(targetView, radius, alpha + fadeOutAlpha * targetView.getRestingAlpha(), - false, false, false); + false, false, false, false); } else { updateIcon(targetView, 0.0f, fadeOutAlpha * targetView.getRestingAlpha(), - animateIcons, slowAnimation, false); + animateIcons, slowAnimation, false, forceNoCircleAnimation); } updateIcon(otherView, 0.0f, fadeOutAlpha * otherView.getRestingAlpha(), - animateIcons, slowAnimation, false); + animateIcons, slowAnimation, false, forceNoCircleAnimation); updateIcon(mCenterIcon, 0.0f, fadeOutAlpha * mCenterIcon.getRestingAlpha(), - animateIcons, slowAnimation, false); + animateIcons, slowAnimation, false, forceNoCircleAnimation); mTranslation = translation; } @@ -431,16 +436,21 @@ public class KeyguardAffordanceHelper { public void animateHideLeftRightIcon() { cancelAnimation(); - updateIcon(mRightIcon, 0f, 0f, true, false, false); - updateIcon(mLeftIcon, 0f, 0f, true, false, false); + updateIcon(mRightIcon, 0f, 0f, true, false, false, false); + updateIcon(mLeftIcon, 0f, 0f, true, false, false, false); } private void updateIcon(KeyguardAffordanceView view, float circleRadius, float alpha, - boolean animate, boolean slowRadiusAnimation, boolean force) { + boolean animate, boolean slowRadiusAnimation, boolean force, + boolean forceNoCircleAnimation) { if (view.getVisibility() != View.VISIBLE && !force) { return; } - view.setCircleRadius(circleRadius, slowRadiusAnimation); + if (forceNoCircleAnimation) { + view.setCircleRadiusWithoutAnimation(circleRadius); + } else { + view.setCircleRadius(circleRadius, slowRadiusAnimation); + } updateIconAlpha(view, alpha, animate); } @@ -503,8 +513,36 @@ public class KeyguardAffordanceHelper { mMotionCancelled = true; if (mSwipingInProgress) { mCallback.onSwipingAborted(); + mSwipingInProgress = false; + } + } + + public boolean isSwipingInProgress() { + return mSwipingInProgress; + } + + public void launchAffordance(boolean animate, boolean left) { + if (mSwipingInProgress) { + // We don't want to mess with the state if the user is actually swiping already. + return; + } + KeyguardAffordanceView targetView = left ? mLeftIcon : mRightIcon; + KeyguardAffordanceView otherView = left ? mRightIcon : mLeftIcon; + startSwiping(targetView); + if (animate) { + fling(0, false, !left); + updateIcon(otherView, 0.0f, 0, true, false, true, false); + updateIcon(mCenterIcon, 0.0f, 0, true, false, true, false); + } else { + mCallback.onAnimationToSideStarted(!left, mTranslation, 0); + mTranslation = left ? mCallback.getMaxTranslationDistance() + : mCallback.getMaxTranslationDistance(); + updateIcon(mCenterIcon, 0.0f, 0.0f, false, false, true, false); + updateIcon(otherView, 0.0f, 0.0f, false, false, true, false); + targetView.instantFinishAnimation(); + mFlingEndListener.onAnimationEnd(null); + mAnimationEndRunnable.run(); } - mSwipingInProgress = false; } public interface Callback { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java index 579889d..d30411a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java @@ -80,7 +80,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL 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 = + public static final Intent INSECURE_CAMERA_INTENT = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA); private static final Intent PHONE_INTENT = new Intent(Intent.ACTION_DIAL); private static final int DOZE_ANIMATION_STAGGER_DELAY = 48; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java index 5be768d..5557f9c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -203,6 +203,7 @@ public class NotificationPanelView extends PanelView implements private int mLastOrientation = -1; private boolean mClosingWithAlphaFadeOut; private boolean mHeadsUpAnimatingAway; + private boolean mLaunchingAffordance; private Runnable mHeadsUpExistenceChangedRunnable = new Runnable() { @Override @@ -488,7 +489,9 @@ public class NotificationPanelView extends PanelView implements mIsLaunchTransitionFinished = false; mBlockTouches = false; mUnlockIconActive = false; - mAfforanceHelper.reset(true); + if (!mLaunchingAffordance) { + mAfforanceHelper.reset(false); + } closeQs(); mStatusBar.dismissPopups(); mNotificationStackScroller.setOverScrollAmount(0f, true /* onTop */, false /* animate */, @@ -2393,4 +2396,36 @@ public class NotificationPanelView extends PanelView implements public boolean hasOverlappingRendering() { return !mDozing; } + + public void launchCamera(boolean animate) { + // If we are launching it when we are occluded already we don't want it to animate, + // nor setting these flags, since the occluded state doesn't change anymore, hence it's + // never reset. + if (!isFullyCollapsed()) { + mLaunchingAffordance = true; + setLaunchingAffordance(true); + } else { + animate = false; + } + mAfforanceHelper.launchAffordance(animate, getLayoutDirection() == LAYOUT_DIRECTION_RTL); + } + + public void onAffordanceLaunchEnded() { + mLaunchingAffordance = false; + setLaunchingAffordance(false); + } + + /** + * Set whether we are currently launching an affordance. This is currently only set when + * launched via a camera gesture. + */ + private void setLaunchingAffordance(boolean launchingAffordance) { + getLeftIcon().setLaunchingAffordance(launchingAffordance); + getRightIcon().setLaunchingAffordance(launchingAffordance); + getCenterIcon().setLaunchingAffordance(launchingAffordance); + } + + public boolean canCameraGestureBeLaunched() { + return !mAfforanceHelper.isSwipingInProgress(); + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 649dad3..8063bbe 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -66,6 +66,7 @@ import android.os.ServiceManager; import android.os.SystemClock; import android.os.UserHandle; import android.os.UserManager; +import android.os.Vibrator; import android.provider.Settings; import android.service.notification.NotificationListenerService; import android.service.notification.NotificationListenerService.RankingMap; @@ -482,6 +483,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, private Runnable mLaunchTransitionEndRunnable; private boolean mLaunchTransitionFadingAway; private ExpandableNotificationRow mDraggedDownRow; + private boolean mLaunchCameraOnScreenTurningOn; + private PowerManager.WakeLock mGestureWakeLock; + private Vibrator mVibrator; // Fingerprint (as computed by getLoggingFingerprint() of the last logged state. private int mLastLoggedStateFingerprint; @@ -903,7 +907,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); mBroadcastReceiver.onReceive(mContext, new Intent(pm.isScreenOn() ? Intent.ACTION_SCREEN_ON : Intent.ACTION_SCREEN_OFF)); - + mGestureWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, + "GestureWakeLock"); + mVibrator = mContext.getSystemService(Vibrator.class); // receive broadcasts IntentFilter filter = new IntentFilter(); @@ -1694,7 +1700,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, final boolean hasArtwork = artworkBitmap != null; if ((hasArtwork || DEBUG_MEDIA_FAKE_ARTWORK) - && (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)) { + && (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) + && mFingerprintUnlockController.getMode() + != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING) { // time to show some art! if (mBackdrop.getVisibility() != View.VISIBLE) { mBackdrop.setVisibility(View.VISIBLE); @@ -1749,31 +1757,40 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, if (DEBUG_MEDIA) { Log.v(TAG, "DEBUG_MEDIA: Fading out album artwork"); } - mBackdrop.animate() - // Never let the alpha become zero - otherwise the RenderNode - // won't draw anything and uninitialized memory will show through - // if mScrimSrcModeEnabled. Note that 0.001 is rounded down to 0 in libhwui. - .alpha(0.002f) - .setInterpolator(mBackdropInterpolator) - .setDuration(300) - .setStartDelay(0) - .withEndAction(new Runnable() { - @Override - public void run() { - mBackdrop.setVisibility(View.GONE); - mBackdropFront.animate().cancel(); - mBackdropBack.animate().cancel(); - mHandler.post(mHideBackdropFront); - } - }); - if (mKeyguardFadingAway) { - mBackdrop.animate() + if (mFingerprintUnlockController.getMode() + == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING) { - // Make it disappear faster, as the focus should be on the activity behind. - .setDuration(mKeyguardFadingAwayDuration / 2) - .setStartDelay(mKeyguardFadingAwayDelay) - .setInterpolator(mLinearInterpolator) - .start(); + // We are unlocking directly - no animation! + mBackdrop.setVisibility(View.GONE); + } else { + mBackdrop.animate() + // Never let the alpha become zero - otherwise the RenderNode + // won't draw anything and uninitialized memory will show through + // if mScrimSrcModeEnabled. Note that 0.001 is rounded down to 0 in + // libhwui. + .alpha(0.002f) + .setInterpolator(mBackdropInterpolator) + .setDuration(300) + .setStartDelay(0) + .withEndAction(new Runnable() { + @Override + public void run() { + mBackdrop.setVisibility(View.GONE); + mBackdropFront.animate().cancel(); + mBackdropBack.animate().cancel(); + mHandler.post(mHideBackdropFront); + } + }); + if (mKeyguardFadingAway) { + mBackdrop.animate() + + // Make it disappear faster, as the focus should be on the activity + // behind. + .setDuration(mKeyguardFadingAwayDuration / 2) + .setStartDelay(mKeyguardFadingAwayDelay) + .setInterpolator(mLinearInterpolator) + .start(); + } } } } @@ -2436,8 +2453,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, || mStatusBarMode == MODE_LIGHTS_OUT_TRANSPARENT); boolean allowLight = isTransparentBar && !mBatteryController.isPowerSave(); boolean light = (vis & View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR) != 0; - - mIconController.setIconsDark(allowLight && light); + boolean animate = mFingerprintUnlockController == null + || (mFingerprintUnlockController.getMode() + != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING + && mFingerprintUnlockController.getMode() + != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK); + mIconController.setIconsDark(allowLight && light, animate); } // restore the recents bit if (wasRecentsVisible) { @@ -3370,6 +3391,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, private void onLaunchTransitionFadingEnded() { mNotificationPanel.setAlpha(1.0f); + mNotificationPanel.onAffordanceLaunchEnded(); + releaseGestureWakeLock(); runLaunchTransitionEndRunnable(); mLaunchTransitionFadingAway = false; mScrimController.forceHideScrims(false /* hide */); @@ -3457,6 +3480,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, private void onLaunchTransitionTimeout() { Log.w(TAG, "Launch transition: Timeout!"); + mNotificationPanel.onAffordanceLaunchEnded(); + releaseGestureWakeLock(); mNotificationPanel.resetViews(); } @@ -3508,10 +3533,18 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mQSPanel.refreshAllTiles(); } mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT); + releaseGestureWakeLock(); + mNotificationPanel.onAffordanceLaunchEnded(); mNotificationPanel.setAlpha(1f); return staying; } + private void releaseGestureWakeLock() { + if (mGestureWakeLock.isHeld()) { + mGestureWakeLock.release(); + } + } + public long calculateGoingToFullShadeDelay() { return mKeyguardFadingAwayDelay + mKeyguardFadingAwayDuration; } @@ -3636,6 +3669,11 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, return mState == StatusBarState.KEYGUARD && mStatusBarKeyguardViewManager.onMenuPressed(); } + public void endAffordanceLaunch() { + releaseGestureWakeLock(); + mNotificationPanel.onAffordanceLaunchEnded(); + } + public boolean onBackPressed() { if (mStatusBarKeyguardViewManager.onBackPressed()) { return true; @@ -3867,6 +3905,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } public void onFinishedGoingToSleep() { + mNotificationPanel.onAffordanceLaunchEnded(); + releaseGestureWakeLock(); + mLaunchCameraOnScreenTurningOn = false; mDeviceInteractive = false; mWakeUpComingFromTouch = false; mWakeUpTouchLocation = null; @@ -3883,6 +3924,14 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, public void onScreenTurningOn() { mNotificationPanel.onScreenTurningOn(); + if (mLaunchCameraOnScreenTurningOn) { + mNotificationPanel.launchCamera(false); + mLaunchCameraOnScreenTurningOn = false; + } + } + + private void vibrateForCameraGesture() { + mVibrator.vibrate(1000L); } public void onScreenTurnedOn() { @@ -4029,8 +4078,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, public void appTransitionStarting(long startTime, long duration) { // Use own timings when Keyguard is going away, see keyguardGoingAway and - // setKeyguardFadingAway - if (!mKeyguardFadingAway) { + // setKeyguardFadingAway. When duration is 0, skip this one because no animation is really + // playing. + if (!mKeyguardFadingAway && duration > 0) { mIconController.appTransitionStarting(startTime, duration); } if (mIconPolicy != null) { @@ -4038,6 +4088,39 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } } + @Override + public void onCameraLaunchGestureDetected() { + if (!mNotificationPanel.canCameraGestureBeLaunched()) { + return; + } + if (!mDeviceInteractive) { + PowerManager pm = mContext.getSystemService(PowerManager.class); + pm.wakeUp(SystemClock.uptimeMillis(), "com.android.systemui:CAMERA_GESTURE"); + mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested(); + } + vibrateForCameraGesture(); + if (!mStatusBarKeyguardViewManager.isShowing()) { + startActivity(KeyguardBottomAreaView.INSECURE_CAMERA_INTENT, + true /* dismissShade */); + } else { + if (!mDeviceInteractive) { + // Avoid flickering of the scrim when we instant launch the camera and the bouncer + // comes on. + mScrimController.dontAnimateBouncerChangesUntilNextFrame(); + mGestureWakeLock.acquire(LAUNCH_TRANSITION_TIMEOUT_MS + 1000L); + } + if (mStatusBarKeyguardViewManager.isScreenTurnedOn()) { + mNotificationPanel.launchCamera(mDeviceInteractive /* animate */); + } else { + // We need to defer the camera launch until the screen comes on, since otherwise + // we will dismiss us too early since we are waiting on an activity to be drawn and + // incorrectly get notified because of the screen on event (which resumes and pauses + // some activities) + mLaunchCameraOnScreenTurningOn = true; + } + } + } + public void notifyFpAuthModeChanged() { updateDozing(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java index cc6f396..b9e9292 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java @@ -87,6 +87,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, private View mDraggedHeadsUpView; private boolean mForceHideScrims; private boolean mSkipFirstFrame; + private boolean mDontAnimateBouncerChanges; public ScrimController(ScrimView scrimBehind, ScrimView scrimInFront, View headsUpScrim, boolean scrimSrcEnabled) { @@ -125,7 +126,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, public void setBouncerShowing(boolean showing) { mBouncerShowing = showing; - mAnimateChange = !mExpanding; + mAnimateChange = !mExpanding && !mDontAnimateBouncerChanges; scheduleUpdate(); } @@ -360,6 +361,9 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, public boolean onPreDraw() { mScrimBehind.getViewTreeObserver().removeOnPreDrawListener(this); mUpdatePending = false; + if (mDontAnimateBouncerChanges) { + mDontAnimateBouncerChanges = false; + } updateScrims(); mDurationOverride = -1; mAnimationDelay = 0; @@ -496,4 +500,8 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, mAnimateChange = false; scheduleUpdate(); } + + public void dontAnimateBouncerChangesUntilNextFrame() { + mDontAnimateBouncerChanges = true; + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java index a1e9ece..18db5b8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsButton.java @@ -19,6 +19,7 @@ import android.animation.Animator; import android.animation.Animator.AnimatorListener; import android.animation.ObjectAnimator; import android.content.Context; +import android.graphics.drawable.RippleDrawable; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java index 7ee47df..e9c4e49 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java @@ -26,6 +26,7 @@ import android.graphics.Outline; import android.graphics.Rect; import android.graphics.drawable.Animatable; import android.graphics.drawable.Drawable; +import android.graphics.drawable.RippleDrawable; import android.util.AttributeSet; import android.util.MathUtils; import android.util.TypedValue; @@ -184,6 +185,12 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL } }); requestCaptureValues(); + + // RenderThread is doing more harm than good when touching the header (to expand quick + // settings), so disable it for this view + ((RippleDrawable) getBackground()).setForceSoftware(true); + ((RippleDrawable) mSettingsButton.getBackground()).setForceSoftware(true); + ((RippleDrawable) mSystemIconsSuperContainer.getBackground()).setForceSoftware(true); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java index 067e50e..5de1c13 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java @@ -335,8 +335,10 @@ public class StatusBarIconController implements Tunable { } } - public void setIconsDark(boolean dark) { - if (mTransitionPending) { + public void setIconsDark(boolean dark, boolean animate) { + if (!animate) { + setIconTintInternal(dark ? 1.0f : 0.0f); + } else if (mTransitionPending) { deferIconTintChange(dark ? 1.0f : 0.0f); } else if (mTransitionDeferring) { animateIconTint(dark ? 1.0f : 0.0f, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index 59ee5c5..d0604c5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -179,6 +179,10 @@ public class StatusBarKeyguardViewManager { mPhoneStatusBar.onScreenTurningOn(); } + public boolean isScreenTurnedOn() { + return mScreenTurnedOn; + } + public void onScreenTurnedOn() { mScreenTurnedOn = true; if (mDeferScrimFadeOut) { @@ -385,6 +389,7 @@ public class StatusBarKeyguardViewManager { */ public boolean onBackPressed() { if (mBouncer.isShowing()) { + mPhoneStatusBar.endAffordanceLaunch(); reset(); return true; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java index 82064a7..cf696a1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java @@ -127,7 +127,7 @@ public class StackScrollAlgorithm { mCollapseSecondCardPadding = context.getResources().getDimensionPixelSize( R.dimen.notification_collapse_second_card_padding); mScaleDimmed = context.getResources().getDisplayMetrics().densityDpi - >= DisplayMetrics.DENSITY_XXHIGH; + >= DisplayMetrics.DENSITY_420; } public boolean shouldScaleDimmed() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java index 920b682..2587b9f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java @@ -171,6 +171,10 @@ public class TvStatusBar extends BaseStatusBar { } @Override + public void onCameraLaunchGestureDetected() { + } + + @Override protected void updateHeadsUp(String key, NotificationData.Entry entry, boolean shouldInterrupt, boolean alertAgain) { } diff --git a/services/core/java/com/android/server/GestureLauncherService.java b/services/core/java/com/android/server/GestureLauncherService.java index 55af9f0..38ba793 100644 --- a/services/core/java/com/android/server/GestureLauncherService.java +++ b/services/core/java/com/android/server/GestureLauncherService.java @@ -19,12 +19,9 @@ package com.android.server; import android.app.ActivityManager; import android.app.KeyguardManager; import android.content.BroadcastReceiver; -import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; import android.content.res.Resources; import android.database.ContentObserver; import android.hardware.Sensor; @@ -35,12 +32,12 @@ import android.os.Handler; import android.os.PowerManager; import android.os.PowerManager.WakeLock; import android.os.SystemProperties; -import android.os.UserHandle; import android.os.Vibrator; -import android.provider.MediaStore; import android.provider.Settings; import android.util.Slog; +import com.android.server.statusbar.StatusBarManagerInternal; + /** * The service that listens for gestures detected in sensor firmware and starts the intent * accordingly. @@ -56,8 +53,6 @@ class GestureLauncherService extends SystemService { private final GestureEventListener mGestureListener = new GestureEventListener(); private Sensor mCameraLaunchSensor; - private Vibrator mVibrator; - private KeyguardManager mKeyGuard; private Context mContext; /** The wake lock held when a gesture is detected. */ @@ -82,12 +77,9 @@ class GestureLauncherService extends SystemService { return; } - mVibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE); - mKeyGuard = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE); PowerManager powerManager = (PowerManager) mContext.getSystemService( Context.POWER_SERVICE); - mWakeLock = powerManager.newWakeLock( - PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, + mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "GestureLauncherService"); updateCameraRegistered(); @@ -227,28 +219,12 @@ class GestureLauncherService extends SystemService { if (DBG) Slog.d(TAG, String.format( "userSetupComplete = %s, performing camera launch gesture.", userSetupComplete)); - boolean locked = mKeyGuard != null && mKeyGuard.inKeyguardRestrictedInputMode(); - String action = locked - ? MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE - : MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA; - Intent intent = new Intent(action); - PackageManager pm = mContext.getPackageManager(); - ResolveInfo componentInfo = pm.resolveActivity(intent, - PackageManager.MATCH_DEFAULT_ONLY); - if (componentInfo == null) { - if (DBG) Slog.d(TAG, "Couldn't find an app to process the camera intent."); - return; - } - if (mVibrator != null && mVibrator.hasVibrator()) { - mVibrator.vibrate(1000L); - } - // Turn on the screen before the camera launches. + // Make sure we don't sleep too early mWakeLock.acquire(500L); - intent.setComponent(new ComponentName(componentInfo.activityInfo.packageName, - componentInfo.activityInfo.name)); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - mContext.startActivityAsUser(intent, UserHandle.CURRENT); + StatusBarManagerInternal service = LocalServices.getService( + StatusBarManagerInternal.class); + service.onCameraLaunchGestureDetected(); mWakeLock.release(); } diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java index cae060a..468ead0 100644 --- a/services/core/java/com/android/server/LocationManagerService.java +++ b/services/core/java/com/android/server/LocationManagerService.java @@ -542,22 +542,25 @@ public class LocationManagerService extends ILocationManager.Stub { Slog.e(TAG, "Unable to bind FLP Geofence proxy."); } - // bind to the hardware activity recognition if supported - if (ActivityRecognitionHardware.isSupported()) { - ActivityRecognitionProxy proxy = ActivityRecognitionProxy.createAndBind( - mContext, - mLocationHandler, - ActivityRecognitionHardware.getInstance(mContext), - com.android.internal.R.bool.config_enableActivityRecognitionHardwareOverlay, - com.android.internal.R.string.config_activityRecognitionHardwarePackageName, - com.android.internal.R.array.config_locationProviderPackageNames); - - if (proxy == null) { - Slog.e(TAG, "Unable to bind ActivityRecognitionProxy."); - } + // bind to hardware activity recognition + boolean activityRecognitionHardwareIsSupported = ActivityRecognitionHardware.isSupported(); + ActivityRecognitionHardware activityRecognitionHardware = null; + if (activityRecognitionHardwareIsSupported) { + activityRecognitionHardware = ActivityRecognitionHardware.getInstance(mContext); } else { Slog.e(TAG, "Hardware Activity-Recognition not supported."); } + ActivityRecognitionProxy proxy = ActivityRecognitionProxy.createAndBind( + mContext, + mLocationHandler, + activityRecognitionHardwareIsSupported, + activityRecognitionHardware, + com.android.internal.R.bool.config_enableActivityRecognitionHardwareOverlay, + com.android.internal.R.string.config_activityRecognitionHardwarePackageName, + com.android.internal.R.array.config_locationProviderPackageNames); + if (proxy == null) { + Slog.e(TAG, "Unable to bind ActivityRecognitionProxy."); + } String[] testProviderStrings = resources.getStringArray( com.android.internal.R.array.config_testLocationProviders); diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java index 005d6a4..f1d7da4 100644 --- a/services/core/java/com/android/server/LockSettingsService.java +++ b/services/core/java/com/android/server/LockSettingsService.java @@ -29,6 +29,8 @@ import android.content.pm.UserInfo; import static android.Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE; import static android.content.Context.USER_SERVICE; import static android.Manifest.permission.READ_CONTACTS; +import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT; + import android.database.sqlite.SQLiteDatabase; import android.os.Binder; import android.os.IBinder; @@ -664,6 +666,10 @@ public class LockSettingsService extends ILockSettings.Stub { if (shouldReEnroll) { credentialUtil.setCredential(credential, credential, userId); } + } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) { + if (response.getTimeout() > 0) { + requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT, userId); + } } return response; diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index 9bf4f5f..335288d 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -1263,8 +1263,8 @@ public final class BatteryStatsService extends IBatteryStats.Stub Slog.v(TAG, "WiFi energy data was reset, new WiFi energy data is " + result); } - // There is some accuracy error in reports so allow 30 milliseconds of error. - final long SAMPLE_ERROR_MILLIS = 30; + // There is some accuracy error in reports so allow some slop in the results. + final long SAMPLE_ERROR_MILLIS = 750; final long totalTimeMs = result.mControllerIdleTimeMs + result.mControllerRxTimeMs + result.mControllerTxTimeMs; if (totalTimeMs > timePeriodMs + SAMPLE_ERROR_MILLIS) { diff --git a/services/core/java/com/android/server/camera/CameraService.java b/services/core/java/com/android/server/camera/CameraService.java index 0be24f4..f82454a 100644 --- a/services/core/java/com/android/server/camera/CameraService.java +++ b/services/core/java/com/android/server/camera/CameraService.java @@ -23,13 +23,17 @@ import android.content.IntentFilter; import android.content.pm.UserInfo; import android.hardware.ICameraService; import android.hardware.ICameraServiceProxy; +import android.nfc.INfcAdapter; import android.os.Handler; import android.os.IBinder; +import android.os.Binder; import android.os.Message; import android.os.Process; import android.os.RemoteException; import android.os.UserManager; +import android.os.SystemProperties; import android.util.Slog; +import android.util.ArraySet; import com.android.server.ServiceThread; import com.android.server.SystemService; @@ -44,8 +48,10 @@ import java.util.Set; * * @hide */ -public class CameraService extends SystemService implements Handler.Callback { +public class CameraService extends SystemService + implements Handler.Callback, IBinder.DeathRecipient { private static final String TAG = "CameraService_proxy"; + private static final boolean DEBUG = false; /** * This must match the ICameraService.aidl definition @@ -58,6 +64,16 @@ public class CameraService extends SystemService implements Handler.Callback { public static final int NO_EVENT = 0; // NOOP public static final int USER_SWITCHED = 1; // User changed, argument is the new user handle + // State arguments to use with the notifyCameraState call from camera service: + public static final int CAMERA_STATE_OPEN = 0; + public static final int CAMERA_STATE_ACTIVE = 1; + public static final int CAMERA_STATE_IDLE = 2; + public static final int CAMERA_STATE_CLOSED = 3; + + // Flags arguments to NFC adapter to enable/disable NFC + public static final int DISABLE_POLLING_FLAGS = 0x1000; + public static final int ENABLE_POLLING_FLAGS = 0x0000; + // Handler message codes private static final int MSG_SWITCH_USER = 1; @@ -72,6 +88,17 @@ public class CameraService extends SystemService implements Handler.Callback { private Set<Integer> mEnabledCameraUsers; private int mLastUser; + private ICameraService mCameraServiceRaw; + + private final ArraySet<String> mActiveCameraIds = new ArraySet<>(); + + private static final String NFC_NOTIFICATION_PROP = "ro.camera.notify_nfc"; + private static final String NFC_SERVICE_BINDER_NAME = "nfc"; + private static final IBinder nfcInterfaceToken = new Binder(); + + private final boolean mNotifyNfc; + private int mActiveCameraCount = 0; + private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { @@ -102,6 +129,14 @@ public class CameraService extends SystemService implements Handler.Callback { public void pingForUserUpdate() { notifySwitchWithRetries(30); } + + @Override + public void notifyCameraState(String cameraId, int newCameraState) { + String state = cameraStateToString(newCameraState); + if (DEBUG) Slog.v(TAG, "Camera " + cameraId + " state now " + state); + + updateActivityCount(cameraId, newCameraState); + } }; public CameraService(Context context) { @@ -110,6 +145,9 @@ public class CameraService extends SystemService implements Handler.Callback { mHandlerThread = new ServiceThread(TAG, Process.THREAD_PRIORITY_DISPLAY, /*allowTo*/false); mHandlerThread.start(); mHandler = new Handler(mHandlerThread.getLooper(), this); + + mNotifyNfc = SystemProperties.getInt(NFC_NOTIFICATION_PROP, 0) > 0; + if (DEBUG) Slog.v(TAG, "Notify NFC behavior is " + (mNotifyNfc ? "active" : "disabled")); } @Override @@ -161,13 +199,32 @@ public class CameraService extends SystemService implements Handler.Callback { } } + /** + * Handle the death of the native camera service + */ + @Override + public void binderDied() { + if (DEBUG) Slog.w(TAG, "Native camera service has died"); + synchronized(mLock) { + mCameraServiceRaw = null; + + // All cameras reset to idle on camera service death + boolean wasEmpty = mActiveCameraIds.isEmpty(); + mActiveCameraIds.clear(); + + if ( mNotifyNfc && !wasEmpty ) { + notifyNfcService(/*enablePolling*/ true); + } + } + } + private void switchUserLocked(int userHandle) { Set<Integer> currentUserHandles = getEnabledUserHandles(userHandle); mLastUser = userHandle; if (mEnabledCameraUsers == null || !mEnabledCameraUsers.equals(currentUserHandles)) { // Some user handles have been added or removed, update mediaserver. mEnabledCameraUsers = currentUserHandles; - notifyMediaserver(USER_SWITCHED, currentUserHandles); + notifyMediaserverLocked(USER_SWITCHED, currentUserHandles); } } @@ -187,7 +244,7 @@ public class CameraService extends SystemService implements Handler.Callback { if (mEnabledCameraUsers == null) { return; } - if (notifyMediaserver(USER_SWITCHED, mEnabledCameraUsers)) { + if (notifyMediaserverLocked(USER_SWITCHED, mEnabledCameraUsers)) { retries = 0; } } @@ -199,19 +256,27 @@ public class CameraService extends SystemService implements Handler.Callback { RETRY_DELAY_TIME); } - private boolean notifyMediaserver(int eventType, Set<Integer> updatedUserHandles) { + private boolean notifyMediaserverLocked(int eventType, Set<Integer> updatedUserHandles) { // Forward the user switch event to the native camera service running in the mediaserver // process. - IBinder cameraServiceBinder = getBinderService(CAMERA_SERVICE_BINDER_NAME); - if (cameraServiceBinder == null) { - Slog.w(TAG, "Could not notify mediaserver, camera service not available."); - return false; // Camera service not active, cannot evict user clients. - } + if (mCameraServiceRaw == null) { + IBinder cameraServiceBinder = getBinderService(CAMERA_SERVICE_BINDER_NAME); + if (cameraServiceBinder == null) { + Slog.w(TAG, "Could not notify mediaserver, camera service not available."); + return false; // Camera service not active, cannot evict user clients. + } + try { + cameraServiceBinder.linkToDeath(this, /*flags*/ 0); + } catch (RemoteException e) { + Slog.w(TAG, "Could not link to death of native camera service"); + return false; + } - ICameraService cameraServiceRaw = ICameraService.Stub.asInterface(cameraServiceBinder); + mCameraServiceRaw = ICameraService.Stub.asInterface(cameraServiceBinder); + } try { - cameraServiceRaw.notifySystemEvent(eventType, toArray(updatedUserHandles)); + mCameraServiceRaw.notifySystemEvent(eventType, toArray(updatedUserHandles)); } catch (RemoteException e) { Slog.w(TAG, "Could not notify mediaserver, remote exception: " + e); // Not much we can do if camera service is dead. @@ -220,6 +285,44 @@ public class CameraService extends SystemService implements Handler.Callback { return true; } + private void updateActivityCount(String cameraId, int newCameraState) { + synchronized(mLock) { + boolean wasEmpty = mActiveCameraIds.isEmpty(); + switch (newCameraState) { + case CAMERA_STATE_OPEN: + break; + case CAMERA_STATE_ACTIVE: + mActiveCameraIds.add(cameraId); + break; + case CAMERA_STATE_IDLE: + case CAMERA_STATE_CLOSED: + mActiveCameraIds.remove(cameraId); + break; + } + boolean isEmpty = mActiveCameraIds.isEmpty(); + if ( mNotifyNfc && (wasEmpty != isEmpty) ) { + notifyNfcService(isEmpty); + } + } + } + + private void notifyNfcService(boolean enablePolling) { + + IBinder nfcServiceBinder = getBinderService(NFC_SERVICE_BINDER_NAME); + if (nfcServiceBinder == null) { + Slog.w(TAG, "Could not connect to NFC service to notify it of camera state"); + return; + } + INfcAdapter nfcAdapterRaw = INfcAdapter.Stub.asInterface(nfcServiceBinder); + int flags = enablePolling ? ENABLE_POLLING_FLAGS : DISABLE_POLLING_FLAGS; + if (DEBUG) Slog.v(TAG, "Setting NFC reader mode to flags " + flags); + try { + nfcAdapterRaw.setReaderMode(nfcInterfaceToken, null, flags, null); + } catch (RemoteException e) { + Slog.w(TAG, "Could not notify NFC service, remote exception: " + e); + } + } + private static int[] toArray(Collection<Integer> c) { int len = c.size(); int[] ret = new int[len]; @@ -229,4 +332,15 @@ public class CameraService extends SystemService implements Handler.Callback { } return ret; } + + private static String cameraStateToString(int newCameraState) { + switch (newCameraState) { + case CAMERA_STATE_OPEN: return "CAMERA_STATE_OPEN"; + case CAMERA_STATE_ACTIVE: return "CAMERA_STATE_ACTIVE"; + case CAMERA_STATE_IDLE: return "CAMERA_STATE_IDLE"; + case CAMERA_STATE_CLOSED: return "CAMERA_STATE_CLOSED"; + default: break; + } + return "CAMERA_STATE_UNKNOWN"; + } } diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java index befa311..470bd5a 100644 --- a/services/core/java/com/android/server/fingerprint/FingerprintService.java +++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java @@ -298,6 +298,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe final int result = daemon.enroll(cryptoToken, groupId, timeout); if (result != 0) { Slog.w(TAG, "startEnroll failed, result=" + result); + dispatchError(mHalDeviceId, FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE); } } catch (RemoteException e) { Slog.e(TAG, "startEnroll failed", e); @@ -391,6 +392,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe final int result = daemon.authenticate(opId, groupId); if (result != 0) { Slog.w(TAG, "startAuthentication failed, result=" + result); + dispatchError(mHalDeviceId, FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE); } } catch (RemoteException e) { Slog.e(TAG, "startAuthentication failed", e); @@ -433,12 +435,14 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe return; } + stopPendingOperations(true); mRemoveClient = new ClientMonitor(token, receiver, userId, restricted); // The fingerprint template ids will be removed when we get confirmation from the HAL try { final int result = daemon.remove(fingerId, userId); if (result != 0) { Slog.w(TAG, "startRemove with id = " + fingerId + " failed, result=" + result); + dispatchError(mHalDeviceId, FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE); } } catch (RemoteException e) { Slog.e(TAG, "startRemove failed", e); @@ -764,6 +768,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe mHandler.post(new Runnable() { @Override public void run() { + MetricsLogger.histogram(mContext, "fingerprint_token", opId != 0L ? 1 : 0); startAuthentication(token, opId, effectiveGroupId, receiver, flags, restricted); } }); diff --git a/services/core/java/com/android/server/location/ActivityRecognitionProxy.java b/services/core/java/com/android/server/location/ActivityRecognitionProxy.java index 607805b..2eb58bf 100644 --- a/services/core/java/com/android/server/location/ActivityRecognitionProxy.java +++ b/services/core/java/com/android/server/location/ActivityRecognitionProxy.java @@ -20,8 +20,10 @@ import com.android.server.ServiceWatcher; import android.content.Context; import android.hardware.location.ActivityRecognitionHardware; +import android.hardware.location.IActivityRecognitionHardwareClient; import android.hardware.location.IActivityRecognitionHardwareWatcher; import android.os.Handler; +import android.os.IBinder; import android.os.RemoteException; import android.util.Log; @@ -34,21 +36,24 @@ public class ActivityRecognitionProxy { private static final String TAG = "ActivityRecognitionProxy"; private final ServiceWatcher mServiceWatcher; - private final ActivityRecognitionHardware mActivityRecognitionHardware; + private final boolean mIsSupported; + private final ActivityRecognitionHardware mInstance; private ActivityRecognitionProxy( Context context, Handler handler, + boolean activityRecognitionHardwareIsSupported, ActivityRecognitionHardware activityRecognitionHardware, int overlaySwitchResId, int defaultServicePackageNameResId, int initialPackageNameResId) { - mActivityRecognitionHardware = activityRecognitionHardware; + mIsSupported = activityRecognitionHardwareIsSupported; + mInstance = activityRecognitionHardware; Runnable newServiceWork = new Runnable() { @Override public void run() { - bindProvider(mActivityRecognitionHardware); + bindProvider(); } }; @@ -72,6 +77,7 @@ public class ActivityRecognitionProxy { public static ActivityRecognitionProxy createAndBind( Context context, Handler handler, + boolean activityRecognitionHardwareIsSupported, ActivityRecognitionHardware activityRecognitionHardware, int overlaySwitchResId, int defaultServicePackageNameResId, @@ -79,6 +85,7 @@ public class ActivityRecognitionProxy { ActivityRecognitionProxy activityRecognitionProxy = new ActivityRecognitionProxy( context, handler, + activityRecognitionHardwareIsSupported, activityRecognitionHardware, overlaySwitchResId, defaultServicePackageNameResId, @@ -89,25 +96,52 @@ public class ActivityRecognitionProxy { Log.e(TAG, "ServiceWatcher could not start."); return null; } - return activityRecognitionProxy; } /** * Helper function to bind the FusedLocationHardware to the appropriate FusedProvider instance. */ - private void bindProvider(ActivityRecognitionHardware activityRecognitionHardware) { - IActivityRecognitionHardwareWatcher watcher = - IActivityRecognitionHardwareWatcher.Stub.asInterface(mServiceWatcher.getBinder()); - if (watcher == null) { - Log.e(TAG, "No provider instance found on connection."); + private void bindProvider() { + IBinder binder = mServiceWatcher.getBinder(); + if (binder == null) { + Log.e(TAG, "Null binder found on connection."); return; } - + String descriptor; try { - watcher.onInstanceChanged(mActivityRecognitionHardware); + descriptor = binder.getInterfaceDescriptor(); } catch (RemoteException e) { - Log.e(TAG, "Error delivering hardware interface.", e); + Log.e(TAG, "Unable to get interface descriptor.", e); + return; + } + + if (IActivityRecognitionHardwareWatcher.class.getCanonicalName().equals(descriptor)) { + IActivityRecognitionHardwareWatcher watcher = + IActivityRecognitionHardwareWatcher.Stub.asInterface(binder); + if (watcher == null) { + Log.e(TAG, "No watcher found on connection."); + return; + } + try { + watcher.onInstanceChanged(mInstance); + } catch (RemoteException e) { + Log.e(TAG, "Error delivering hardware interface to watcher.", e); + } + } else if (IActivityRecognitionHardwareClient.class.getCanonicalName().equals(descriptor)) { + IActivityRecognitionHardwareClient client = + IActivityRecognitionHardwareClient.Stub.asInterface(binder); + if (client == null) { + Log.e(TAG, "No client found on connection."); + return; + } + try { + client.onAvailabilityChanged(mIsSupported, mInstance); + } catch (RemoteException e) { + Log.e(TAG, "Error delivering hardware interface to client.", e); + } + } else { + Log.e(TAG, "Invalid descriptor found on connection: " + descriptor); } } } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 4bb3c1a..e1bd9f9 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -4626,7 +4626,7 @@ public class PackageManagerService extends IPackageManager.Stub { if (result == null) { result = new CrossProfileDomainInfo(); result.resolveInfo = - createForwardingResolveInfo(null, sourceUserId, parentUserId); + createForwardingResolveInfo(new IntentFilter(), sourceUserId, parentUserId); result.bestDomainVerificationStatus = status; } else { result.bestDomainVerificationStatus = bestDomainVerificationStatus(status, diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 5b0c06b..0423aa3 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -4410,7 +4410,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (mAppsToBeHidden.isEmpty()) { if (dismissKeyguard && !mKeyguardSecure) { mAppsThatDismissKeyguard.add(appToken); - } else { + } else if (win.isDrawnLw()) { mWinShowWhenLocked = win; mHideLockScreen = true; mForceStatusBarFromKeyguard = false; @@ -4444,7 +4444,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { mWinDismissingKeyguard = win; mSecureDismissingKeyguard = mKeyguardSecure; mForceStatusBarFromKeyguard = mShowingLockscreen && mKeyguardSecure; - } else if (mAppsToBeHidden.isEmpty() && showWhenLocked) { + } else if (mAppsToBeHidden.isEmpty() && showWhenLocked && win.isDrawnLw()) { if (DEBUG_LAYOUT) Slog.v(TAG, "Setting mHideLockScreen to true by win " + win); mHideLockScreen = true; diff --git a/services/core/java/com/android/server/policy/StatusBarController.java b/services/core/java/com/android/server/policy/StatusBarController.java index d1b50da..b1ae922 100644 --- a/services/core/java/com/android/server/policy/StatusBarController.java +++ b/services/core/java/com/android/server/policy/StatusBarController.java @@ -72,7 +72,9 @@ public class StatusBarController extends BarController { if (statusbar != null) { long startTime = calculateStatusBarTransitionStartTime(openAnimation, closeAnimation); - statusbar.appTransitionStarting(startTime, TRANSITION_DURATION); + long duration = closeAnimation != null || openAnimation != null + ? TRANSITION_DURATION : 0; + statusbar.appTransitionStarting(startTime, duration); } } catch (RemoteException e) { Slog.e(mTag, "RemoteException when app transition is starting", e); diff --git a/services/core/java/com/android/server/policy/WindowOrientationListener.java b/services/core/java/com/android/server/policy/WindowOrientationListener.java index 8b3c036..9916223 100644 --- a/services/core/java/com/android/server/policy/WindowOrientationListener.java +++ b/services/core/java/com/android/server/policy/WindowOrientationListener.java @@ -217,6 +217,8 @@ public abstract class WindowOrientationListener { * It is called each time the orientation determination transitions from being * uncertain to being certain again, even if it is the same orientation as before. * + * This should only be called on the Handler thread. + * * @param rotation The new orientation of the device, one of the Surface.ROTATION_* constants. * @see android.view.Surface */ @@ -995,9 +997,13 @@ public abstract class WindowOrientationListener { @Override public void onSensorChanged(SensorEvent event) { + int newRotation; synchronized (mLock) { mDesiredRotation = (int) event.values[0]; - evaluateRotationChangeLocked(); + newRotation = evaluateRotationChangeLocked(); + } + if (newRotation >=0) { + onProposedRotationChanged(newRotation); } } @@ -1023,18 +1029,19 @@ public abstract class WindowOrientationListener { unscheduleRotationEvaluationLocked(); } - public void evaluateRotationChangeLocked() { + public int evaluateRotationChangeLocked() { unscheduleRotationEvaluationLocked(); if (mDesiredRotation == mProposedRotation) { - return; + return -1; } final long now = SystemClock.elapsedRealtimeNanos(); if (isDesiredRotationAcceptableLocked(now)) { mProposedRotation = mDesiredRotation; - onProposedRotationChanged(mProposedRotation); + return mProposedRotation; } else { scheduleRotationEvaluationIfNecessaryLocked(now); } + return -1; } private boolean isDesiredRotationAcceptableLocked(long now) { @@ -1090,9 +1097,13 @@ public abstract class WindowOrientationListener { private Runnable mRotationEvaluator = new Runnable() { @Override public void run() { + int newRotation; synchronized (mLock) { mRotationEvaluationScheduled = false; - evaluateRotationChangeLocked(); + newRotation = evaluateRotationChangeLocked(); + } + if (newRotation >= 0) { + onProposedRotationChanged(newRotation); } } }; diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java index 130815e..5d01931 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java @@ -28,4 +28,5 @@ public interface StatusBarManagerInternal { void showScreenPinningRequest(); void showAssistDisclosure(); void startAssist(Bundle args); + void onCameraLaunchGestureDetected(); } diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java index 2a817ea..0fb1169 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java @@ -176,6 +176,16 @@ public class StatusBarManagerService extends IStatusBarService.Stub { } } } + + @Override + public void onCameraLaunchGestureDetected() { + if (mBar != null) { + try { + mBar.onCameraLaunchGestureDetected(); + } catch (RemoteException e) { + } + } + } }; // ================================================================================ diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index ee1149e..36cb7f2 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -10408,8 +10408,8 @@ public class WindowManagerService extends IWindowManager.Stub ": removed=" + win.mRemoved + " visible=" + win.isVisibleLw() + " mHasSurface=" + win.mHasSurface + " drawState=" + win.mWinAnimator.mDrawState); - if (win.mRemoved || !win.mHasSurface) { - // Window has been removed; no draw will now happen, so stop waiting. + if (win.mRemoved || !win.mHasSurface || !win.mPolicyVisibility) { + // Window has been removed or hidden; no draw will now happen, so stop waiting. if (DEBUG_SCREEN_ON) Slog.w(TAG, "Aborted waiting for drawn: " + win); mWaitingForDrawn.remove(win); } else if (win.hasDrawnLw()) { diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index ab56d5e..726d29d 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -1589,8 +1589,6 @@ class WindowStateAnimator { final int left = ((int) shownFrame.left) - attrs.surfaceInsets.left; final int top = ((int) shownFrame.top) - attrs.surfaceInsets.top; if (mSurfaceX != left || mSurfaceY != top) { - mSurfaceX = left; - mSurfaceY = top; if (mAnimating) { // If this window (or its app token) is animating, then the position // of the surface will be re-computed on the next animation frame. @@ -1598,6 +1596,8 @@ class WindowStateAnimator { // transformation is being applied by the animation. return; } + mSurfaceX = left; + mSurfaceY = top; if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setWallpaperOffset"); SurfaceControl.openTransaction(); try { |