diff options
89 files changed, 1086 insertions, 1346 deletions
diff --git a/Android.bp b/Android.bp index 5b8e6e1b8d32..7cc2f30cc227 100644 --- a/Android.bp +++ b/Android.bp @@ -436,6 +436,7 @@ java_defaults { "core/java/com/android/internal/os/IShellCallback.aidl", "core/java/com/android/internal/statusbar/IStatusBar.aidl", "core/java/com/android/internal/statusbar/IStatusBarService.aidl", + "core/java/com/android/internal/statusbar/RegisterStatusBarResult.aidl", "core/java/com/android/internal/textservice/ISpellCheckerService.aidl", "core/java/com/android/internal/textservice/ISpellCheckerServiceCallback.aidl", "core/java/com/android/internal/textservice/ISpellCheckerSession.aidl", diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index cbb78bf5732c..8986c6fd02c2 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -234,7 +234,7 @@ message Atom { BluetoothDeviceTxPowerLevelReported bluetooth_device_tx_power_level_reported = 159; BluetoothHciTimeoutReported bluetooth_hci_timeout_reported = 160; BluetoothQualityReportReported bluetooth_quality_report_reported = 161; - BluetoothManufacturerInfoReported bluetooth_device_info_reported = 162; + BluetoothDeviceInfoReported bluetooth_device_info_reported = 162; BluetoothRemoteVersionInfoReported bluetooth_remote_version_info_reported = 163; BluetoothSdpAttributeReported bluetooth_sdp_attribute_reported = 164; BluetoothBondStateChanged bluetooth_bond_state_changed = 165; @@ -1935,7 +1935,7 @@ message BluetoothQualityReportReported { * Logged from: * packages/apps/Bluetooth */ -message BluetoothManufacturerInfoReported { +message BluetoothDeviceInfoReported { // An identifier that can be used to match events for this device. // Currently, this is a salted hash of the MAC address of this Bluetooth device. // Salt: Randomly generated 256 bit value diff --git a/core/java/android/database/CursorWindow.java b/core/java/android/database/CursorWindow.java index 647448caee82..6873577553a7 100644 --- a/core/java/android/database/CursorWindow.java +++ b/core/java/android/database/CursorWindow.java @@ -138,7 +138,7 @@ public class CursorWindow extends SQLiteClosable implements Parcelable { mName = name != null && name.length() != 0 ? name : "<unnamed>"; mWindowPtr = nativeCreate(mName, (int) windowSizeBytes); if (mWindowPtr == 0) { - throw new IllegalStateException(); // Shouldn't happen. + throw new AssertionError(); // Not possible, the native code won't return it. } mCloseGuard.open("close"); recordNewWindow(Binder.getCallingPid(), mWindowPtr); @@ -166,7 +166,7 @@ public class CursorWindow extends SQLiteClosable implements Parcelable { mStartPos = source.readInt(); mWindowPtr = nativeCreateFromParcel(source); if (mWindowPtr == 0) { - throw new IllegalStateException(); // Shouldn't happen. + throw new AssertionError(); // Not possible, the native code won't return it. } mName = nativeGetName(mWindowPtr); mCloseGuard.open("close"); diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java index 10fe52a71d9d..33e51c9fa11c 100644 --- a/core/java/android/hardware/Camera.java +++ b/core/java/android/hardware/Camera.java @@ -271,7 +271,7 @@ public class Camera { * If there is a * {@link android.hardware.camera2.CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA * logical multi-camera} in the system, to maintain app backward compatibility, this method will - * only expose one camera for every logical camera and underlying physical cameras group. + * only expose one camera per facing for all logical camera and physical camera groups. * Use camera2 API to see all cameras. * * @return total number of accessible camera devices, or 0 if there are no diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 85feac878c67..ee0c83ea72f8 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -8113,6 +8113,16 @@ public final class Settings { BOOLEAN_VALIDATOR; /** + * Whether or not face unlock requires attention. This is a cached value, the source of + * truth is obtained through the HAL. + * @hide + */ + public static final String FACE_UNLOCK_ATTENTION_REQUIRED = + "face_unlock_attention_required"; + + private static final Validator FACE_UNLOCK_ATTENTION_REQUIRED_VALIDATOR = BOOLEAN_VALIDATOR; + + /** * Whether or not face unlock is allowed for apps (through BiometricPrompt). * @hide */ @@ -8761,6 +8771,7 @@ public final class Settings { AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN, FACE_UNLOCK_KEYGUARD_ENABLED, FACE_UNLOCK_DISMISSES_KEYGUARD, + FACE_UNLOCK_ATTENTION_REQUIRED, FACE_UNLOCK_APP_ENABLED, FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION, ASSIST_GESTURE_ENABLED, @@ -8927,6 +8938,8 @@ public final class Settings { VALIDATORS.put(FACE_UNLOCK_KEYGUARD_ENABLED, FACE_UNLOCK_KEYGUARD_ENABLED_VALIDATOR); VALIDATORS.put(FACE_UNLOCK_DISMISSES_KEYGUARD, FACE_UNLOCK_DISMISSES_KEYGUARD_VALIDATOR); + VALIDATORS.put(FACE_UNLOCK_ATTENTION_REQUIRED, + FACE_UNLOCK_ATTENTION_REQUIRED_VALIDATOR); VALIDATORS.put(FACE_UNLOCK_APP_ENABLED, FACE_UNLOCK_APP_ENABLED_VALIDATOR); VALIDATORS.put(FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION, FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION_VALIDATOR); diff --git a/core/java/android/view/DisplayListCanvas.java b/core/java/android/view/DisplayListCanvas.java index 3e749f4ba16f..8e6e99a6d949 100644 --- a/core/java/android/view/DisplayListCanvas.java +++ b/core/java/android/view/DisplayListCanvas.java @@ -20,7 +20,6 @@ import android.annotation.UnsupportedAppUsage; import android.graphics.BaseRecordingCanvas; import android.graphics.CanvasProperty; import android.graphics.Paint; -import android.os.Build; /** * This class exists temporarily to workaround broken apps @@ -36,14 +35,20 @@ public abstract class DisplayListCanvas extends BaseRecordingCanvas { super(nativeCanvas); } - /** @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.O) + /** + * TODO: Public API alternative + * @hide + */ + @UnsupportedAppUsage public abstract void drawRoundRect(CanvasProperty<Float> left, CanvasProperty<Float> top, CanvasProperty<Float> right, CanvasProperty<Float> bottom, CanvasProperty<Float> rx, CanvasProperty<Float> ry, CanvasProperty<Paint> paint); - /** @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) + /** + * TODO: Public API alternative + * @hide + */ + @UnsupportedAppUsage public abstract void drawCircle(CanvasProperty<Float> cx, CanvasProperty<Float> cy, CanvasProperty<Float> radius, CanvasProperty<Paint> paint); } diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index d553c6c11dcf..8d7df4f4ca85 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -1808,15 +1808,17 @@ public class ChooserActivity extends ResolverActivity { offset += lastHeight; } - if (lastHeight != 0 && isSendAction(getTargetIntent())) { + boolean isPortrait = getResources().getConfiguration().orientation + == Configuration.ORIENTATION_PORTRAIT; + if (lastHeight != 0 && isSendAction(getTargetIntent()) && isPortrait) { // make sure to leave room for direct share 4->8 expansion int expansionArea = - (int) (mResolverDrawerLayout.getUncollapsibleHeight() + (int) (mResolverDrawerLayout.getAlwaysShowHeight() / DIRECT_SHARE_EXPANSION_RATE); offset = Math.min(offset, bottom - top - lastHeight - expansionArea); } - mResolverDrawerLayout.setCollapsibleHeightReserved(offset); + mResolverDrawerLayout.setCollapsibleHeightReserved(Math.min(offset, bottom - top)); }); } } diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl index 343761430762..5fee2c9bbdd3 100644 --- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl @@ -24,6 +24,7 @@ import android.service.notification.StatusBarNotification; import android.hardware.biometrics.IBiometricServiceReceiverInternal; import com.android.internal.statusbar.IStatusBar; +import com.android.internal.statusbar.RegisterStatusBarResult; import com.android.internal.statusbar.StatusBarIcon; import com.android.internal.statusbar.StatusBarIconList; import com.android.internal.statusbar.NotificationVisibility; @@ -54,10 +55,7 @@ interface IStatusBarService // ---- Methods below are for use by the status bar policy services ---- // You need the STATUS_BAR_SERVICE permission - void registerStatusBar(IStatusBar callbacks, out List<String> iconSlots, - out List<StatusBarIcon> iconList, - out int[] switches, out List<IBinder> binders, out Rect fullscreenStackBounds, - out Rect dockedStackBounds); + RegisterStatusBarResult registerStatusBar(IStatusBar callbacks); void onPanelRevealed(boolean clearNotificationEffects, int numItems); void onPanelHidden(); // Mark current notifications as "seen" and stop ringing, vibrating, blinking. diff --git a/core/java/com/android/internal/statusbar/RegisterStatusBarResult.aidl b/core/java/com/android/internal/statusbar/RegisterStatusBarResult.aidl new file mode 100644 index 000000000000..ec2e60480aea --- /dev/null +++ b/core/java/com/android/internal/statusbar/RegisterStatusBarResult.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.statusbar; + +parcelable RegisterStatusBarResult; diff --git a/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java b/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java new file mode 100644 index 000000000000..b47ef125275f --- /dev/null +++ b/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.statusbar; + +import android.graphics.Rect; +import android.os.IBinder; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.ArrayMap; + +/** + * An immutable data object to return a set of values from StatusBarManagerService to its clients. + */ +public final class RegisterStatusBarResult implements Parcelable { + public final ArrayMap<String, StatusBarIcon> mIcons; + public final int mDisabledFlags1; // switch[0] + public final int mSystemUiVisibility; // switch[1] + public final boolean mMenuVisible; // switch[2] + public final int mImeWindowVis; // switch[3] + public final int mImeBackDisposition; // switch[4] + public final boolean mShowImeSwitcher; // switch[5] + public final int mDisabledFlags2; // switch[6] + public final int mFullscreenStackSysUiVisibility; // switch[7] + public final int mDockedStackSysUiVisibility; // switch[8] + public final IBinder mImeToken; + public final Rect mFullscreenStackBounds; + public final Rect mDockedStackBounds; + + public RegisterStatusBarResult(ArrayMap<String, StatusBarIcon> icons, int disabledFlags1, + int systemUiVisibility, boolean menuVisible, int imeWindowVis, int imeBackDisposition, + boolean showImeSwitcher, int disabledFlags2, int fullscreenStackSysUiVisibility, + int dockedStackSysUiVisibility, IBinder imeToken, Rect fullscreenStackBounds, + Rect dockedStackBounds) { + mIcons = new ArrayMap<>(icons); + mDisabledFlags1 = disabledFlags1; + mSystemUiVisibility = systemUiVisibility; + mMenuVisible = menuVisible; + mImeWindowVis = imeWindowVis; + mImeBackDisposition = imeBackDisposition; + mShowImeSwitcher = showImeSwitcher; + mDisabledFlags2 = disabledFlags2; + mFullscreenStackSysUiVisibility = fullscreenStackSysUiVisibility; + mDockedStackSysUiVisibility = dockedStackSysUiVisibility; + mImeToken = imeToken; + mFullscreenStackBounds = fullscreenStackBounds; + mDockedStackBounds = dockedStackBounds; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeTypedArrayMap(mIcons, flags); + dest.writeInt(mDisabledFlags1); + dest.writeInt(mSystemUiVisibility); + dest.writeBoolean(mMenuVisible); + dest.writeInt(mImeWindowVis); + dest.writeInt(mImeBackDisposition); + dest.writeBoolean(mShowImeSwitcher); + dest.writeInt(mDisabledFlags2); + dest.writeInt(mFullscreenStackSysUiVisibility); + dest.writeInt(mDockedStackSysUiVisibility); + dest.writeStrongBinder(mImeToken); + dest.writeParcelable(mFullscreenStackBounds, flags); + dest.writeParcelable(mDockedStackBounds, flags); + } + + /** + * Used to make this class parcelable. + */ + public static final Parcelable.Creator<RegisterStatusBarResult> CREATOR = + new Parcelable.Creator<RegisterStatusBarResult>() { + @Override + public RegisterStatusBarResult createFromParcel(Parcel source) { + final ArrayMap<String, StatusBarIcon> icons = + source.createTypedArrayMap(StatusBarIcon.CREATOR); + final int disabledFlags1 = source.readInt(); + final int systemUiVisibility = source.readInt(); + final boolean menuVisible = source.readBoolean(); + final int imeWindowVis = source.readInt(); + final int imeBackDisposition = source.readInt(); + final boolean showImeSwitcher = source.readBoolean(); + final int disabledFlags2 = source.readInt(); + final int fullscreenStackSysUiVisibility = source.readInt(); + final int dockedStackSysUiVisibility = source.readInt(); + final IBinder imeToken = source.readStrongBinder(); + final Rect fullscreenStackBounds = Rect.CREATOR.createFromParcel(source); + final Rect dockedStackBounds = Rect.CREATOR.createFromParcel(source); + return new RegisterStatusBarResult(icons, disabledFlags1, systemUiVisibility, + menuVisible, imeWindowVis, imeBackDisposition, showImeSwitcher, + disabledFlags2, fullscreenStackSysUiVisibility, + dockedStackSysUiVisibility, imeToken, fullscreenStackBounds, + dockedStackBounds); + } + + @Override + public RegisterStatusBarResult[] newArray(int size) { + return new RegisterStatusBarResult[size]; + } + }; +} diff --git a/core/java/com/android/internal/widget/ResolverDrawerLayout.java b/core/java/com/android/internal/widget/ResolverDrawerLayout.java index a160b57fe2a1..329c6b395bba 100644 --- a/core/java/com/android/internal/widget/ResolverDrawerLayout.java +++ b/core/java/com/android/internal/widget/ResolverDrawerLayout.java @@ -75,6 +75,7 @@ public class ResolverDrawerLayout extends ViewGroup { private int mCollapsibleHeight; private int mUncollapsibleHeight; + private int mAlwaysShowHeight; /** * The height in pixels of reserved space added to the top of the collapsed UI; @@ -832,7 +833,7 @@ public class ResolverDrawerLayout extends ViewGroup { } } - final int alwaysShowHeight = heightUsed; + mAlwaysShowHeight = heightUsed; // And now the rest. for (int i = 0; i < childCount; i++) { @@ -854,7 +855,7 @@ public class ResolverDrawerLayout extends ViewGroup { final int oldCollapsibleHeight = mCollapsibleHeight; mCollapsibleHeight = Math.max(0, - heightUsed - alwaysShowHeight - getMaxCollapsedHeight()); + heightUsed - mAlwaysShowHeight - getMaxCollapsedHeight()); mUncollapsibleHeight = heightUsed - mCollapsibleHeight; updateCollapseOffset(oldCollapsibleHeight, !isDragging()); @@ -871,8 +872,8 @@ public class ResolverDrawerLayout extends ViewGroup { /** * @return The space reserved by views with 'alwaysShow=true' */ - public int getUncollapsibleHeight() { - return mUncollapsibleHeight; + public int getAlwaysShowHeight() { + return mAlwaysShowHeight; } @Override diff --git a/core/res/res/drawable/ic_wifi_signal_0.xml b/core/res/res/drawable/ic_wifi_signal_0.xml index e732a8dbbf20..cab8be3d3482 100644 --- a/core/res/res/drawable/ic_wifi_signal_0.xml +++ b/core/res/res/drawable/ic_wifi_signal_0.xml @@ -15,12 +15,11 @@ limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="26dp" - android:height="24dp" - android:viewportWidth="26" - android:viewportHeight="24"> + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> <path - android:fillAlpha="0.3" - android:fillColor="#FFFFFF" - android:pathData="M13.0,22.0L25.6,6.5C25.1,6.1 20.3,2.1 13.0,2.1S0.9,6.1 0.4,6.5L13.0,22.0L13.0,22.0L13.0,22.0L13.0,22.0L13.0,22.0z"/> + android:fillColor="@android:color/white" + android:pathData="M12,4c3.42,0,6.73,1.27,9.3,3.53L12,18.85L2.7,7.53C5.27,5.27,8.58,4,12,4 M12,2C7.25,2,2.97,4.08,0,7.39L12,22L24,7.39 C21.03,4.08,16.75,2,12,2L12,2z" /> </vector>
\ No newline at end of file diff --git a/core/res/res/drawable/ic_wifi_signal_1.xml b/core/res/res/drawable/ic_wifi_signal_1.xml index 3d006953fcaa..54b68aeaaaee 100644 --- a/core/res/res/drawable/ic_wifi_signal_1.xml +++ b/core/res/res/drawable/ic_wifi_signal_1.xml @@ -15,15 +15,14 @@ limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="26dp" + android:width="24dp" android:height="24dp" - android:viewportWidth="26" + android:viewportWidth="24" android:viewportHeight="24"> <path - android:fillAlpha="0.3" - android:fillColor="#FFFFFF" - android:pathData="M13.1,22.0L25.6,6.5C25.1,6.1 20.3,2.1 13.0,2.1S0.9,6.1 0.5,6.5L13.1,22.0L13.1,22.0L13.1,22.0L13.1,22.0L13.1,22.0z"/> + android:fillColor="@android:color/white" + android:pathData="M12,2.01c-4.75,0-9.03,2.08-12,5.39L12,22L24,7.4C21.03,4.09,16.75,2.01,12,2.01z M12,18.86L2.7,7.54 C5.27,5.28,8.58,4.01,12,4.01s6.73,1.27,9.3,3.53L12,18.86z" /> <path - android:fillColor="#FFFFFF" - android:pathData="M13.1,22.0l5.5,-6.8c-0.2,-0.2 -2.3,-1.9 -5.5,-1.9s-5.3,1.8 -5.5,1.9L13.1,22.0L13.1,22.0L13.1,22.0L13.1,22.0L13.1,22.0z"/> -</vector> + android:fillColor="@android:color/white" + android:pathData="M16.42,16.63L12,22l-4.42-5.37c0.15-0.74,0.48-1.43,0.95-1.99C9.35,13.64,10.6,13,12,13s2.65,0.64,3.47,1.64 C15.94,15.2,16.27,15.89,16.42,16.63z" /> +</vector>
\ No newline at end of file diff --git a/core/res/res/drawable/ic_wifi_signal_2.xml b/core/res/res/drawable/ic_wifi_signal_2.xml index 2cce9e90c02b..52f589502d39 100644 --- a/core/res/res/drawable/ic_wifi_signal_2.xml +++ b/core/res/res/drawable/ic_wifi_signal_2.xml @@ -15,15 +15,14 @@ limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="26dp" + android:width="24dp" android:height="24dp" - android:viewportWidth="26" + android:viewportWidth="24" android:viewportHeight="24"> <path - android:fillAlpha="0.3" - android:fillColor="#FFFFFF" - android:pathData="M13.0,22.0L25.6,6.5C25.1,6.1 20.3,2.1 13.0,2.1S0.9,6.1 0.4,6.5L13.0,22.0L13.0,22.0L13.0,22.0L13.0,22.0L13.0,22.0z"/> + android:fillColor="@android:color/white" + android:pathData="M12,2C7.25,2,2.97,4.08,0,7.39L12,22L24,7.39C21.03,4.08,16.75,2,12,2z M12,18.85L2.7,7.53C5.27,5.27,8.58,4,12,4 s6.73,1.27,9.3,3.53L12,18.85z" /> <path - android:fillColor="#FFFFFF" - android:pathData="M13.0,22.0l7.6,-9.4C20.3,12.4 17.4,10.0 13.0,10.0s-7.3,2.4 -7.6,2.7L13.0,22.0L13.0,22.0L13.0,22.0L13.0,22.0L13.0,22.0z"/> -</vector> + android:fillColor="@android:color/white" + android:pathData="M18.61,13.95L12,22l-6.61-8.05c0.33-0.61,0.74-1.17,1.22-1.66c1.36-1.42,3.27-2.3,5.39-2.3s4.03,0.88,5.39,2.3 C17.87,12.78,18.28,13.34,18.61,13.95z" /> +</vector>
\ No newline at end of file diff --git a/core/res/res/drawable/ic_wifi_signal_3.xml b/core/res/res/drawable/ic_wifi_signal_3.xml index d3b3d3ad6025..8e51ed2f53b6 100644 --- a/core/res/res/drawable/ic_wifi_signal_3.xml +++ b/core/res/res/drawable/ic_wifi_signal_3.xml @@ -15,15 +15,14 @@ limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="26dp" + android:width="24dp" android:height="24dp" - android:viewportWidth="26" + android:viewportWidth="24" android:viewportHeight="24"> <path - android:fillAlpha="0.3" - android:fillColor="#FFFFFF" - android:pathData="M13.0,22.0L25.6,6.5C25.1,6.1 20.3,2.1 13.0,2.1S0.9,6.1 0.4,6.5L13.0,22.0L13.0,22.0L13.0,22.0L13.0,22.0L13.0,22.0z"/> + android:fillColor="@android:color/white" + android:pathData="M12,2C7.25,2,2.97,4.08,0,7.39L12,22L24,7.39C21.03,4.08,16.75,2,12,2z M12,18.85L2.7,7.53C5.27,5.27,8.58,4,12,4 s6.73,1.27,9.3,3.53L12,18.85z" /> <path - android:fillColor="#FFFFFF" - android:pathData="M13.0,22.0l9.2,-11.4c-0.4,-0.3 -3.9,-3.2 -9.2,-3.2s-8.9,3.0 -9.2,3.2L13.0,22.0L13.0,22.0L13.0,22.0L13.0,22.0L13.0,22.0z"/> -</vector> + android:fillColor="@android:color/white" + android:pathData="M20.7,11.41L12,22L3.3,11.41c0.38-0.52,0.8-0.99,1.26-1.43C6.49,8.13,9.1,6.99,12,6.99s5.51,1.13,7.44,2.99 C19.9,10.41,20.33,10.89,20.7,11.41z" /> +</vector>
\ No newline at end of file diff --git a/core/res/res/drawable/ic_wifi_signal_4.xml b/core/res/res/drawable/ic_wifi_signal_4.xml index aca4551044ec..04b63af4a372 100644 --- a/core/res/res/drawable/ic_wifi_signal_4.xml +++ b/core/res/res/drawable/ic_wifi_signal_4.xml @@ -15,11 +15,11 @@ limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="26dp" + android:width="24dp" android:height="24dp" - android:viewportWidth="26" + android:viewportWidth="24" android:viewportHeight="24"> <path - android:fillColor="#FFFFFF" - android:pathData="M13.0,22.0L25.6,6.5C25.1,6.1 20.3,2.1 13.0,2.1S0.9,6.1 0.4,6.5L13.0,22.0L13.0,22.0L13.0,22.0L13.0,22.0L13.0,22.0z"/> -</vector> + android:fillColor="@android:color/white" + android:pathData="M24,7.39L12,22L0,7.39C2.97,4.08,7.25,2,12,2S21.03,4.08,24,7.39z" /> +</vector>
\ No newline at end of file diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 4b8a96cf3c4e..6f3adfd11a48 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -1434,7 +1434,7 @@ <string name="permdesc_mediaLocation">Allows the app to read locations from your media collection.</string> <!-- Title shown when the system-provided biometric dialog is shown, asking the user to authenticate. [CHAR LIMIT=40] --> - <string name="biometric_dialog_default_title">Application <xliff:g id="app" example="Gmail">%s</xliff:g> wants to authenticate.</string> + <string name="biometric_dialog_default_title">Verify it\u2018s you</string> <!-- Message shown when biometric hardware is not available [CHAR LIMIT=50] --> <string name="biometric_error_hw_unavailable">Biometric hardware unavailable</string> <!-- Message shown when biometric authentication was canceled by the user [CHAR LIMIT=50] --> diff --git a/libs/hwui/HWUIProperties.sysprop b/libs/hwui/HWUIProperties.sysprop index 42191ca6f514..34aeaae867f9 100644 --- a/libs/hwui/HWUIProperties.sysprop +++ b/libs/hwui/HWUIProperties.sysprop @@ -7,3 +7,10 @@ prop { scope: Public access: Readonly } +prop { + api_name: "render_ahead" + type: Integer + prop_name: "ro.hwui.render_ahead" + scope: Public + access: Readonly +}
\ No newline at end of file diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp index 046ffc4da5ea..9b1f25986d56 100644 --- a/libs/hwui/Properties.cpp +++ b/libs/hwui/Properties.cpp @@ -67,6 +67,7 @@ bool Properties::debuggingEnabled = false; bool Properties::isolatedProcess = false; int Properties::contextPriority = 0; +int Properties::defaultRenderAhead = 0; static int property_get_int(const char* key, int defaultValue) { char buf[PROPERTY_VALUE_MAX] = { @@ -129,6 +130,13 @@ bool Properties::load() { enableForceDarkSupport = property_get_bool(PROPERTY_ENABLE_FORCE_DARK, true); + defaultRenderAhead = std::max(0, std::min(2, property_get_int(PROPERTY_RENDERAHEAD, + render_ahead().value_or(0)))); + + if (defaultRenderAhead && sRenderPipelineType == RenderPipelineType::SkiaVulkan) { + ALOGW("hwui.render_ahead of %d ignored because pipeline is skiavk", defaultRenderAhead); + } + return (prevDebugLayersUpdates != debugLayersUpdates) || (prevDebugOverdraw != debugOverdraw); } diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h index 0a7f4e7eb41c..3e91c63fcbde 100644 --- a/libs/hwui/Properties.h +++ b/libs/hwui/Properties.h @@ -167,6 +167,8 @@ enum DebugLevel { #define PROPERTY_ENABLE_FORCE_DARK "debug.hwui.force_dark_enabled" +#define PROPERTY_RENDERAHEAD "debug.hwui.render_ahead" + /////////////////////////////////////////////////////////////////////////////// // Misc /////////////////////////////////////////////////////////////////////////////// @@ -251,6 +253,8 @@ public: ANDROID_API static int contextPriority; + static int defaultRenderAhead; + private: static ProfileType sProfileType; static bool sDisableProfileBars; diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index baa41c1ec698..4808d68b89ab 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -111,6 +111,7 @@ CanvasContext::CanvasContext(RenderThread& thread, bool translucent, RenderNode* rootRenderNode->makeRoot(); mRenderNodes.emplace_back(rootRenderNode); mProfiler.setDensity(mRenderThread.mainDisplayInfo().density); + setRenderAheadDepth(Properties::defaultRenderAhead); } CanvasContext::~CanvasContext() { @@ -159,6 +160,7 @@ void CanvasContext::setSurface(sp<Surface>&& surface) { if (hasSurface) { mHaveNewSurface = true; mSwapHistory.clear(); + applyRenderAheadSettings(); } else { mRenderThread.removeFrameCallback(this); mGenerationID++; @@ -423,6 +425,12 @@ void CanvasContext::draw() { waitOnFences(); + if (mRenderAheadDepth) { + auto presentTime = mCurrentFrameInfo->get(FrameInfoIndex::Vsync) + + (mRenderThread.timeLord().frameIntervalNanos() * (mRenderAheadDepth + 1)); + native_window_set_buffers_timestamp(mNativeSurface.get(), presentTime); + } + bool requireSwap = false; bool didSwap = mRenderPipeline->swapBuffers(frame, drew, windowDirty, mCurrentFrameInfo, &requireSwap); @@ -636,6 +644,28 @@ bool CanvasContext::surfaceRequiresRedraw() { return width == mLastFrameWidth && height == mLastFrameHeight; } +void CanvasContext::applyRenderAheadSettings() { + if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) { + // TODO: Fix SkiaVulkan's assumptions on buffer counts. And SIGBUS crashes. + mRenderAheadDepth = 0; + return; + } + if (mNativeSurface) { + native_window_set_buffer_count(mNativeSurface.get(), 3 + mRenderAheadDepth); + if (!mRenderAheadDepth) { + native_window_set_buffers_timestamp(mNativeSurface.get(), NATIVE_WINDOW_TIMESTAMP_AUTO); + } + } +} + +void CanvasContext::setRenderAheadDepth(int renderAhead) { + if (renderAhead < 0 || renderAhead > 2 || renderAhead == mRenderAheadDepth) { + return; + } + mRenderAheadDepth = renderAhead; + applyRenderAheadSettings(); +} + SkRect CanvasContext::computeDirtyRect(const Frame& frame, SkRect* dirty) { if (frame.width() != mLastFrameWidth || frame.height() != mLastFrameHeight) { // can't rely on prior content of window if viewport size changes diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h index abca34225f98..4a3119a55c77 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -204,6 +204,8 @@ public: return mUseForceDark; } + void setRenderAheadDepth(int renderAhead); + private: CanvasContext(RenderThread& thread, bool translucent, RenderNode* rootRenderNode, IContextFactory* contextFactory, std::unique_ptr<IRenderPipeline> renderPipeline); @@ -217,6 +219,7 @@ private: bool isSwapChainStuffed(); bool surfaceRequiresRedraw(); + void applyRenderAheadSettings(); SkRect computeDirtyRect(const Frame& frame, SkRect* dirty); @@ -235,6 +238,7 @@ private: // painted onto its surface. bool mIsDirty = false; SwapBehavior mSwapBehavior = SwapBehavior::kSwap_default; + int mRenderAheadDepth = 0; struct SwapHistory { SkRect damage; nsecs_t vsyncTime; diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp index 16240b4e177b..b58bab1191ed 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -312,6 +312,12 @@ void RenderProxy::setForceDark(bool enable) { mRenderThread.queue().post([this, enable]() { mContext->setForceDark(enable); }); } +void RenderProxy::setRenderAheadDepth(int renderAhead) { + mRenderThread.queue().post([ context = mContext, renderAhead ] { + context->setRenderAheadDepth(renderAhead); + }); +} + int RenderProxy::copySurfaceInto(sp<Surface>& surface, int left, int top, int right, int bottom, SkBitmap* bitmap) { auto& thread = RenderThread::getInstance(); diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h index a1a5551722bc..a0f08cbd26f9 100644 --- a/libs/hwui/renderthread/RenderProxy.h +++ b/libs/hwui/renderthread/RenderProxy.h @@ -123,6 +123,23 @@ public: ANDROID_API void removeFrameMetricsObserver(FrameMetricsObserver* observer); ANDROID_API void setForceDark(bool enable); + /** + * Sets a render-ahead depth on the backing renderer. This will increase latency by + * <swapInterval> * renderAhead and increase memory usage by (3 + renderAhead) * <resolution>. + * In return the renderer will be less susceptible to jitter, resulting in a smoother animation. + * + * Not recommended to use in response to anything touch driven, but for canned animations + * where latency is not a concern careful use may be beneficial. + * + * Note that when increasing this there will be a frame gap of N frames where N is + * renderAhead - <current renderAhead>. When decreasing this if there are any pending + * frames they will retain their prior renderAhead value, so it will take a few frames + * for the decrease to flush through. + * + * @param renderAhead How far to render ahead, must be in the range [0..2] + */ + ANDROID_API void setRenderAheadDepth(int renderAhead); + ANDROID_API static int copySurfaceInto(sp<Surface>& surface, int left, int top, int right, int bottom, SkBitmap* bitmap); ANDROID_API static void prepareToDraw(Bitmap& bitmap); diff --git a/libs/hwui/tests/common/TestScene.h b/libs/hwui/tests/common/TestScene.h index 91022cfe734b..74a039b3d090 100644 --- a/libs/hwui/tests/common/TestScene.h +++ b/libs/hwui/tests/common/TestScene.h @@ -38,6 +38,7 @@ public: int count = 0; int reportFrametimeWeight = 0; bool renderOffscreen = true; + int renderAhead = 0; }; template <class T> diff --git a/libs/hwui/tests/macrobench/TestSceneRunner.cpp b/libs/hwui/tests/macrobench/TestSceneRunner.cpp index b45dbc8b832b..aa579adfb2ce 100644 --- a/libs/hwui/tests/macrobench/TestSceneRunner.cpp +++ b/libs/hwui/tests/macrobench/TestSceneRunner.cpp @@ -154,6 +154,11 @@ void run(const TestScene::Info& info, const TestScene::Options& opts, proxy->resetProfileInfo(); proxy->fence(); + if (opts.renderAhead) { + usleep(33000); + } + proxy->setRenderAheadDepth(opts.renderAhead); + ModifiedMovingAverage<double> avgMs(opts.reportFrametimeWeight); nsecs_t start = systemTime(CLOCK_MONOTONIC); diff --git a/libs/hwui/tests/macrobench/main.cpp b/libs/hwui/tests/macrobench/main.cpp index 174a14080eff..88d33c315a09 100644 --- a/libs/hwui/tests/macrobench/main.cpp +++ b/libs/hwui/tests/macrobench/main.cpp @@ -69,6 +69,7 @@ OPTIONS: are offscreen rendered --benchmark_format Set output format. Possible values are tabular, json, csv --renderer=TYPE Sets the render pipeline to use. May be skiagl or skiavk + --render-ahead=NUM Sets how far to render-ahead. Must be 0 (default), 1, or 2. )"); } @@ -170,6 +171,7 @@ enum { Onscreen, Offscreen, Renderer, + RenderAhead, }; } @@ -185,6 +187,7 @@ static const struct option LONG_OPTIONS[] = { {"onscreen", no_argument, nullptr, LongOpts::Onscreen}, {"offscreen", no_argument, nullptr, LongOpts::Offscreen}, {"renderer", required_argument, nullptr, LongOpts::Renderer}, + {"render-ahead", required_argument, nullptr, LongOpts::RenderAhead}, {0, 0, 0, 0}}; static const char* SHORT_OPTIONS = "c:r:h"; @@ -283,6 +286,16 @@ void parseOptions(int argc, char* argv[]) { gOpts.renderOffscreen = true; break; + case LongOpts::RenderAhead: + if (!optarg) { + error = true; + } + gOpts.renderAhead = atoi(optarg); + if (gOpts.renderAhead < 0 || gOpts.renderAhead > 2) { + error = true; + } + break; + case 'h': printHelp(); exit(EXIT_SUCCESS); diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java index 4d63cc8825e3..8b667f772867 100644 --- a/media/java/android/media/MediaFormat.java +++ b/media/java/android/media/MediaFormat.java @@ -416,8 +416,8 @@ public final class MediaFormat { /** * An optional key describing whether encoders prepend headers to sync frames (e.g. * SPS and PPS to IDR frames for H.264). This is an optional parameter that applies only - * to video encoders. A video encoder may not support this feature; check the output - * format to verify that this feature was enabled. + * to video encoders. A video encoder may not support this feature; the component will fail + * to configure in that case. For other components, this key is ignored. * * The value is an integer, with 1 indicating to prepend headers to every sync frames, * or 0 otherwise. The default value is 0. diff --git a/native/webview/loader/loader.cpp b/native/webview/loader/loader.cpp index 7f71f6312f00..1265763d47d3 100644 --- a/native/webview/loader/loader.cpp +++ b/native/webview/loader/loader.cpp @@ -93,7 +93,8 @@ jboolean DoCreateRelroFile(JNIEnv* env, const char* lib, const char* relro, } android_dlextinfo extinfo; extinfo.flags = ANDROID_DLEXT_RESERVED_ADDRESS | ANDROID_DLEXT_WRITE_RELRO | - ANDROID_DLEXT_USE_NAMESPACE; + ANDROID_DLEXT_USE_NAMESPACE | + ANDROID_DLEXT_RESERVED_ADDRESS_RECURSIVE; extinfo.reserved_addr = gReservedAddress; extinfo.reserved_size = gReservedSize; extinfo.relro_fd = tmp_fd; @@ -131,7 +132,8 @@ jint DoLoadWithRelroFile(JNIEnv* env, const char* lib, const char* relro, } android_dlextinfo extinfo; extinfo.flags = ANDROID_DLEXT_RESERVED_ADDRESS | ANDROID_DLEXT_USE_RELRO | - ANDROID_DLEXT_USE_NAMESPACE; + ANDROID_DLEXT_USE_NAMESPACE | + ANDROID_DLEXT_RESERVED_ADDRESS_RECURSIVE; extinfo.reserved_addr = gReservedAddress; extinfo.reserved_size = gReservedSize; extinfo.relro_fd = relro_fd; diff --git a/packages/NetworkStack/tests/Android.bp b/packages/NetworkStack/tests/Android.bp index 0535af30681c..d0f419c929f8 100644 --- a/packages/NetworkStack/tests/Android.bp +++ b/packages/NetworkStack/tests/Android.bp @@ -42,6 +42,7 @@ android_test { "libbinder", "libbinderthreadstate", "libc++", + "libcgrouprc", "libcrypto", "libcutils", "libdexfile", diff --git a/packages/SystemUI/plugin_core/Android.bp b/packages/SystemUI/plugin_core/Android.bp index 58a8e494856e..42d67620b81d 100644 --- a/packages/SystemUI/plugin_core/Android.bp +++ b/packages/SystemUI/plugin_core/Android.bp @@ -13,9 +13,7 @@ // limitations under the License. java_library { - + sdk_version: "current", name: "PluginCoreLib", - srcs: ["src/**/*.java"], - } diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_1.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_1.xml index 675dfc947b7e..694b0ddc127f 100644 --- a/packages/SystemUI/res/drawable/ic_qs_wifi_1.xml +++ b/packages/SystemUI/res/drawable/ic_qs_wifi_1.xml @@ -16,17 +16,13 @@ <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" - android:viewportWidth="25.50" - android:viewportHeight="25.50"> - <group - android:translateX="0.77" - android:translateY="0.23" > - <path - android:pathData="M14,12h6.54l3.12,-3.89c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3C6.44,3 2.33,5.36 0.56,6.57C0.05,6.92 -0.05,7.63 0.33,8.11L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L14,20.13V12z" - android:fillAlpha="0.3" - android:fillColor="#FFFFFF"/> - <path - android:pathData="M14,20.13l-1.18,1.47c-0.43,0.53 -1.23,0.53 -1.66,0l-5.1,-6.35C7.65,13.85 9.72,13 12,13c0.69,0 1.36,0.08 2,0.23V20.13zM22.71,14.29L22.71,14.29c-0.38,-0.38 -1,-0.39 -1.38,0l-1.82,1.82l-1.82,-1.82c-0.38,-0.38 -1,-0.38 -1.38,0l-0.01,0.01c-0.38,0.38 -0.38,1 0,1.38l1.82,1.82l-1.83,1.83c-0.38,0.38 -0.38,1 0,1.38l0.01,0.01c0.38,0.38 1,0.38 1.38,0l1.83,-1.83l1.83,1.83c0.38,0.38 1,0.38 1.38,0v0c0.38,-0.38 0.38,-1 0,-1.38l-1.83,-1.83l1.83,-1.83C23.09,15.29 23.09,14.67 22.71,14.29z" - android:fillColor="#FFFFFF"/> - </group> + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="@android:color/white" + android:pathData="M22,16.41L20.59,15l-2.09,2.09L16.41,15L15,16.41l2.09,2.09L15,20.59L16.41,22l2.09,-2.08L20.59,22L22,20.59l-2.08,-2.09L22,16.41z"/> + <path + android:fillColor="@android:color/white" + android:pathData="M12,2.01C7.25,2.01 2.97,4.09 0,7.4L7.582,16.625C7.582,16.627 7.58,16.629 7.58,16.631L11.99,22L12,22L13,20.789L13,17.641L13,13.119C12.68,13.039 12.34,13 12,13C10.601,13 9.351,13.64 8.531,14.639L2.699,7.539C5.269,5.279 8.58,4.01 12,4.01C15.42,4.01 18.731,5.279 21.301,7.539L16.811,13L19.4,13L24,7.4C21.03,4.09 16.75,2.01 12,2.01z" + android:fillAlpha="0.3"/> </vector> diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_2.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_2.xml index c9a7eb8fd362..dcb3fa82eb5d 100644 --- a/packages/SystemUI/res/drawable/ic_qs_wifi_2.xml +++ b/packages/SystemUI/res/drawable/ic_qs_wifi_2.xml @@ -16,17 +16,13 @@ <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" - android:viewportWidth="25.50" - android:viewportHeight="25.50"> - <group - android:translateX="0.77" - android:translateY="0.23" > - <path - android:pathData="M14,12h6.54l3.12,-3.89c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3C6.44,3 2.33,5.36 0.56,6.57C0.05,6.92 -0.05,7.63 0.33,8.11L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L14,20.13V12z" - android:fillAlpha="0.3" - android:fillColor="#FFFFFF"/> - <path - android:pathData="M14,20.13l-1.18,1.47c-0.43,0.53 -1.23,0.53 -1.66,0l-6.98,-8.7C6.28,11.1 9.01,10 12,10c2.45,0 4.72,0.74 6.62,2H14V20.13zM22.71,14.29L22.71,14.29c-0.38,-0.38 -1,-0.39 -1.38,0l-1.82,1.82l-1.82,-1.82c-0.38,-0.38 -1,-0.38 -1.38,0l-0.01,0.01c-0.38,0.38 -0.38,1 0,1.38l1.82,1.82l-1.83,1.83c-0.38,0.38 -0.38,1 0,1.38l0.01,0.01c0.38,0.38 1,0.38 1.38,0l1.83,-1.83l1.83,1.83c0.38,0.38 1,0.38 1.38,0v0c0.38,-0.38 0.38,-1 0,-1.38l-1.83,-1.83l1.83,-1.83C23.09,15.29 23.09,14.67 22.71,14.29z" - android:fillColor="#FFFFFF"/> - </group> + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="@android:color/white" + android:pathData="M22,16.41L20.59,15l-2.09,2.09L16.41,15L15,16.41l2.09,2.09L15,20.59L16.41,22l2.09,-2.08L20.59,22L22,20.59l-2.08,-2.09L22,16.41z"/> + <path + android:fillColor="@android:color/white" + android:pathData="M12,2C7.25,2 2.97,4.081 0,7.391L12,22L13,20.779L13,17.631L13,13L16.801,13L18,13L19.391,13L24,7.391C21.03,4.081 16.75,2 12,2zM12,4C14.747,4 17.423,4.819 19.701,6.313C20.259,6.678 20.795,7.085 21.301,7.529L17.389,12.287C16.029,10.868 14.119,9.99 12,9.99C9.88,9.99 7.969,10.869 6.609,12.289L2.699,7.529C5.269,5.269 8.58,4 12,4z" + android:fillAlpha="0.3"/> </vector> diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_3.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_3.xml index a6facaed82d8..d68a2f6fe426 100644 --- a/packages/SystemUI/res/drawable/ic_qs_wifi_3.xml +++ b/packages/SystemUI/res/drawable/ic_qs_wifi_3.xml @@ -16,17 +16,13 @@ <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" - android:viewportWidth="25.50" - android:viewportHeight="25.50"> - <group - android:translateX="0.77" - android:translateY="0.23" > - <path - android:pathData="M14,12h6.54l3.12,-3.89c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3C6.44,3 2.33,5.36 0.56,6.57C0.05,6.92 -0.05,7.63 0.33,8.11L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L14,20.13V12z" - android:fillAlpha="0.3" - android:fillColor="#FFFFFF"/> - <path - android:pathData="M14,20.13l-1.18,1.47c-0.43,0.53 -1.23,0.53 -1.66,0L2.93,11.35C5.37,9.26 8.54,8 12,8c3.46,0 6.62,1.26 9.07,3.34L20.54,12H14V20.13zM22.71,14.29L22.71,14.29c-0.38,-0.38 -1,-0.39 -1.38,0l-1.82,1.82l-1.82,-1.82c-0.38,-0.38 -1,-0.38 -1.38,0l-0.01,0.01c-0.38,0.38 -0.38,1 0,1.38l1.82,1.82l-1.83,1.83c-0.38,0.38 -0.38,1 0,1.38l0.01,0.01c0.38,0.38 1,0.38 1.38,0l1.83,-1.83l1.83,1.83c0.38,0.38 1,0.38 1.38,0v0c0.38,-0.38 0.38,-1 0,-1.38l-1.83,-1.83l1.83,-1.83C23.09,15.29 23.09,14.67 22.71,14.29z" - android:fillColor="#FFFFFF"/> - </group> + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="@android:color/white" + android:pathData="M22,16.41L20.59,15l-2.09,2.09L16.41,15L15,16.41l2.09,2.09L15,20.59L16.41,22l2.09,-2.08L20.59,22L22,20.59l-2.08,-2.09L22,16.41z"/> + <path + android:fillColor="@android:color/white" + android:pathData="M12,2C7.25,2 2.97,4.081 0,7.391L3.301,11.41L12,22L13,20.779L13,17.631L13,13L16.801,13L19.391,13L20.699,11.41C20.699,11.409 20.698,11.409 20.697,11.408L24,7.391C21.03,4.081 16.75,2 12,2zM12,4C15.42,4 18.731,5.269 21.301,7.529L19.35,9.9C17.43,8.1 14.86,6.99 12,6.99C9.14,6.99 6.57,8.1 4.65,9.9C4.65,9.901 4.649,9.902 4.648,9.902L2.699,7.529C5.269,5.269 8.58,4 12,4z" + android:fillAlpha="0.3"/> </vector> diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_4.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_4.xml index 2eae8f5b3318..886cc3534322 100644 --- a/packages/SystemUI/res/drawable/ic_qs_wifi_4.xml +++ b/packages/SystemUI/res/drawable/ic_qs_wifi_4.xml @@ -16,13 +16,13 @@ <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" - android:viewportWidth="25.50" - android:viewportHeight="25.50"> - <group - android:translateX="0.77" - android:translateY="0.23" > - <path - android:pathData="M22.71,15.67l-1.83,1.83l1.83,1.83c0.38,0.38 0.38,1 0,1.38v0c-0.38,0.38 -1,0.39 -1.38,0l-1.83,-1.83l-1.83,1.83c-0.38,0.38 -1,0.38 -1.38,0l-0.01,-0.01c-0.38,-0.38 -0.38,-1 0,-1.38l1.83,-1.83l-1.82,-1.82c-0.38,-0.38 -0.38,-1 0,-1.38l0.01,-0.01c0.38,-0.38 1,-0.38 1.38,0l1.82,1.82l1.82,-1.82c0.38,-0.38 1,-0.38 1.38,0l0,0C23.09,14.67 23.09,15.29 22.71,15.67zM14,12h6.54l3.12,-3.89c0.39,-0.48 0.28,-1.19 -0.23,-1.54C21.66,5.36 17.55,3 12,3C6.44,3 2.33,5.36 0.56,6.57C0.05,6.92 -0.05,7.63 0.33,8.11L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L14,20.13V12z" - android:fillColor="#FFFFFF"/> - </group> + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="@android:color/white" + android:pathData="M12,2C7.25,2 2.97,4.08 0,7.39L12,22l1,-1.22V13h6.39L24,7.39C21.03,4.08 16.75,2 12,2z" + android:fillAlpha="0.3"/> + <path + android:fillColor="@android:color/white" + android:pathData="M22,16.41L20.59,15l-2.09,2.09L16.41,15L15,16.41l2.09,2.09L15,20.59L16.41,22l2.09,-2.08L20.59,22L22,20.59l-2.08,-2.09L22,16.41z"/> </vector> diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_detail_empty.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_detail_empty.xml deleted file mode 100644 index 30024dd64a3e..000000000000 --- a/packages/SystemUI/res/drawable/ic_qs_wifi_detail_empty.xml +++ /dev/null @@ -1,30 +0,0 @@ -<!-- -Copyright (C) 2017 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. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="32dp" - android:height="29.5dp" - android:viewportWidth="25.6" - android:viewportHeight="23.6" - android:alpha="0.14" - android:tint="?android:attr/colorForeground" > - <group - android:translateX="0.51" - android:translateY="-1.1"> - <path - android:pathData="M23.66,8.11c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3 6.44,3 2.33,5.36 0.56,6.57c-0.51,0.35 -0.61,1.06 -0.23,1.54L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L23.66,8.11z" - android:fillColor="#FFFFFF"/> - </group> -</vector> diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_disconnected.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_disconnected.xml index cb87caeb1b8d..3c45761ca4dd 100644 --- a/packages/SystemUI/res/drawable/ic_qs_wifi_disconnected.xml +++ b/packages/SystemUI/res/drawable/ic_qs_wifi_disconnected.xml @@ -14,19 +14,20 @@ limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="26dp" + android:width="24dp" android:height="24dp" - android:viewportWidth="25.6" - android:viewportHeight="23.7"> - <group - android:translateX="0.82" - android:translateY="-1"> - <path - android:pathData="M18.9,20.85c0,-0.61 0.49,-1.1 1.1,-1.1 0.61,0 1.1,0.49 1.1,1.1 0,0.61 -0.49,1.1 -1.1,1.1 -0.61,0 -1.1,-0.49 -1.1,-1.1zM20,10c-1.53,0 -2.84,0.99 -3.31,2.36 -0.19,0.56 0.23,1.14 0.81,1.14 0.36,0 0.72,-0.21 0.84,-0.55 0.23,-0.7 0.89,-1.2 1.66,-1.2 0.97,0 1.75,0.78 1.75,1.75 0,0.48 -0.2,0.92 -0.51,1.24l-1.09,1.1c-0.69,0.69 -0.92,1.38 -0.99,2.2 -0.04,0.51 0.36,0.96 0.88,0.96 0.44,0 0.83,-0.33 0.87,-0.77 0.07,-0.79 0.31,-1.27 1,-1.95l0.78,-0.8c0.5,-0.5 0.82,-1.2 0.82,-1.97C23.5,11.57 21.93,10 20,10z" - android:fillColor="#FFFFFFFF"/> - <path - android:pathData="M14.73,12.88c0,-2.7 2.19,-4.88 4.88,-4.88 1.22,0 2.32,0.46 3.18,1.2l0.88,-1.09c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3 6.44,3 2.33,5.36 0.56,6.57c-0.51,0.35 -0.61,1.06 -0.23,1.54L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0l3.88,-4.82a4.862,4.862 0,0 1,-1.97 -3.9z" - android:fillAlpha="0.3" - android:fillColor="#FFFFFFFF"/> - </group> -</vector> + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="@android:color/white" + android:fillAlpha="0.3" + android:strokeAlpha="0.3" + android:strokeWidth="1" + android:pathData="M12,2C7.25,2,2.97,4.08,0,7.39L12,22l3.18-3.87c-0.46-0.57-0.79-1.24-0.98-1.96L12,18.85L2.7,7.53 C5.27,5.27,8.58,4,12,4s6.73,1.27,9.3,3.53l-1.43,1.74c0.76,0.04,1.47,0.24,2.12,0.57L24,7.39C21.03,4.08,16.75,2,12,2z" /> + <path + android:fillColor="@android:color/white" + android:pathData="M 18.63 20.25 H 20.38 V 22 H 18.63 V 20.25 Z" /> + <path + android:fillColor="@android:color/white" + android:pathData="M19.5,11.25c-1.93,0-3.5,1.57-3.5,3.5h1.75c0-0.96,0.79-1.75,1.75-1.75s1.75,0.79,1.75,1.75c0,1.76-2.62,1.54-2.62,4.38 h1.75c0-1.97,2.62-2.19,2.62-4.38C23,12.82,21.43,11.25,19.5,11.25z" /> +</vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_no_network.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_no_network.xml deleted file mode 100644 index e59e7f4b61e3..000000000000 --- a/packages/SystemUI/res/drawable/ic_qs_wifi_no_network.xml +++ /dev/null @@ -1,24 +0,0 @@ -<!-- -Copyright (C) 2014 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. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="32.0dp" - android:height="29.5dp" - android:viewportWidth="26.0" - android:viewportHeight="24.0"> - <path - android:fillColor="#FFFFFFFF" - android:pathData="M13.000000,2.000000C7.700000,2.000000 3.700000,3.900000 0.400000,6.400000L13.000000,22.000000L25.600000,6.500000C22.299999,4.000000 18.299999,2.000000 13.000000,2.000000zM13.000000,18.600000L3.300000,7.000000l0.000000,0.000000l0.000000,0.000000C6.000000,5.300000 8.700000,4.000000 13.000000,4.000000s7.000000,1.400000 9.700000,3.000000l0.000000,0.000000l0.000000,0.000000L13.000000,18.600000z"/> -</vector> diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_0.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_0.xml deleted file mode 100644 index 56ca422758fa..000000000000 --- a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_0.xml +++ /dev/null @@ -1,31 +0,0 @@ -<!-- - Copyright (C) 2017 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. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="16.41dp" - android:height="16.41dp" - android:viewportWidth="21.2" - android:viewportHeight="21.2"> - <group - android:translateX="0.5" - android:translateY="2.0"> - <path - android:pathData="M18.79,9.79c-0.32,-0.32 -0.83,-0.32 -1.15,0L16.43,11l-1.21,-1.21c-0.32,-0.32 -0.83,-0.32 -1.15,0L14.06,9.8l0,0c-0.32,0.32 -0.32,0.83 0,1.15l1.21,1.21l-1.21,1.21l0,0c-0.32,0.32 -0.32,0.83 0,1.15l0.01,0.01c0.32,0.32 0.83,0.32 1.15,0l1.21,-1.21l1.21,1.21c0.32,0.32 0.83,0.32 1.15,0c0.32,-0.32 0.32,-0.83 0,-1.15l-1.21,-1.21l1.21,-1.21C19.1,10.64 19.1,10.13 18.79,9.79z" - android:fillColor="?attr/fillColor"/> - <path - android:pathData="M11.69,7.44h6.27L19.95,5c0.4,-0.49 0.3,-1.22 -0.23,-1.56c-1.6,-1.05 -5.04,-2.9 -9.62,-2.9c-4.59,0 -8.03,1.85 -9.62,2.9C-0.05,3.78 -0.16,4.51 0.24,5l9.02,11.08c0.42,0.52 1.22,0.52 1.64,0l0.78,-0.96V7.44z" - android:fillColor="?attr/backgroundColor"/> - </group> -</vector> diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_0_fully.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_0_fully.xml deleted file mode 100644 index 737d5a0f3d97..000000000000 --- a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_0_fully.xml +++ /dev/null @@ -1,28 +0,0 @@ -<!-- -Copyright (C) 2017 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. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="16.25dp" - android:height="15dp" - android:viewportWidth="21.66" - android:viewportHeight="20"> - <group - android:translateX="0.74" - android:translateY="1.2"> - <path - android:pathData="M19.95,5c0.4,-0.49 0.3,-1.22 -0.23,-1.56 -1.6,-1.05 -5.04,-2.9 -9.62,-2.9 -4.59,0 -8.03,1.85 -9.62,2.9C-0.05,3.78 -0.16,4.51 0.24,5l9.02,11.08c0.42,0.52 1.22,0.52 1.64,0L19.95,5z" - android:fillColor="?attr/backgroundColor"/> - </group> -</vector> diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_1.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_1.xml deleted file mode 100644 index e5b0d1a94890..000000000000 --- a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_1.xml +++ /dev/null @@ -1,34 +0,0 @@ -<!-- - Copyright (C) 2017 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. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="16.41dp" - android:height="16.41dp" - android:viewportWidth="21.7" - android:viewportHeight="21.7"> - <group - android:translateY="2.2" - android:translateX="0.75"> - <path - android:pathData="M11.69,7.44h6.27L19.95,5c0.4,-0.49 0.3,-1.22 -0.23,-1.56c-1.6,-1.05 -5.04,-2.9 -9.62,-2.9c-4.59,0 -8.03,1.85 -9.62,2.9C-0.05,3.78 -0.16,4.51 0.24,5l9.02,11.08c0.42,0.52 1.22,0.52 1.64,0l0.78,-0.96V7.44z" - android:fillColor="?attr/backgroundColor" /> - <path - android:pathData="M5.02,10.86l4.25,5.21c0.42,0.52 1.22,0.52 1.64,0l0.78,-0.96V9.14c-0.51,-0.11 -1.05,-0.17 -1.59,-0.17C8.15,8.97 6.37,9.69 5.02,10.86z" - android:fillColor="?attr/fillColor" /> - <path - android:pathData="M17.57,12.17l1.21,-1.21c0.32,-0.32 0.32,-0.83 0,-1.17c-0.32,-0.32 -0.83,-0.32 -1.15,0L16.43,11l-1.21,-1.21c-0.32,-0.32 -0.83,-0.32 -1.15,0L14.06,9.8c-0.32,0.32 -0.32,0.83 0,1.15l1.21,1.21l-1.21,1.21c-0.32,0.32 -0.32,0.83 0,1.15l0.01,0.01c0.32,0.32 0.83,0.32 1.15,0l1.21,-1.21l1.21,1.21c0.32,0.32 0.83,0.32 1.15,0c0.32,-0.32 0.32,-0.83 0,-1.15L17.57,12.17z" - android:fillColor="?attr/fillColor" /> - </group> -</vector> diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_1_fully.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_1_fully.xml deleted file mode 100644 index 5d6457044974..000000000000 --- a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_1_fully.xml +++ /dev/null @@ -1,31 +0,0 @@ -<!-- -Copyright (C) 2017 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. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="16.25dp" - android:height="15dp" - android:viewportWidth="21.66" - android:viewportHeight="20.0"> - <group - android:translateX="0.79" - android:translateY="1.2"> - <path - android:pathData="M19.95,5c0.4,-0.49 0.3,-1.22 -0.23,-1.56 -1.6,-1.05 -5.04,-2.9 -9.62,-2.9 -4.59,0 -8.03,1.85 -9.62,2.9C-0.05,3.78 -0.16,4.51 0.24,5l9.02,11.08c0.42,0.52 1.22,0.52 1.64,0L19.95,5z" - android:fillColor="?attr/backgroundColor"/> - <path - android:pathData="M10.1,8.97c-1.95,0 -3.72,0.72 -5.08,1.9l4.25,5.21c0.42,0.52 1.22,0.52 1.64,0l4.26,-5.22a7.702,7.702 0,0 0,-5.07 -1.89z" - android:fillColor="?attr/fillColor"/> - </group> -</vector> diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_2.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_2.xml deleted file mode 100644 index b3ee86e5cd6a..000000000000 --- a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_2.xml +++ /dev/null @@ -1,34 +0,0 @@ -<!-- - Copyright (C) 2017 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. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="16.41dp" - android:height="16.41dp" - android:viewportWidth="21.7" - android:viewportHeight="21.7"> - <group - android:translateX="0.75" - android:translateY="2.2" > - <path - android:pathData="M11.69,7.44h6.27L19.95,5c0.4,-0.49 0.3,-1.22 -0.23,-1.56c-1.6,-1.05 -5.04,-2.9 -9.62,-2.9c-4.59,0 -8.03,1.85 -9.62,2.9C-0.05,3.78 -0.16,4.51 0.24,5l9.02,11.08c0.42,0.52 1.22,0.52 1.64,0l0.78,-0.96V7.44z" - android:fillColor="?attr/backgroundColor"/> - <path - android:pathData="M10.09,6.44c-2.55,0 -4.88,0.93 -6.68,2.45l5.85,7.18c0.42,0.52 1.22,0.52 1.64,0l0.78,-0.96V7.44h2.84C13.18,6.8 11.68,6.44 10.09,6.44z" - android:fillColor="?attr/fillColor"/> - <path - android:pathData="M17.57,12.17l1.21,-1.21c0.32,-0.32 0.32,-0.83 0,-1.17c-0.32,-0.32 -0.83,-0.32 -1.15,0L16.43,11l-1.21,-1.21c-0.32,-0.32 -0.83,-0.32 -1.15,0L14.06,9.8c-0.32,0.32 -0.32,0.83 0,1.15l1.21,1.21l-1.21,1.21c-0.32,0.32 -0.32,0.83 0,1.15l0.01,0.01c0.32,0.32 0.83,0.32 1.15,0l1.21,-1.21l1.21,1.21c0.32,0.32 0.83,0.32 1.15,0c0.32,-0.32 0.32,-0.83 0,-1.15L17.57,12.17z" - android:fillColor="?attr/fillColor"/> - </group> -</vector> diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_2_fully.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_2_fully.xml deleted file mode 100644 index 012e74250e65..000000000000 --- a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_2_fully.xml +++ /dev/null @@ -1,31 +0,0 @@ -<!-- -Copyright (C) 2017 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. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" -android:width="16.24dp" -android:height="15dp" -android:viewportWidth="21.86" -android:viewportHeight="20.19"> - <group - android:translateX="0.85" - android:translateY="1.4" > - <path - android:pathData="M19.95,5c0.4,-0.49 0.3,-1.22 -0.23,-1.56 -1.6,-1.05 -5.04,-2.9 -9.62,-2.9 -4.59,0 -8.03,1.85 -9.62,2.9C-0.05,3.78 -0.16,4.51 0.24,5l9.02,11.08c0.42,0.52 1.22,0.52 1.64,0L19.95,5z" - android:fillColor="?attr/backgroundColor" /> - <path - android:pathData="M10.09,6.44c-2.55,0 -4.88,0.93 -6.68,2.45l5.85,7.18c0.42,0.52 1.22,0.52 1.64,0l5.86,-7.19a10.284,10.284 0,0 0,-6.67 -2.44z" - android:fillColor="?attr/fillColor" /> - </group> -</vector> diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_3.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_3.xml deleted file mode 100644 index 9b919c187913..000000000000 --- a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_3.xml +++ /dev/null @@ -1,34 +0,0 @@ -<!-- - Copyright (C) 2017 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. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="16.41dp" - android:height="16.41dp" - android:viewportWidth="21.7" - android:viewportHeight="21.7"> - <group - android:translateX="0.75" - android:translateY="2.3" > - <path - android:pathData="M11.69,7.44h6.27L19.95,5c0.4,-0.49 0.3,-1.22 -0.23,-1.56c-1.6,-1.05 -5.04,-2.9 -9.62,-2.9c-4.59,0 -8.03,1.85 -9.62,2.9C-0.05,3.78 -0.16,4.51 0.24,5l9.02,11.08c0.42,0.52 1.22,0.52 1.64,0l0.78,-0.96V7.44z" - android:fillColor="?attr/backgroundColor"/> - <path - android:pathData="M10.08,4.75c-2.96,0 -5.66,1.06 -7.74,2.82l6.93,8.5c0.21,0.26 0.51,0.39 0.82,0.39c0.22,0 0.44,-0.07 0.63,-0.2c0.07,-0.05 0.14,-0.11 0.2,-0.19l0.78,-0.96V7.44h5.98C15.6,5.77 12.96,4.75 10.08,4.75z" - android:fillColor="?attr/fillColor"/> - <path - android:pathData="M17.57,12.17l1.21,-1.21c0.32,-0.32 0.32,-0.83 0,-1.17c-0.32,-0.32 -0.83,-0.32 -1.15,0L16.43,11l-1.21,-1.21c-0.32,-0.32 -0.83,-0.32 -1.15,0L14.06,9.8c-0.32,0.32 -0.32,0.83 0,1.15l1.21,1.21l-1.21,1.21c-0.32,0.32 -0.32,0.83 0,1.15l0.01,0.01c0.32,0.32 0.83,0.32 1.15,0l1.21,-1.21l1.21,1.21c0.32,0.32 0.83,0.32 1.15,0c0.32,-0.32 0.32,-0.83 0,-1.15L17.57,12.17z" - android:fillColor="?attr/fillColor"/> - </group> -</vector> diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_3_fully.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_3_fully.xml deleted file mode 100644 index 5a61d2a69f68..000000000000 --- a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_3_fully.xml +++ /dev/null @@ -1,31 +0,0 @@ -<!-- -Copyright (C) 2017 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. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="16.27dp" - android:height="15dp" - android:viewportWidth="21.80" - android:viewportHeight="20.1"> - <group - android:translateX="0.81" - android:translateY="1.29" > - <path - android:pathData="M19.95,5c0.4,-0.49 0.3,-1.22 -0.23,-1.56 -1.6,-1.05 -5.04,-2.9 -9.62,-2.9 -4.59,0 -8.03,1.85 -9.62,2.9C-0.05,3.78 -0.16,4.51 0.24,5l9.02,11.08c0.42,0.52 1.22,0.52 1.64,0L19.95,5z" - android:fillColor="?attr/backgroundColor"/> - <path - android:pathData="M10.08,4.75c-2.96,0 -5.66,1.06 -7.74,2.82l6.93,8.5c0.21,0.26 0.51,0.39 0.82,0.39 0.23,0 0.46,-0.07 0.65,-0.22 -0.02,0.02 -0.04,0.03 -0.07,0.05 0.09,-0.06 0.17,-0.13 0.24,-0.22l6.93,-8.5c-2.09,-1.74 -4.8,-2.82 -7.76,-2.82z" - android:fillColor="?attr/fillColor"/> - </group> -</vector> diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_4.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_4.xml deleted file mode 100644 index 144af5af3bdb..000000000000 --- a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_4.xml +++ /dev/null @@ -1,29 +0,0 @@ -<!-- - Copyright (C) 2017 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. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="16.41dp" - android:height="16.41dp" - android:viewportWidth="21.95" - android:viewportHeight="21.65"> - <group - android:translateX="0.90" - android:translateY="2.25" - > - <path - android:pathData="M11.69,15.12l-0.78,0.96c-0.43,0.52 -1.22,0.52 -1.64,0L0.24,5c-0.4,-0.49 -0.29,-1.22 0.23,-1.56c1.59,-1.05 5.03,-2.9 9.62,-2.9c4.59,0 8.02,1.85 9.62,2.9c0.53,0.35 0.63,1.08 0.23,1.56l-1.99,2.44h-6.27V15.12zM18.79,9.79c-0.32,-0.32 -0.83,-0.32 -1.15,0L16.43,11l-1.21,-1.21c-0.32,-0.32 -0.83,-0.32 -1.15,0L14.06,9.8l0,0c-0.32,0.32 -0.32,0.83 0,1.15l1.21,1.21l-1.21,1.21l0,0c-0.32,0.32 -0.32,0.83 0,1.15l0.01,0.01c0.32,0.32 0.83,0.32 1.15,0l1.21,-1.21l1.21,1.21c0.32,0.32 0.83,0.32 1.15,0c0.32,-0.32 0.32,-0.83 0,-1.15l-1.21,-1.21l1.21,-1.21C19.1,10.64 19.1,10.13 18.79,9.79z" - android:fillColor="?attr/singleToneColor"/> - </group> -</vector> diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_4_fully.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_4_fully.xml deleted file mode 100644 index 6c9f983b41dd..000000000000 --- a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_4_fully.xml +++ /dev/null @@ -1,28 +0,0 @@ -<!-- -Copyright (C) 2017 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. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="16.31dp" - android:height="15dp" - android:viewportWidth="21.75" - android:viewportHeight="20.0"> - <group - android:translateX="0.80" - android:translateY="1.25"> - <path - android:pathData="M19.95,5c0.4,-0.49 0.3,-1.22 -0.23,-1.56 -1.6,-1.05 -5.04,-2.9 -9.62,-2.9 -4.59,0 -8.03,1.85 -9.62,2.9C-0.05,3.78 -0.16,4.51 0.24,5l9.02,11.08c0.42,0.52 1.22,0.52 1.64,0L19.95,5z" - android:fillColor="?attr/singleToneColor"/> - </group> -</vector> diff --git a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_null.xml b/packages/SystemUI/res/drawable/stat_sys_wifi_signal_null.xml deleted file mode 100644 index 330daa4d0e7b..000000000000 --- a/packages/SystemUI/res/drawable/stat_sys_wifi_signal_null.xml +++ /dev/null @@ -1,24 +0,0 @@ -<!-- -Copyright (C) 2014 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. ---> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="16.25dp" - android:height="17dp" - android:viewportWidth="26.0" - android:viewportHeight="24.0"> - <path - android:fillColor="?attr/backgroundColor" - android:pathData="M13.000000,2.000000C7.700000,2.000000 3.700000,3.900000 0.400000,6.400000L13.000000,22.000000L25.600000,6.500000C22.299999,4.000000 18.299999,2.000000 13.000000,2.000000zM13.000000,18.600000L3.300000,7.000000l0.000000,0.000000l0.000000,0.000000C6.000000,5.300000 8.700000,4.000000 13.000000,4.000000s7.000000,1.400000 9.700000,3.000000l0.000000,0.000000l0.000000,0.000000L13.000000,18.600000z"/> -</vector> diff --git a/packages/SystemUI/res/layout/status_bar_wifi_group.xml b/packages/SystemUI/res/layout/status_bar_wifi_group.xml index c419b907ab17..35cce25d45a7 100644 --- a/packages/SystemUI/res/layout/status_bar_wifi_group.xml +++ b/packages/SystemUI/res/layout/status_bar_wifi_group.xml @@ -59,10 +59,9 @@ android:layout_width="wrap_content" android:gravity="center_vertical" > <com.android.systemui.statusbar.AlphaOptimizedImageView - android:theme="?attr/lightIconTheme" android:id="@+id/wifi_signal" - android:layout_height="wrap_content" - android:layout_width="wrap_content" /> + android:layout_height="@dimen/status_bar_wifi_signal_size" + android:layout_width="@dimen/status_bar_wifi_signal_size" /> </FrameLayout> <View diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index a02469ee9fb9..95a4da670417 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -79,6 +79,9 @@ <!-- Spacing after the wifi signals that is present if there are any icons following it. --> <dimen name="status_bar_wifi_signal_spacer_width">2.5dp</dimen> + <!-- Size of the view displaying the wifi signal icon in the status bar. --> + <dimen name="status_bar_wifi_signal_size">15dp</dimen> + <!-- Spacing before the airplane mode icon if there are any icons preceding it. --> <dimen name="status_bar_airplane_spacer_width">4dp</dimen> diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java index a5aed87f5e21..56b231bba83e 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java @@ -109,11 +109,6 @@ public class BubbleController implements BubbleExpandedView.OnBubbleBlockedListe /** Use an activityView for an auto-bubbled notifs if it has an appropriate content intent */ private static final String ENABLE_BUBBLE_CONTENT_INTENT = "experiment_bubble_content_intent"; - /** Whether the row of bubble circles are anchored to the top or bottom of the screen. */ - private static final String ENABLE_BUBBLES_AT_TOP = "experiment_enable_top_bubbles"; - /** Flag to position the header below the activity view */ - private static final String ENABLE_BUBBLE_FOOTER = "experiment_enable_bubble_footer"; - private static final String BUBBLE_STIFFNESS = "experiment_bubble_stiffness"; private static final String BUBBLE_BOUNCINESS = "experiment_bubble_bounciness"; @@ -607,22 +602,6 @@ public class BubbleController implements BubbleExpandedView.OnBubbleBlockedListe ENABLE_BUBBLES, 1) != 0; } - /** - * Whether bubbles should be positioned at the top of the screen or not. - */ - public static boolean showBubblesAtTop(Context context) { - return Settings.Secure.getInt(context.getContentResolver(), - ENABLE_BUBBLES_AT_TOP, 0) != 0; - } - - /** - * Whether the bubble chrome should display as a footer or not (in which case it's a header). - */ - public static boolean useFooter(Context context) { - return Settings.Secure.getInt(context.getContentResolver(), - ENABLE_BUBBLE_FOOTER, 0) != 0; - } - /** Default stiffness to use for bubble physics animations. */ public static int getBubbleStiffness(Context context, int defaultStiffness) { return Settings.Secure.getInt( diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java index 6c2db76e19e1..e8b11226539a 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java @@ -74,10 +74,6 @@ import com.android.systemui.statusbar.notification.stack.ExpandableViewState; public class BubbleExpandedView extends LinearLayout implements View.OnClickListener { private static final String TAG = "BubbleExpandedView"; - // Configurable via bubble settings; just for testing - private boolean mUseFooter; - private boolean mShowOnTop; - // The triangle pointing to the expanded view private View mPointerView; private int mPointerMargin; @@ -185,11 +181,8 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList int bgColor = ta.getColor(0, Color.WHITE); ta.recycle(); - mShowOnTop = BubbleController.showBubblesAtTop(getContext()); - mUseFooter = BubbleController.useFooter(getContext()); - ShapeDrawable triangleDrawable = new ShapeDrawable( - TriangleShape.create(width, height, mShowOnTop /* pointUp */)); + TriangleShape.create(width, height, false /* pointUp */)); triangleDrawable.setTint(bgColor); mPointerView.setBackground(triangleDrawable); @@ -238,18 +231,6 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList } return view.onApplyWindowInsets(insets); }); - - if (!mShowOnTop) { - removeView(mPointerView); - if (mUseFooter) { - View divider = findViewById(R.id.divider); - viewWrapper.removeView(divider); - removeView(viewWrapper); - addView(divider); - addView(viewWrapper); - } - addView(mPointerView); - } } @Override @@ -289,9 +270,7 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList final float cr = ta2.getDimension(0, 0f); ta2.recycle(); - float[] radii = mUseFooter - ? new float[] {0, 0, 0, 0, cr, cr, cr, cr} - : new float[] {cr, cr, cr, cr, 0, 0, 0, 0}; + float[] radii = new float[] {cr, cr, cr, cr, 0, 0, 0, 0}; GradientDrawable chromeBackground = new GradientDrawable(); chromeBackground.setShape(GradientDrawable.RECTANGLE); chromeBackground.setCornerRadii(radii); @@ -353,11 +332,7 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList // Still in the shade... remove it parent.removeView(mNotifRow); } - if (mShowOnTop) { - addView(mNotifRow); - } else { - addView(mNotifRow, mUseFooter ? 0 : 1); - } + addView(mNotifRow, 1 /* index */); } } diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java index de4605b55272..b1998c497022 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java @@ -303,6 +303,7 @@ public class BubbleStackView extends FrameLayout { */ public void onConfigChanged() { for (Bubble b: mBubbleData.getBubbles()) { + b.iconView.updateViews(); b.expandedView.updateHeaderColor(); } } @@ -809,28 +810,16 @@ public class BubbleStackView extends FrameLayout { * y position when the bubbles are expanded as well as the bounds of the dismiss target. */ int getMaxExpandedHeight() { - boolean showOnTop = BubbleController.showBubblesAtTop(getContext()); int expandedY = (int) mExpandedAnimationController.getExpandedY(); - if (showOnTop) { - // PIP dismiss view uses FLAG_LAYOUT_IN_SCREEN so we need to subtract the bottom inset - int pipDismissHeight = mPipDismissHeight - getBottomInset(); - return mDisplaySize.y - expandedY - mBubbleSize - pipDismissHeight; - } else { - return expandedY - getStatusBarHeight(); - } + return expandedY - getStatusBarHeight(); } /** * Calculates the y position of the expanded view when it is expanded. */ float getYPositionForExpandedView() { - boolean showOnTop = BubbleController.showBubblesAtTop(getContext()); - if (showOnTop) { - return getStatusBarHeight() + mBubbleSize + mBubblePadding; - } else { - return mExpandedAnimationController.getExpandedY() - - mExpandedBubble.expandedView.getExpandedSize() - mBubblePadding; - } + return mExpandedAnimationController.getExpandedY() + - mExpandedBubble.expandedView.getExpandedSize() - mBubblePadding; } /** diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java index 84b86bf9b69f..2681b6d0c891 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java @@ -159,7 +159,7 @@ public class BubbleView extends FrameLayout { } } - private void updateViews() { + void updateViews() { if (mEntry == null) { return; } @@ -186,6 +186,13 @@ public class BubbleView extends FrameLayout { } private Drawable buildIconWithTint(Drawable iconDrawable, int backgroundColor) { + iconDrawable = checkTint(iconDrawable, backgroundColor); + InsetDrawable foreground = new InsetDrawable(iconDrawable, mIconInset); + ColorDrawable background = new ColorDrawable(backgroundColor); + return new AdaptiveIconDrawable(background, foreground); + } + + private Drawable checkTint(Drawable iconDrawable, int backgroundColor) { backgroundColor = ColorUtils.setAlphaComponent(backgroundColor, 255 /* alpha */); if (backgroundColor == Color.TRANSPARENT) { // ColorUtils throws exception when background is translucent. @@ -197,9 +204,7 @@ public class BubbleView extends FrameLayout { int dark = ColorUtils.setAlphaComponent(Color.BLACK, DARK_ICON_ALPHA); iconDrawable.setTint(dark); } - InsetDrawable foreground = new InsetDrawable(iconDrawable, mIconInset); - ColorDrawable background = new ColorDrawable(backgroundColor); - return new AdaptiveIconDrawable(background, foreground); + return iconDrawable; } private int determineDominateColor(Drawable d, int defaultTint) { diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java index d601e633137d..95fbfe33ee71 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java @@ -26,7 +26,6 @@ import androidx.dynamicanimation.animation.DynamicAnimation; import androidx.dynamicanimation.animation.SpringForce; import com.android.systemui.R; -import com.android.systemui.bubbles.BubbleController; import com.google.android.collect.Sets; @@ -222,23 +221,14 @@ public class ExpandedAnimationController if (mLayout == null || mLayout.getRootWindowInsets() == null) { return 0; } - final boolean showOnTop = BubbleController.showBubblesAtTop(mLayout.getContext()); final WindowInsets insets = mLayout.getRootWindowInsets(); - if (showOnTop) { - return mBubblePaddingPx + Math.max( - mStatusBarHeight, - insets.getDisplayCutout() != null - ? insets.getDisplayCutout().getSafeInsetTop() - : 0); - } else { - int keyboardHeight = insets.getSystemWindowInsetBottom() - - insets.getStableInsetBottom(); - float bottomInset = keyboardHeight > 0 - ? keyboardHeight - : (mPipDismissHeight - insets.getStableInsetBottom()); - // Stable insets are excluded from display size, so we must subtract it - return mDisplaySize.y - mBubbleSizePx - mBubblePaddingPx - bottomInset; - } + int keyboardHeight = insets.getSystemWindowInsetBottom() + - insets.getStableInsetBottom(); + float bottomInset = keyboardHeight > 0 + ? keyboardHeight + : (mPipDismissHeight - insets.getStableInsetBottom()); + // Stable insets are excluded from display size, so we must subtract it + return mDisplaySize.y - mBubbleSizePx - mBubblePaddingPx - bottomInset; } @Override diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java index 78c4fc17c655..b953f270f337 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java @@ -57,22 +57,24 @@ public class StackAnimationController extends /** * Values to use for the default {@link SpringForce} provided to the physics animation layout. */ - private static final float DEFAULT_STIFFNESS = 2500f; - private static final float DEFAULT_BOUNCINESS = 0.85f; + private static final int DEFAULT_STIFFNESS = 12000; + private static final int FLING_FOLLOW_STIFFNESS = 20000; + private static final float DEFAULT_BOUNCINESS = 0.9f; /** * Friction applied to fling animations. Since the stack must land on one of the sides of the * screen, we want less friction horizontally so that the stack has a better chance of making it * to the side without needing a spring. */ - private static final float FLING_FRICTION_X = 1.15f; - private static final float FLING_FRICTION_Y = 1.5f; + private static final float FLING_FRICTION_X = 2.2f; + private static final float FLING_FRICTION_Y = 2.2f; /** - * Damping ratio to use for the stack spring animation used to spring the stack to its final - * position after a fling. + * Values to use for the stack spring animation used to spring the stack to its final position + * after a fling. */ - private static final float SPRING_DAMPING_RATIO = 0.85f; + private static final int SPRING_AFTER_FLING_STIFFNESS = 750; + private static final float SPRING_AFTER_FLING_DAMPING_RATIO = 0.85f; /** * Minimum fling velocity required to trigger moving the stack from one side of the screen to @@ -108,6 +110,12 @@ public class StackAnimationController extends private HashMap<DynamicAnimation.ViewProperty, DynamicAnimation> mStackPositionAnimations = new HashMap<>(); + /** + * Whether the current motion of the stack is due to a fling animation (vs. being dragged + * manually). + */ + private boolean mIsMovingFromFlinging = false; + /** Horizontal offset of bubbles in the stack. */ private float mStackOffset; /** Diameter of the bubbles themselves. */ @@ -147,6 +155,10 @@ public class StackAnimationController extends moveFirstBubbleWithStackFollowing(DynamicAnimation.TRANSLATION_X, x); moveFirstBubbleWithStackFollowing(DynamicAnimation.TRANSLATION_Y, y); + + // This method is called when the stack is being dragged manually, so we're clearly no + // longer flinging. + mIsMovingFromFlinging = false; } /** @@ -202,8 +214,8 @@ public class StackAnimationController extends startXVelocity, FLING_FRICTION_X, new SpringForce() - .setStiffness(SpringForce.STIFFNESS_LOW) - .setDampingRatio(SPRING_DAMPING_RATIO), + .setStiffness(SPRING_AFTER_FLING_STIFFNESS) + .setDampingRatio(SPRING_AFTER_FLING_DAMPING_RATIO), destinationRelativeX); flingThenSpringFirstBubbleWithStackFollowing( @@ -211,8 +223,8 @@ public class StackAnimationController extends velY, FLING_FRICTION_Y, new SpringForce() - .setStiffness(SpringForce.STIFFNESS_LOW) - .setDampingRatio(SPRING_DAMPING_RATIO), + .setStiffness(SPRING_AFTER_FLING_STIFFNESS) + .setDampingRatio(SPRING_AFTER_FLING_DAMPING_RATIO), /* destination */ null); mLayout.setEndActionForMultipleProperties( @@ -223,6 +235,8 @@ public class StackAnimationController extends mLayout.removeEndActionForProperty(DynamicAnimation.TRANSLATION_Y); }, DynamicAnimation.TRANSLATION_X, DynamicAnimation.TRANSLATION_Y); + + mIsMovingFromFlinging = true; } /** @@ -432,7 +446,8 @@ public class StackAnimationController extends .setDampingRatio(BubbleController.getBubbleBounciness( mLayout.getContext(), DEFAULT_BOUNCINESS)) .setStiffness(BubbleController.getBubbleStiffness( - mLayout.getContext(), (int) DEFAULT_STIFFNESS)); + mLayout.getContext(), + mIsMovingFromFlinging ? FLING_FOLLOW_STIFFNESS : DEFAULT_STIFFNESS)); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java index 4e41108f6496..25d6d940d92e 100644 --- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java +++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java @@ -341,8 +341,9 @@ public class PowerUI extends SystemUI { // mark if we've already shown a warning this cycle. This will prevent the notification // trigger from spamming users by only showing low/critical warnings once per cycle if (currentSnapshot.getTimeRemainingMillis() - <= currentSnapshot.getSevereLevelThreshold() - || currentSnapshot.getBatteryLevel() <= mLowBatteryReminderLevels[1]) { + <= currentSnapshot.getSevereThresholdMillis() + || currentSnapshot.getBatteryLevel() + <= currentSnapshot.getSevereLevelThreshold()) { mSevereWarningShownThisChargeCycle = true; mLowWarningShownThisChargeCycle = true; if (DEBUG) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java index 3e40cfc0cda2..15df1f161159 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java @@ -200,7 +200,7 @@ public class WifiTile extends QSTileImpl<SignalState> { state.icon = ResourceIcon.get(R.drawable.ic_qs_wifi_disconnected); state.label = r.getString(R.string.quick_settings_wifi_label); } else { - state.icon = ResourceIcon.get(R.drawable.ic_qs_wifi_no_network); + state.icon = ResourceIcon.get(WifiIcons.QS_WIFI_NO_NETWORK); state.label = r.getString(R.string.quick_settings_wifi_label); } minimalContentDescription.append( @@ -415,14 +415,14 @@ public class WifiTile extends QSTileImpl<SignalState> { // Wi-Fi is off if (!mSignalCallback.mInfo.enabled) { - mItems.setEmptyState(R.drawable.ic_qs_wifi_detail_empty, + mItems.setEmptyState(WifiIcons.QS_WIFI_NO_NETWORK, R.string.wifi_is_off); mItems.setItems(null); return; } // No available access points - mItems.setEmptyState(R.drawable.ic_qs_wifi_detail_empty, + mItems.setEmptyState(WifiIcons.QS_WIFI_NO_NETWORK, R.string.quick_settings_wifi_detail_empty_text); // Build the list diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NeutralGoodDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/NeutralGoodDrawable.java deleted file mode 100644 index 8642ca4c7d33..000000000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NeutralGoodDrawable.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2017 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.systemui.statusbar; - -import android.content.Context; -import android.graphics.drawable.Drawable; -import android.graphics.drawable.LayerDrawable; -import android.view.ContextThemeWrapper; -import android.view.Gravity; - -import com.android.settingslib.Utils; -import com.android.systemui.R; - -/** - * NeutralGoodDrawable implements a drawable that will load 2 underlying drawable resources, one - * with each the DualToneDarkTheme and DualToneLightTheme, choosing which one based on what - * DarkIconDispatcher tells us about darkness - */ -public class NeutralGoodDrawable extends LayerDrawable { - - public static NeutralGoodDrawable create(Context context, int resId) { - int dualToneLightTheme = Utils.getThemeAttr(context, R.attr.lightIconTheme); - int dualToneDarkTheme = Utils.getThemeAttr(context, R.attr.darkIconTheme); - ContextThemeWrapper light = new ContextThemeWrapper(context, dualToneLightTheme); - ContextThemeWrapper dark = new ContextThemeWrapper(context, dualToneDarkTheme); - - return create(light, dark, resId); - } - - /** - * For the on-the-go young entrepreneurial who wants to cache contexts - * @param light - a context using the R.attr.lightIconTheme - * @param dark - a context using the R.attr.darkIconTheme - * @param resId - the resId for our drawable - */ - public static NeutralGoodDrawable create(Context light, Context dark, int resId) { - return new NeutralGoodDrawable( - new Drawable[] { - light.getDrawable(resId).mutate(), - dark.getDrawable(resId).mutate() }); - } - - protected NeutralGoodDrawable(Drawable []drawables) { - super(drawables); - - for (int i = 0; i < drawables.length; i++) { - setLayerGravity(i, Gravity.CENTER); - } - - mutate(); - setDarkIntensity(0); - } - - public void setDarkIntensity(float intensity) { - - getDrawable(0).setAlpha((int) ((1 - intensity) * 255f)); - getDrawable(1).setAlpha((int) (intensity * 255f)); - - invalidateSelf(); - } -} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java index c5751c300c01..351627980c08 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java @@ -25,9 +25,7 @@ import static com.android.systemui.statusbar.StatusBarIconView.STATE_ICON; import android.content.Context; import android.content.res.ColorStateList; import android.graphics.Rect; -import android.graphics.drawable.Drawable; import android.util.AttributeSet; -import android.view.ContextThemeWrapper; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; @@ -35,7 +33,6 @@ import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; -import com.android.settingslib.Utils; import com.android.systemui.R; import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState; @@ -59,12 +56,8 @@ public class StatusBarWifiView extends FrameLayout implements DarkReceiver, private View mAirplaneSpacer; private WifiIconState mState; private String mSlot; - private float mDarkIntensity = 0; private int mVisibleState = -1; - private ContextThemeWrapper mDarkContext; - private ContextThemeWrapper mLightContext; - public static StatusBarWifiView fromContext(Context context, String slot) { LayoutInflater inflater = LayoutInflater.from(context); StatusBarWifiView v = (StatusBarWifiView) inflater.inflate(R.layout.status_bar_wifi_group, null); @@ -160,11 +153,6 @@ public class StatusBarWifiView extends FrameLayout implements DarkReceiver, } private void init() { - int dualToneLightTheme = Utils.getThemeAttr(mContext, R.attr.lightIconTheme); - int dualToneDarkTheme = Utils.getThemeAttr(mContext, R.attr.darkIconTheme); - mLightContext = new ContextThemeWrapper(mContext, dualToneLightTheme); - mDarkContext = new ContextThemeWrapper(mContext, dualToneDarkTheme); - mWifiGroup = findViewById(R.id.wifi_group); mWifiIcon = findViewById(R.id.wifi_signal); mIn = findViewById(R.id.wifi_in); @@ -209,10 +197,7 @@ public class StatusBarWifiView extends FrameLayout implements DarkReceiver, private boolean updateState(WifiIconState state) { setContentDescription(state.contentDescription); if (mState.resId != state.resId && state.resId >= 0) { - NeutralGoodDrawable drawable = NeutralGoodDrawable - .create(mLightContext, mDarkContext, state.resId); - drawable.setDarkIntensity(mDarkIntensity); - mWifiIcon.setImageDrawable(drawable); + mWifiIcon.setImageDrawable(mContext.getDrawable(mState.resId)); } mIn.setVisibility(state.activityIn ? View.VISIBLE : View.GONE); @@ -237,10 +222,7 @@ public class StatusBarWifiView extends FrameLayout implements DarkReceiver, private void initViewState() { setContentDescription(mState.contentDescription); if (mState.resId >= 0) { - NeutralGoodDrawable drawable = NeutralGoodDrawable.create( - mLightContext, mDarkContext, mState.resId); - drawable.setDarkIntensity(mDarkIntensity); - mWifiIcon.setImageDrawable(drawable); + mWifiIcon.setImageDrawable(mContext.getDrawable(mState.resId)); } mIn.setVisibility(mState.activityIn ? View.VISIBLE : View.GONE); @@ -257,11 +239,8 @@ public class StatusBarWifiView extends FrameLayout implements DarkReceiver, if (!isInArea(area, this)) { return; } - mDarkIntensity = darkIntensity; - Drawable d = mWifiIcon.getDrawable(); - if (d instanceof NeutralGoodDrawable) { - ((NeutralGoodDrawable)d).setDarkIntensity(darkIntensity); - } + + mWifiIcon.setImageTintList(ColorStateList.valueOf(getTint(area, this, tint))); mIn.setImageTintList(ColorStateList.valueOf(getTint(area, this, tint))); mOut.setImageTintList(ColorStateList.valueOf(getTint(area, this, tint))); mDotView.setDecorColor(tint); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java index 99269cf17141..02ee2433d251 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java @@ -215,16 +215,13 @@ public class NotificationIconAreaController implements DarkReceiver, if (entry.isRowDismissed() && hideDismissed) { return false; } - if (hideRepliedMessages && entry.isLastMessageFromReply()) { return false; } - // showAmbient == show in shade but not shelf - if (!showAmbient && entry.shouldSuppressStatusBar()) { + if ((!showAmbient || mFullyDark) && entry.shouldSuppressStatusBar()) { return false; } - return true; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index e5defae1f159..b34e24eee7fe 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -81,7 +81,6 @@ import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; -import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.PowerManager; @@ -123,7 +122,7 @@ import com.android.internal.colorextraction.ColorExtractor; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.statusbar.IStatusBarService; -import com.android.internal.statusbar.StatusBarIcon; +import com.android.internal.statusbar.RegisterStatusBarResult; import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; @@ -690,17 +689,11 @@ public class StatusBar extends SystemUI implements DemoMode, mCommandQueue = getComponent(CommandQueue.class); mCommandQueue.addCallback(this); - int[] switches = new int[9]; - ArrayList<IBinder> binders = new ArrayList<>(); - ArrayList<String> iconSlots = new ArrayList<>(); - ArrayList<StatusBarIcon> icons = new ArrayList<>(); - Rect fullscreenStackBounds = new Rect(); - Rect dockedStackBounds = new Rect(); + RegisterStatusBarResult result = null; try { - mBarService.registerStatusBar(mCommandQueue, iconSlots, icons, switches, binders, - fullscreenStackBounds, dockedStackBounds); + result = mBarService.registerStatusBar(mCommandQueue); } catch (RemoteException ex) { - // If the system process isn't there we're doomed anyway. + ex.rethrowFromSystemServer(); } createAndAddWindows(); @@ -714,28 +707,29 @@ public class StatusBar extends SystemUI implements DemoMode, // Set up the initial notification state. This needs to happen before CommandQueue.disable() setUpPresenter(); - setSystemUiVisibility(mDisplayId, switches[1], switches[7], switches[8], 0xffffffff, - fullscreenStackBounds, dockedStackBounds); - topAppWindowChanged(mDisplayId, switches[2] != 0); + setSystemUiVisibility(mDisplayId, result.mSystemUiVisibility, + result.mFullscreenStackSysUiVisibility, result.mDockedStackSysUiVisibility, + 0xffffffff, result.mFullscreenStackBounds, result.mDockedStackBounds); + topAppWindowChanged(mDisplayId, result.mMenuVisible); // StatusBarManagerService has a back up of IME token and it's restored here. - setImeWindowStatus(mDisplayId, binders.get(0), switches[3], switches[4], switches[5] != 0); + setImeWindowStatus(mDisplayId, result.mImeToken, result.mImeWindowVis, + result.mImeBackDisposition, result.mShowImeSwitcher); // Set up the initial icon state - int N = iconSlots.size(); - for (int i=0; i < N; i++) { - mCommandQueue.setIcon(iconSlots.get(i), icons.get(i)); + int numIcons = result.mIcons.size(); + for (int i = 0; i < numIcons; i++) { + mCommandQueue.setIcon(result.mIcons.keyAt(i), result.mIcons.valueAt(i)); } if (DEBUG) { Log.d(TAG, String.format( "init: icons=%d disabled=0x%08x lights=0x%08x menu=0x%08x imeButton=0x%08x", - icons.size(), - switches[0], - switches[1], - switches[2], - switches[3] - )); + numIcons, + result.mDisabledFlags1, + result.mSystemUiVisibility, + result.mMenuVisible ? 1 : 0, + result.mImeWindowVis)); } IntentFilter internalFilter = new IntentFilter(); @@ -774,9 +768,10 @@ public class StatusBar extends SystemUI implements DemoMode, // set the initial view visibility Dependency.get(InitController.class).addPostInitTask(this::updateAreThereNotifications); - Dependency.get(InitController.class).addPostInitTask(() -> { - setUpDisableFlags(switches[0], switches[6]); - }); + int disabledFlags1 = result.mDisabledFlags1; + int disabledFlags2 = result.mDisabledFlags2; + Dependency.get(InitController.class).addPostInitTask( + () -> setUpDisableFlags(disabledFlags1, disabledFlags2)); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiIcons.java index f629863c53a9..9db109de369b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiIcons.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiIcons.java @@ -19,18 +19,6 @@ package com.android.systemui.statusbar.policy; import com.android.systemui.R; public class WifiIcons { - static final int[][] WIFI_SIGNAL_STRENGTH = { - { R.drawable.stat_sys_wifi_signal_0, - R.drawable.stat_sys_wifi_signal_1, - R.drawable.stat_sys_wifi_signal_2, - R.drawable.stat_sys_wifi_signal_3, - R.drawable.stat_sys_wifi_signal_4 }, - { R.drawable.stat_sys_wifi_signal_0_fully, - R.drawable.stat_sys_wifi_signal_1_fully, - R.drawable.stat_sys_wifi_signal_2_fully, - R.drawable.stat_sys_wifi_signal_3_fully, - R.drawable.stat_sys_wifi_signal_4_fully } - }; static final int[] WIFI_FULL_ICONS = { com.android.internal.R.drawable.ic_wifi_signal_0, @@ -40,18 +28,23 @@ public class WifiIcons { com.android.internal.R.drawable.ic_wifi_signal_4 }; + private static final int[] WIFI_NO_INTERNET_ICONS = { + R.drawable.ic_qs_wifi_0, + R.drawable.ic_qs_wifi_1, + R.drawable.ic_qs_wifi_2, + R.drawable.ic_qs_wifi_3, + R.drawable.ic_qs_wifi_4 + }; + public static final int[][] QS_WIFI_SIGNAL_STRENGTH = { - { R.drawable.ic_qs_wifi_0, - R.drawable.ic_qs_wifi_1, - R.drawable.ic_qs_wifi_2, - R.drawable.ic_qs_wifi_3, - R.drawable.ic_qs_wifi_4 }, + WIFI_NO_INTERNET_ICONS, WIFI_FULL_ICONS - }; + }; + static final int[][] WIFI_SIGNAL_STRENGTH = QS_WIFI_SIGNAL_STRENGTH; public static final int QS_WIFI_DISABLED = com.android.internal.R.drawable.ic_wifi_signal_0; - static final int QS_WIFI_NO_NETWORK = R.drawable.ic_qs_wifi_no_network; - static final int WIFI_NO_NETWORK = R.drawable.stat_sys_wifi_signal_null; + public static final int QS_WIFI_NO_NETWORK = com.android.internal.R.drawable.ic_wifi_signal_0; + static final int WIFI_NO_NETWORK = QS_WIFI_NO_NETWORK; static final int WIFI_LEVEL_COUNT = WIFI_SIGNAL_STRENGTH[0].length; } 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 4a69cd783a6c..17d9cbe3af07 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java @@ -17,19 +17,14 @@ package com.android.systemui.statusbar.tv; import android.content.Context; -import android.graphics.Rect; -import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; import com.android.internal.statusbar.IStatusBarService; -import com.android.internal.statusbar.StatusBarIcon; import com.android.systemui.SystemUI; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.CommandQueue.Callbacks; -import java.util.ArrayList; - /** * Status bar implementation for "large screen" products that mostly present no on-screen nav */ @@ -43,17 +38,10 @@ public class TvStatusBar extends SystemUI implements Callbacks { putComponent(TvStatusBar.class, this); CommandQueue commandQueue = getComponent(CommandQueue.class); commandQueue.addCallback(this); - int[] switches = new int[9]; - ArrayList<IBinder> binders = new ArrayList<>(); - ArrayList<String> iconSlots = new ArrayList<>(); - ArrayList<StatusBarIcon> icons = new ArrayList<>(); - Rect fullscreenStackBounds = new Rect(); - Rect dockedStackBounds = new Rect(); mBarService = IStatusBarService.Stub.asInterface( ServiceManager.getService(Context.STATUS_BAR_SERVICE)); try { - mBarService.registerStatusBar(commandQueue, iconSlots, icons, switches, binders, - fullscreenStackBounds, dockedStackBounds); + mBarService.registerStatusBar(commandQueue); } catch (RemoteException ex) { // If the system process isn't there we're doomed anyway. } diff --git a/services/core/java/com/android/server/ExplicitHealthCheckController.java b/services/core/java/com/android/server/ExplicitHealthCheckController.java index 164837ab98dd..27ad208ef8a1 100644 --- a/services/core/java/com/android/server/ExplicitHealthCheckController.java +++ b/services/core/java/com/android/server/ExplicitHealthCheckController.java @@ -41,10 +41,14 @@ import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.Preconditions; +import java.util.Collection; import java.util.Collections; +import java.util.Iterator; import java.util.List; +import java.util.Set; import java.util.function.Consumer; +// TODO(b/120598832): Add tests /** * Controls the connections with {@link ExplicitHealthCheckService}. */ @@ -53,18 +57,30 @@ class ExplicitHealthCheckController { private final Object mLock = new Object(); private final Context mContext; - // Called everytime the service is connected, so the watchdog can sync it's state with - // the health check service. In practice, should never be null after it has been #setEnabled. - @GuardedBy("mLock") @Nullable private Runnable mOnConnected; // Called everytime a package passes the health check, so the watchdog is notified of the // passing check. In practice, should never be null after it has been #setEnabled. + // To prevent deadlocks between the controller and watchdog threads, we have + // a lock invariant to ALWAYS acquire the PackageWatchdog#mLock before #mLock in this class. + // It's easier to just NOT hold #mLock when calling into watchdog code on this consumer. @GuardedBy("mLock") @Nullable private Consumer<String> mPassedConsumer; + // Called everytime after a successful #syncRequest call, so the watchdog can receive packages + // supporting health checks and update its internal state. In practice, should never be null + // after it has been #setEnabled. + // To prevent deadlocks between the controller and watchdog threads, we have + // a lock invariant to ALWAYS acquire the PackageWatchdog#mLock before #mLock in this class. + // It's easier to just NOT hold #mLock when calling into watchdog code on this consumer. + @GuardedBy("mLock") @Nullable private Consumer<List<String>> mSupportedConsumer; + // Called everytime we need to notify the watchdog to sync requests between itself and the + // health check service. In practice, should never be null after it has been #setEnabled. + // To prevent deadlocks between the controller and watchdog threads, we have + // a lock invariant to ALWAYS acquire the PackageWatchdog#mLock before #mLock in this class. + // It's easier to just NOT hold #mLock when calling into watchdog code on this runnable. + @GuardedBy("mLock") @Nullable private Runnable mNotifySyncRunnable; // Actual binder object to the explicit health check service. @GuardedBy("mLock") @Nullable private IExplicitHealthCheckService mRemoteService; - // Cache for packages supporting explicit health checks. This cache should not change while - // the health check service is running. - @GuardedBy("mLock") @Nullable private List<String> mSupportedPackages; - // Connection to the explicit health check service, necessary to unbind + // Connection to the explicit health check service, necessary to unbind. + // We should only try to bind if mConnection is null, non-null indicates we + // are connected or at least connecting. @GuardedBy("mLock") @Nullable private ServiceConnection mConnection; // Bind state of the explicit health check service. @GuardedBy("mLock") private boolean mEnabled; @@ -73,23 +89,117 @@ class ExplicitHealthCheckController { mContext = context; } + /** Enables or disables explicit health checks. */ + public void setEnabled(boolean enabled) { + synchronized (mLock) { + Slog.i(TAG, "Explicit health checks " + (enabled ? "enabled." : "disabled.")); + mEnabled = enabled; + } + } + + /** + * Sets callbacks to listen to important events from the controller. + * + * <p> Should be called once at initialization before any other calls to the controller to + * ensure a happens-before relationship of the set parameters and visibility on other threads. + */ + public void setCallbacks(Consumer<String> passedConsumer, + Consumer<List<String>> supportedConsumer, Runnable notifySyncRunnable) { + synchronized (mLock) { + if (mPassedConsumer != null || mSupportedConsumer != null + || mNotifySyncRunnable != null) { + Slog.wtf(TAG, "Resetting health check controller callbacks"); + } + + mPassedConsumer = Preconditions.checkNotNull(passedConsumer); + mSupportedConsumer = Preconditions.checkNotNull(supportedConsumer); + mNotifySyncRunnable = Preconditions.checkNotNull(notifySyncRunnable); + } + } + + /** + * Calls the health check service to request or cancel packages based on + * {@code newRequestedPackages}. + * + * <p> Supported packages in {@code newRequestedPackages} that have not been previously + * requested will be requested while supported packages not in {@code newRequestedPackages} + * but were previously requested will be cancelled. + * + * <p> This handles binding and unbinding to the health check service as required. + * + * <p> Note, calling this may modify {@code newRequestedPackages}. + * + * <p> Note, this method is not thread safe, all calls should be serialized. + */ + public void syncRequests(Set<String> newRequestedPackages) { + boolean enabled; + synchronized (mLock) { + enabled = mEnabled; + } + + if (!enabled) { + Slog.i(TAG, "Health checks disabled, no supported packages"); + // Call outside lock + mSupportedConsumer.accept(Collections.emptyList()); + return; + } + + getSupportedPackages(supportedPackages -> { + // Notify the watchdog without lock held + mSupportedConsumer.accept(supportedPackages); + getRequestedPackages(previousRequestedPackages -> { + synchronized (mLock) { + // Hold lock so requests and cancellations are sent atomically. + // It is important we don't mix requests from multiple threads. + + // Note, this may modify newRequestedPackages + newRequestedPackages.retainAll(supportedPackages); + + // Cancel packages no longer requested + actOnDifference(previousRequestedPackages, + newRequestedPackages, p -> cancel(p)); + // Request packages not yet requested + actOnDifference(newRequestedPackages, + previousRequestedPackages, p -> request(p)); + + if (newRequestedPackages.isEmpty()) { + Slog.i(TAG, "No more health check requests, unbinding..."); + unbindService(); + return; + } + } + }); + }); + } + + private void actOnDifference(Collection<String> collection1, Collection<String> collection2, + Consumer<String> action) { + Iterator<String> iterator = collection1.iterator(); + while (iterator.hasNext()) { + String packageName = iterator.next(); + if (!collection2.contains(packageName)) { + action.accept(packageName); + } + } + } + /** * Requests an explicit health check for {@code packageName}. * After this request, the callback registered on {@link #setCallbacks} can receive explicit * health check passed results. - * - * @throws IllegalStateException if the service is not started */ - public void request(String packageName) throws RemoteException { + private void request(String packageName) { synchronized (mLock) { - if (!mEnabled) { + if (!prepareServiceLocked("request health check for " + packageName)) { return; } - enforceServiceReadyLocked(); - Slog.i(TAG, "Requesting health check for package " + packageName); - mRemoteService.request(packageName); + try { + mRemoteService.request(packageName); + } catch (RemoteException e) { + Slog.w(TAG, "Failed to request health check for package " + packageName, e); + } } } @@ -97,46 +207,46 @@ class ExplicitHealthCheckController { * Cancels all explicit health checks for {@code packageName}. * After this request, the callback registered on {@link #setCallbacks} can no longer receive * explicit health check passed results. - * - * @throws IllegalStateException if the service is not started */ - public void cancel(String packageName) throws RemoteException { + private void cancel(String packageName) { synchronized (mLock) { - if (!mEnabled) { + if (!prepareServiceLocked("cancel health check for " + packageName)) { return; } - enforceServiceReadyLocked(); - Slog.i(TAG, "Cancelling health check for package " + packageName); - mRemoteService.cancel(packageName); + try { + mRemoteService.cancel(packageName); + } catch (RemoteException e) { + // Do nothing, if the service is down, when it comes up, we will sync requests, + // if there's some other error, retrying wouldn't fix anyways. + Slog.w(TAG, "Failed to cancel health check for package " + packageName, e); + } } } /** * Returns the packages that we can request explicit health checks for. * The packages will be returned to the {@code consumer}. - * - * @throws IllegalStateException if the service is not started */ - public void getSupportedPackages(Consumer<List<String>> consumer) throws RemoteException { + private void getSupportedPackages(Consumer<List<String>> consumer) { synchronized (mLock) { - if (!mEnabled) { - consumer.accept(Collections.emptyList()); + if (!prepareServiceLocked("get health check supported packages")) { return; } - enforceServiceReadyLocked(); - - if (mSupportedPackages == null) { - Slog.d(TAG, "Getting health check supported packages"); + Slog.d(TAG, "Getting health check supported packages"); + try { mRemoteService.getSupportedPackages(new RemoteCallback(result -> { - mSupportedPackages = result.getStringArrayList(EXTRA_SUPPORTED_PACKAGES); - consumer.accept(mSupportedPackages); + List<String> packages = result.getStringArrayList(EXTRA_SUPPORTED_PACKAGES); + Slog.i(TAG, "Explicit health check supported packages " + packages); + consumer.accept(packages); })); - } else { - Slog.d(TAG, "Getting cached health check supported packages"); - consumer.accept(mSupportedPackages); + } catch (RemoteException e) { + // Request failed, treat as if all observed packages are supported, if any packages + // expire during this period, we may incorrectly treat it as failing health checks + // even if we don't support health checks for the package. + Slog.w(TAG, "Failed to get health check supported packages", e); } } } @@ -144,57 +254,42 @@ class ExplicitHealthCheckController { /** * Returns the packages for which health checks are currently in progress. * The packages will be returned to the {@code consumer}. - * - * @throws IllegalStateException if the service is not started */ - public void getRequestedPackages(Consumer<List<String>> consumer) throws RemoteException { + private void getRequestedPackages(Consumer<List<String>> consumer) { synchronized (mLock) { - if (!mEnabled) { - consumer.accept(Collections.emptyList()); + if (!prepareServiceLocked("get health check requested packages")) { return; } - enforceServiceReadyLocked(); - Slog.d(TAG, "Getting health check requested packages"); - mRemoteService.getRequestedPackages(new RemoteCallback( - result -> consumer.accept( - result.getStringArrayList(EXTRA_REQUESTED_PACKAGES)))); - } - } - - /** Enables or disables explicit health checks. */ - public void setEnabled(boolean enabled) { - synchronized (mLock) { - if (enabled == mEnabled) { - return; - } - - Slog.i(TAG, "Setting explicit health checks enabled " + enabled); - mEnabled = enabled; - if (enabled) { - bindService(); - } else { - unbindService(); + try { + mRemoteService.getRequestedPackages(new RemoteCallback(result -> { + List<String> packages = result.getStringArrayList(EXTRA_REQUESTED_PACKAGES); + Slog.i(TAG, "Explicit health check requested packages " + packages); + consumer.accept(packages); + })); + } catch (RemoteException e) { + // Request failed, treat as if we haven't requested any packages, if any packages + // were actually requested, they will not be cancelled now. May be cancelled later + Slog.w(TAG, "Failed to get health check requested packages", e); } } } /** - * Sets callbacks to listen to important events from the controller. - * Should be called at initialization. + * Binds to the explicit health check service if the controller is enabled and + * not already bound. */ - public void setCallbacks(Runnable onConnected, Consumer<String> passedConsumer) { - Preconditions.checkNotNull(onConnected); - Preconditions.checkNotNull(passedConsumer); - mOnConnected = onConnected; - mPassedConsumer = passedConsumer; - } - - /** Binds to the explicit health check service. */ private void bindService() { synchronized (mLock) { - if (mRemoteService != null) { + if (!mEnabled || mConnection != null || mRemoteService != null) { + if (!mEnabled) { + Slog.i(TAG, "Not binding to service, service disabled"); + } else if (mRemoteService != null) { + Slog.i(TAG, "Not binding to service, service already connected"); + } else { + Slog.i(TAG, "Not binding to service, service already connecting"); + } return; } ComponentName component = getServiceComponentNameLocked(); @@ -205,14 +300,11 @@ class ExplicitHealthCheckController { Intent intent = new Intent(); intent.setComponent(component); - // TODO: Fix potential race conditions during mConnection state transitions. - // E.g after #onServiceDisconected, the mRemoteService object is invalid until - // we get an #onServiceConnected. mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { - initState(service); Slog.i(TAG, "Explicit health check service is connected " + name); + initState(service); } @Override @@ -221,19 +313,18 @@ class ExplicitHealthCheckController { // Service crashed or process was killed, #onServiceConnected will be called. // Don't need to re-bind. Slog.i(TAG, "Explicit health check service is disconnected " + name); + synchronized (mLock) { + mRemoteService = null; + } } @Override public void onBindingDied(ComponentName name) { // Application hosting service probably got updated // Need to re-bind. - synchronized (mLock) { - if (mEnabled) { - unbindService(); - bindService(); - } - } - Slog.i(TAG, "Explicit health check service binding is dead " + name); + Slog.i(TAG, "Explicit health check service binding is dead. Rebind: " + name); + unbindService(); + bindService(); } @Override @@ -243,9 +334,9 @@ class ExplicitHealthCheckController { } }; - Slog.i(TAG, "Binding to explicit health service"); - mContext.bindServiceAsUser(intent, mConnection, Context.BIND_AUTO_CREATE, - UserHandle.of(UserHandle.USER_SYSTEM)); + mContext.bindServiceAsUser(intent, mConnection, + Context.BIND_AUTO_CREATE, UserHandle.of(UserHandle.USER_SYSTEM)); + Slog.i(TAG, "Explicit health check service is bound"); } } @@ -253,10 +344,11 @@ class ExplicitHealthCheckController { private void unbindService() { synchronized (mLock) { if (mRemoteService != null) { - Slog.i(TAG, "Unbinding from explicit health service"); mContext.unbindService(mConnection); mRemoteService = null; + mConnection = null; } + Slog.i(TAG, "Explicit health check service is unbound"); } } @@ -301,40 +393,54 @@ class ExplicitHealthCheckController { private void initState(IBinder service) { synchronized (mLock) { - mSupportedPackages = null; + if (!mEnabled) { + Slog.w(TAG, "Attempting to connect disabled service?? Unbinding..."); + // Very unlikely, but we disabled the service after binding but before we connected + unbindService(); + return; + } mRemoteService = IExplicitHealthCheckService.Stub.asInterface(service); try { mRemoteService.setCallback(new RemoteCallback(result -> { String packageName = result.getString(EXTRA_HEALTH_CHECK_PASSED_PACKAGE); if (!TextUtils.isEmpty(packageName)) { - synchronized (mLock) { - if (mPassedConsumer == null) { - Slog.w(TAG, "Health check passed for package " + packageName - + "but no consumer registered."); - } else { - mPassedConsumer.accept(packageName); - } + if (mPassedConsumer == null) { + Slog.wtf(TAG, "Health check passed for package " + packageName + + "but no consumer registered."); + } else { + // Call without lock held + mPassedConsumer.accept(packageName); } } else { - Slog.w(TAG, "Empty package passed explicit health check?"); + Slog.wtf(TAG, "Empty package passed explicit health check?"); } })); - if (mOnConnected == null) { - Slog.w(TAG, "Health check service connected but no runnable registered."); - } else { - mOnConnected.run(); - } + Slog.i(TAG, "Service initialized, syncing requests"); } catch (RemoteException e) { Slog.wtf(TAG, "Could not setCallback on explicit health check service"); } } + // Calling outside lock + mNotifySyncRunnable.run(); } + /** + * Prepares the health check service to receive requests. + * + * @return {@code true} if it is ready and we can proceed with a request, + * {@code false} otherwise. If it is not ready, and the service is enabled, + * we will bind and the request should be automatically attempted later. + */ @GuardedBy("mLock") - private void enforceServiceReadyLocked() { - if (mRemoteService == null) { - // TODO: Try to bind to service - throw new IllegalStateException("Explicit health check service not ready"); + private boolean prepareServiceLocked(String action) { + if (mRemoteService != null && mEnabled) { + return true; + } + Slog.i(TAG, "Service not ready to " + action + + (mEnabled ? ". Binding..." : ". Disabled")); + if (mEnabled) { + bindService(); } + return false; } } diff --git a/services/core/java/com/android/server/PackageWatchdog.java b/services/core/java/com/android/server/PackageWatchdog.java index 2ba4d975a6b0..feffe2f72b6f 100644 --- a/services/core/java/com/android/server/PackageWatchdog.java +++ b/services/core/java/com/android/server/PackageWatchdog.java @@ -26,7 +26,6 @@ import android.content.pm.VersionedPackage; import android.os.Environment; import android.os.Handler; import android.os.Looper; -import android.os.RemoteException; import android.os.SystemClock; import android.text.TextUtils; import android.util.ArrayMap; @@ -55,12 +54,10 @@ import java.io.InputStream; import java.lang.annotation.Retention; import java.nio.charset.StandardCharsets; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Set; -import java.util.function.Consumer; /** * Monitors the health of packages on the system and notifies interested observers when packages @@ -154,10 +151,11 @@ public class PackageWatchdog { public void onPackagesReady() { synchronized (mLock) { mIsPackagesReady = true; - mHealthCheckController.setCallbacks(this::updateHealthChecks, - packageName -> onHealthCheckPassed(packageName)); - // Controller is disabled at creation until here where we may enable it - mHealthCheckController.setEnabled(mIsHealthCheckEnabled); + mHealthCheckController.setCallbacks(packageName -> onHealthCheckPassed(packageName), + packages -> onSupportedPackages(packages), + () -> syncRequestsAsync()); + // Controller is initially disabled until here where we may enable it and sync requests + setExplicitHealthCheckEnabled(mIsHealthCheckEnabled); } } @@ -196,41 +194,23 @@ public class PackageWatchdog { * @throws IllegalArgumentException if {@code packageNames} is empty * or {@code durationMs} is less than 1 */ - public void startObservingHealth(PackageHealthObserver observer, List<String> packages, + public void startObservingHealth(PackageHealthObserver observer, List<String> packageNames, long durationMs) { - if (packages.isEmpty() || durationMs < 1) { - throw new IllegalArgumentException("Observation not started, no packages specified" - + "or invalid duration"); - } - if (!mIsPackagesReady) { - // TODO: Queue observation requests when packages are not ready - Slog.w(TAG, "Attempt to observe when packages not ready"); + if (packageNames.isEmpty()) { + Slog.wtf(TAG, "No packages to observe, " + observer.getName()); return; } - - try { - Slog.i(TAG, "Getting packages supporting explicit health check"); - mHealthCheckController.getSupportedPackages(supportedPackages -> - startObservingInner(observer, packages, durationMs, supportedPackages)); - } catch (RemoteException e) { - Slog.wtf(TAG, "Failed to fetch supported explicit health check packages"); + if (durationMs < 1) { + // TODO: Instead of failing, monitor for default? 48hrs? + throw new IllegalArgumentException("Invalid duration " + durationMs + "ms for observer " + + observer.getName() + ". Not observing packages " + packageNames); } - } - private void startObservingInner(PackageHealthObserver observer, - List<String> packageNames, long durationMs, - List<String> healthCheckSupportedPackages) { - Slog.i(TAG, "Start observing packages " + packageNames - + ". Explicit health check supported packages " + healthCheckSupportedPackages); List<MonitoredPackage> packages = new ArrayList<>(); for (int i = 0; i < packageNames.size(); i++) { - String packageName = packageNames.get(i); - boolean shouldEnableHealthCheck = healthCheckSupportedPackages.contains(packageName); - // If we should enable explicit health check for a package, - // MonitoredPackage#mHasHealthCheckPassed will be false - // until PackageWatchdog#onHealthCheckPassed - packages.add(new MonitoredPackage(packageName, durationMs, !shouldEnableHealthCheck)); + packages.add(new MonitoredPackage(packageNames.get(i), durationMs, false)); } + synchronized (mLock) { ObserverInternal oldObserver = mAllObservers.get(observer.getName()); if (oldObserver == null) { @@ -248,97 +228,11 @@ public class PackageWatchdog { // Always reschedule because we may need to expire packages // earlier than we are already scheduled for rescheduleCleanup(); - updateHealthChecks(); + Slog.i(TAG, "Syncing health check requests, observing packages " + packageNames); + syncRequestsAsync(); saveToFileAsync(); } - private void requestCheck(String packageName) { - try { - Slog.d(TAG, "Requesting explicit health check for " + packageName); - mHealthCheckController.request(packageName); - } catch (RemoteException e) { - Slog.wtf(TAG, "Failed to request explicit health check for " + packageName, e); - } - } - - private void cancelCheck(String packageName) { - try { - Slog.d(TAG, "Cancelling explicit health check for " + packageName); - mHealthCheckController.cancel(packageName); - } catch (RemoteException e) { - Slog.wtf(TAG, "Failed to cancel explicit health check for " + packageName, e); - } - } - - private void actOnDifference(Collection<String> collection1, Collection<String> collection2, - Consumer<String> action) { - Iterator<String> iterator = collection1.iterator(); - while (iterator.hasNext()) { - String packageName = iterator.next(); - if (!collection2.contains(packageName)) { - action.accept(packageName); - } - } - } - - private void updateChecksInner(List<String> supportedPackages, - List<String> previousRequestedPackages) { - boolean shouldUpdateFile = false; - - synchronized (mLock) { - Slog.i(TAG, "Updating explicit health checks. Supported packages: " + supportedPackages - + ". Requested packages: " + previousRequestedPackages); - Set<String> newRequestedPackages = new ArraySet<>(); - Iterator<ObserverInternal> oit = mAllObservers.values().iterator(); - while (oit.hasNext()) { - ObserverInternal observer = oit.next(); - Iterator<MonitoredPackage> pit = - observer.mPackages.values().iterator(); - while (pit.hasNext()) { - MonitoredPackage monitoredPackage = pit.next(); - String packageName = monitoredPackage.mName; - if (!monitoredPackage.mHasPassedHealthCheck) { - if (supportedPackages.contains(packageName)) { - newRequestedPackages.add(packageName); - } else { - shouldUpdateFile = true; - monitoredPackage.mHasPassedHealthCheck = true; - } - } - } - } - // TODO: Support ending the binding if newRequestedPackages is empty. - // Will have to re-bind when we #startObservingHealth. - - // Cancel packages no longer requested - actOnDifference(previousRequestedPackages, newRequestedPackages, p -> cancelCheck(p)); - // Request packages not yet requested - actOnDifference(newRequestedPackages, previousRequestedPackages, p -> requestCheck(p)); - } - - if (shouldUpdateFile) { - saveToFileAsync(); - } - } - - private void updateHealthChecks() { - mShortTaskHandler.post(() -> { - try { - Slog.i(TAG, "Updating explicit health checks for all available packages"); - mHealthCheckController.getSupportedPackages(supported -> { - try { - mHealthCheckController.getRequestedPackages( - requested -> updateChecksInner(supported, requested)); - } catch (RemoteException e) { - Slog.e(TAG, "Failed to get requested health check packages", e); - } - }); - } catch (RemoteException e) { - Slog.e(TAG, "Failed to get supported health check package", e); - } - }); - } - /** * Unregisters {@code observer} from listening to package failure. * Additionally, this stops observing any packages that may have previously been observed @@ -441,6 +335,9 @@ public class PackageWatchdog { synchronized (mLock) { mIsHealthCheckEnabled = enabled; mHealthCheckController.setEnabled(enabled); + Slog.i(TAG, "Syncing health check requests, explicit health check is " + + (enabled ? "enabled" : "disabled")); + syncRequestsAsync(); } } @@ -487,6 +384,35 @@ public class PackageWatchdog { } /** + * Serializes and syncs health check requests with the {@link ExplicitHealthCheckController}. + */ + private void syncRequestsAsync() { + if (!mShortTaskHandler.hasCallbacks(this::syncRequests)) { + mShortTaskHandler.post(this::syncRequests); + } + } + + /** + * Syncs health check requests with the {@link ExplicitHealthCheckController}. + * Calls to this must be serialized. + * + * @see #syncRequestsAsync + */ + private void syncRequests() { + Set<String> packages = null; + synchronized (mLock) { + if (mIsPackagesReady) { + packages = getPackagesPendingHealthChecksLocked(); + } // else, we will sync requests when packages become ready + } + + // Call outside lock to avoid holding lock when calling into the controller. + if (packages != null) { + mHealthCheckController.syncRequests(packages); + } + } + + /** * Updates the observers monitoring {@code packageName} that explicit health check has passed. * * <p> This update is strictly for registered observers at the time of the call @@ -512,11 +438,64 @@ public class PackageWatchdog { } } } + + // So we can unbind from the service if this was the last result we expected + Slog.i(TAG, "Syncing health check requests, health check passed for " + packageName); + syncRequestsAsync(); + + if (shouldUpdateFile) { + saveToFileAsync(); + } + } + + private void onSupportedPackages(List<String> supportedPackages) { + boolean shouldUpdateFile = false; + + synchronized (mLock) { + Slog.i(TAG, "Received supported packages " + supportedPackages); + Iterator<ObserverInternal> oit = mAllObservers.values().iterator(); + while (oit.hasNext()) { + ObserverInternal observer = oit.next(); + Iterator<MonitoredPackage> pit = + observer.mPackages.values().iterator(); + while (pit.hasNext()) { + MonitoredPackage monitoredPackage = pit.next(); + String packageName = monitoredPackage.mName; + if (!monitoredPackage.mHasPassedHealthCheck + && !supportedPackages.contains(packageName)) { + // Hasn't passed health check but health check is not supported + Slog.i(TAG, packageName + " does not support health checks, passing"); + shouldUpdateFile = true; + monitoredPackage.mHasPassedHealthCheck = true; + } + } + } + } + if (shouldUpdateFile) { saveToFileAsync(); } } + private Set<String> getPackagesPendingHealthChecksLocked() { + Slog.d(TAG, "Getting all observed packages pending health checks"); + Set<String> packages = new ArraySet<>(); + Iterator<ObserverInternal> oit = mAllObservers.values().iterator(); + while (oit.hasNext()) { + ObserverInternal observer = oit.next(); + Iterator<MonitoredPackage> pit = + observer.mPackages.values().iterator(); + while (pit.hasNext()) { + MonitoredPackage monitoredPackage = pit.next(); + String packageName = monitoredPackage.mName; + if (!monitoredPackage.mHasPassedHealthCheck) { + packages.add(packageName); + } + } + } + return packages; + } + /** Reschedules handler to prune expired packages from observers. */ private void rescheduleCleanup() { synchronized (mLock) { @@ -591,7 +570,8 @@ public class PackageWatchdog { } } } - updateHealthChecks(); + Slog.i(TAG, "Syncing health check requests pruned packages"); + syncRequestsAsync(); saveToFileAsync(); } @@ -690,6 +670,7 @@ public class PackageWatchdog { } private void saveToFileAsync() { + // TODO(b/120598832): Use Handler#hasCallbacks instead of removing and posting mLongTaskHandler.removeCallbacks(this::saveToFile); mLongTaskHandler.post(this::saveToFile); } diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index 1c9931616630..c647e2ed824f 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -78,7 +78,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; -import java.util.OptionalInt; import java.util.stream.Collectors; /** @@ -248,6 +247,8 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { private final LocalLog mLocalLog = new LocalLog(100); + private final LocalLog mListenLog = new LocalLog(100); + private PreciseDataConnectionState mPreciseDataConnectionState = new PreciseDataConnectionState(); @@ -305,6 +306,8 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } mDefaultSubId = newDefaultSubId; mDefaultPhoneId = newDefaultPhoneId; + mLocalLog.log("Default subscription updated: mDefaultPhoneId=" + + mDefaultPhoneId + ", mDefaultSubId" + mDefaultSubId); } } } @@ -598,10 +601,12 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { boolean notifyNow, int subId) { int callerUserId = UserHandle.getCallingUserId(); mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); - if (VDBG) { - log("listen: E pkg=" + callingPackage + " events=0x" + Integer.toHexString(events) + String str = "listen: E pkg=" + callingPackage + " events=0x" + Integer.toHexString(events) + " notifyNow=" + notifyNow + " subId=" + subId + " myUserId=" - + UserHandle.myUserId() + " callerUserId=" + callerUserId); + + UserHandle.myUserId() + " callerUserId=" + callerUserId; + mListenLog.log(str); + if (VDBG) { + log(str); } if (events != PhoneStateListener.LISTEN_NONE) { @@ -1410,8 +1415,10 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { if (PhoneConstants.APN_TYPE_DEFAULT.equals(apnType) && (mDataConnectionState[phoneId] != state || mDataConnectionNetworkType[phoneId] != networkType)) { - String str = "onDataConnectionStateChanged(" + state - + ", " + networkType + ")"; + String str = "onDataConnectionStateChanged(" + + TelephonyManager.dataStateToString(state) + + ", " + TelephonyManager.getNetworkTypeName(networkType) + + ") subId=" + subId + ", phoneId=" + phoneId; log(str); mLocalLog.log(str); for (Record r : mRecords) { @@ -1926,12 +1933,16 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { pw.println("mEmergencyNumberList=" + mEmergencyNumberList); pw.println("mCallQuality=" + mCallQuality); pw.println("mCallAttributes=" + mCallAttributes); + pw.println("mDefaultPhoneId" + mDefaultPhoneId); + pw.println("mDefaultSubId" + mDefaultSubId); pw.decreaseIndent(); pw.println("local logs:"); pw.increaseIndent(); mLocalLog.dump(fd, pw, args); + pw.println("listen logs:"); + mListenLog.dump(fd, pw, args); pw.decreaseIndent(); pw.println("registrations: count=" + recordCount); pw.increaseIndent(); diff --git a/services/core/java/com/android/server/am/AppCompactor.java b/services/core/java/com/android/server/am/AppCompactor.java index 043dc8d00081..13b55dbcad48 100644 --- a/services/core/java/com/android/server/am/AppCompactor.java +++ b/services/core/java/com/android/server/am/AppCompactor.java @@ -278,17 +278,15 @@ public final class AppCompactor { + " full, " + mPersistentCompactionCount + " persistent, " + mBfgsCompactionCount + " BFGS compactions."); - if (mLastCompactionStats != null) { - pw.println(" Tracking last compaction stats for " + mLastCompactionStats.size() - + " processes."); - if (DEBUG_COMPACTION) { - for (Map.Entry<Integer, LastCompactionStats> entry - : mLastCompactionStats.entrySet()) { - int pid = entry.getKey(); - LastCompactionStats stats = entry.getValue(); - pw.println(" " + pid + ": " - + Arrays.toString(stats.getRssAfterCompaction())); - } + pw.println(" Tracking last compaction stats for " + mLastCompactionStats.size() + + " processes."); + if (DEBUG_COMPACTION) { + for (Map.Entry<Integer, LastCompactionStats> entry + : mLastCompactionStats.entrySet()) { + int pid = entry.getKey(); + LastCompactionStats stats = entry.getValue(); + pw.println(" " + pid + ": " + + Arrays.toString(stats.getRssAfterCompaction())); } } } @@ -506,10 +504,6 @@ public final class AppCompactor { } } - @VisibleForTesting static String procStateListToString(Integer... processStates) { - return Arrays.toString(processStates); - } - private static final class LastCompactionStats { private final long[] mRssAfterCompaction; diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java index 516844d85484..843ecac14b62 100644 --- a/services/core/java/com/android/server/biometrics/BiometricService.java +++ b/services/core/java/com/android/server/biometrics/BiometricService.java @@ -19,7 +19,6 @@ package com.android.server.biometrics; import static android.Manifest.permission.USE_BIOMETRIC; import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL; import static android.Manifest.permission.USE_FINGERPRINT; -import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE; import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT; import static android.hardware.biometrics.BiometricAuthenticator.TYPE_IRIS; @@ -351,6 +350,11 @@ public class BiometricService extends SystemService { } private final class SettingObserver extends ContentObserver { + + private static final boolean DEFAULT_KEYGUARD_ENABLED = true; + private static final boolean DEFAULT_APP_ENABLED = true; + private static final boolean DEFAULT_ALWAYS_REQUIRE_CONFIRMATION = false; + private final Uri FACE_UNLOCK_KEYGUARD_ENABLED = Settings.Secure.getUriFor(Settings.Secure.FACE_UNLOCK_KEYGUARD_ENABLED); private final Uri FACE_UNLOCK_APP_ENABLED = @@ -359,9 +363,10 @@ public class BiometricService extends SystemService { Settings.Secure.getUriFor(Settings.Secure.FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION); private final ContentResolver mContentResolver; - private boolean mFaceEnabledOnKeyguard; - private boolean mFaceEnabledForApps; - private boolean mFaceAlwaysRequireConfirmation; + + private Map<Integer, Boolean> mFaceEnabledOnKeyguard = new HashMap<>(); + private Map<Integer, Boolean> mFaceEnabledForApps = new HashMap<>(); + private Map<Integer, Boolean> mFaceAlwaysRequireConfirmation = new HashMap<>(); /** * Creates a content observer. @@ -379,63 +384,65 @@ public class BiometricService extends SystemService { mContentResolver.registerContentObserver(FACE_UNLOCK_KEYGUARD_ENABLED, false /* notifyForDescendents */, this /* observer */, - UserHandle.USER_CURRENT); + UserHandle.USER_ALL); mContentResolver.registerContentObserver(FACE_UNLOCK_APP_ENABLED, false /* notifyForDescendents */, this /* observer */, - UserHandle.USER_CURRENT); + UserHandle.USER_ALL); mContentResolver.registerContentObserver(FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION, false /* notifyForDescendents */, this /* observer */, - UserHandle.USER_CURRENT); - - // Update the value immediately - onChange(true /* selfChange */, FACE_UNLOCK_KEYGUARD_ENABLED); - onChange(true /* selfChange */, FACE_UNLOCK_APP_ENABLED); - onChange(true /* selfChange */, FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION); + UserHandle.USER_ALL); } @Override - public void onChange(boolean selfChange, Uri uri) { + public void onChange(boolean selfChange, Uri uri, int userId) { if (FACE_UNLOCK_KEYGUARD_ENABLED.equals(uri)) { - mFaceEnabledOnKeyguard = - Settings.Secure.getIntForUser( + mFaceEnabledOnKeyguard.put(userId, Settings.Secure.getIntForUser( mContentResolver, Settings.Secure.FACE_UNLOCK_KEYGUARD_ENABLED, - 1 /* default */, - UserHandle.USER_CURRENT) != 0; + DEFAULT_KEYGUARD_ENABLED ? 1 : 0 /* default */, + userId) != 0); - List<EnabledOnKeyguardCallback> callbacks = mEnabledOnKeyguardCallbacks; - for (int i = 0; i < callbacks.size(); i++) { - callbacks.get(i).notify(BiometricSourceType.FACE, mFaceEnabledOnKeyguard); + if (userId == ActivityManager.getCurrentUser()) { + notifyEnabledOnKeyguardCallbacks(userId); } } else if (FACE_UNLOCK_APP_ENABLED.equals(uri)) { - mFaceEnabledForApps = - Settings.Secure.getIntForUser( + mFaceEnabledForApps.put(userId, Settings.Secure.getIntForUser( mContentResolver, Settings.Secure.FACE_UNLOCK_APP_ENABLED, - 1 /* default */, - UserHandle.USER_CURRENT) != 0; + DEFAULT_APP_ENABLED ? 1 : 0 /* default */, + userId) != 0); } else if (FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION.equals(uri)) { - mFaceAlwaysRequireConfirmation = - Settings.Secure.getIntForUser( + mFaceAlwaysRequireConfirmation.put(userId, Settings.Secure.getIntForUser( mContentResolver, Settings.Secure.FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION, - 0 /* default */, - UserHandle.USER_CURRENT) != 0; + DEFAULT_ALWAYS_REQUIRE_CONFIRMATION ? 1 : 0 /* default */, + userId) != 0); } } boolean getFaceEnabledOnKeyguard() { - return mFaceEnabledOnKeyguard; + return mFaceEnabledOnKeyguard.getOrDefault( + ActivityManager.getCurrentUser(), DEFAULT_KEYGUARD_ENABLED); } - boolean getFaceEnabledForApps() { - return mFaceEnabledForApps; + boolean getFaceEnabledForApps(int userId) { + return mFaceEnabledForApps.getOrDefault(userId, DEFAULT_APP_ENABLED); } - boolean getFaceAlwaysRequireConfirmation() { - return mFaceAlwaysRequireConfirmation; + boolean getFaceAlwaysRequireConfirmation(int userId) { + return mFaceAlwaysRequireConfirmation + .getOrDefault(userId, DEFAULT_ALWAYS_REQUIRE_CONFIRMATION); + } + + void notifyEnabledOnKeyguardCallbacks(int userId) { + List<EnabledOnKeyguardCallback> callbacks = mEnabledOnKeyguardCallbacks; + for (int i = 0; i < callbacks.size(); i++) { + callbacks.get(i).notify(BiometricSourceType.FACE, + mFaceEnabledOnKeyguard.getOrDefault(userId, + DEFAULT_KEYGUARD_ENABLED)); + } } } @@ -576,30 +583,9 @@ public class BiometricService extends SystemService { if (useDefaultTitle) { checkInternalPermission(); // Set the default title if necessary - try { - final List<ActivityManager.RunningAppProcessInfo> procs = - ActivityManager.getService().getRunningAppProcesses(); - for (int i = 0; i < procs.size(); i++) { - final ActivityManager.RunningAppProcessInfo info = procs.get(i); - if (info.uid == callingUid - && info.importance == IMPORTANCE_FOREGROUND) { - PackageManager pm = getContext().getPackageManager(); - final CharSequence label = pm.getApplicationLabel( - pm.getApplicationInfo(info.processName, - PackageManager.GET_META_DATA)); - final String title = getContext() - .getString(R.string.biometric_dialog_default_title, label); - if (TextUtils.isEmpty( - bundle.getCharSequence(BiometricPrompt.KEY_TITLE))) { - bundle.putCharSequence(BiometricPrompt.KEY_TITLE, title); - } - break; - } - } - } catch (RemoteException e) { - Slog.e(TAG, "Remote exception", e); - } catch (PackageManager.NameNotFoundException e) { - Slog.e(TAG, "Name not found", e); + if (TextUtils.isEmpty(bundle.getCharSequence(BiometricPrompt.KEY_TITLE))) { + bundle.putCharSequence(BiometricPrompt.KEY_TITLE, + getContext().getString(R.string.biometric_dialog_default_title)); } } @@ -625,7 +611,7 @@ public class BiometricService extends SystemService { mConfirmDeviceCredentialReceiver = receiver; // Use this so we don't need to duplicate logic.. final Intent intent = kgm.createConfirmDeviceCredentialIntent(null /* title */, - null /* description */); + null /* description */, userId); // Then give it the bundle to do magic behavior.. intent.putExtra(KeyguardManager.EXTRA_BIOMETRIC_PROMPT_BUNDLE, bundle); // Create a new task with this activity located at the root. @@ -805,6 +791,7 @@ public class BiometricService extends SystemService { @Override public void onUserSwitchComplete(int newUserId) { mSettingObserver.updateContentObserver(); + mSettingObserver.notifyEnabledOnKeyguardCallbacks(newUserId); } }, BiometricService.class.getName() ); @@ -884,7 +871,7 @@ public class BiometricService extends SystemService { } if (authenticator.hasEnrolledTemplates(userId)) { hasTemplatesEnrolled = true; - if (isEnabledForApp(modality)) { + if (isEnabledForApp(modality, userId)) { // TODO(b/110907543): When face settings (and other settings) have both a // user toggle as well as a work profile settings page, this needs to be // updated to reflect the correct setting. @@ -909,14 +896,14 @@ public class BiometricService extends SystemService { return new Pair<>(modality, BiometricConstants.BIOMETRIC_SUCCESS); } - private boolean isEnabledForApp(int modality) { + private boolean isEnabledForApp(int modality, int userId) { switch(modality) { case TYPE_FINGERPRINT: return true; case TYPE_IRIS: return true; case TYPE_FACE: - return mSettingObserver.getFaceEnabledForApps(); + return mSettingObserver.getFaceEnabledForApps(userId); default: Slog.w(TAG, "Unsupported modality: " + modality); return false; @@ -1363,7 +1350,7 @@ public class BiometricService extends SystemService { if ((modality & TYPE_FACE) != 0) { // Check if the user has forced confirmation to be required in Settings. requireConfirmation = requireConfirmation - || mSettingObserver.getFaceAlwaysRequireConfirmation(); + || mSettingObserver.getFaceAlwaysRequireConfirmation(userId); } // Generate random cookies to pass to the services that should prepare to start // authenticating. Store the cookie here and wait for all services to "ack" diff --git a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java index d8e7b7db7b75..18c2edc086dc 100644 --- a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java +++ b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java @@ -903,9 +903,8 @@ public abstract class BiometricServiceBase extends SystemService } protected void setActiveUserInternal(int userId) { - mHandler.post(() -> { - updateActiveGroup(userId, null /* clientPackage */); - }); + // Do not put on handler, since it should finish before returning to caller. + updateActiveGroup(userId, null /* clientPackage */); } protected void removeInternal(RemovalClient client) { @@ -1045,10 +1044,15 @@ public abstract class BiometricServiceBase extends SystemService } } else { currentClient.stop(initiatedByClient); + + // Only post the reset runnable for non-cleanup clients. Cleanup clients should + // never be forcibly stopped since they ensure synchronization between HAL and + // framework. Thus, we should instead just start the pending client once cleanup + // finishes instead of using the reset runnable. + mHandler.removeCallbacks(mResetClientState); + mHandler.postDelayed(mResetClientState, CANCEL_TIMEOUT_LIMIT); } mPendingClient = newClient; - mHandler.removeCallbacks(mResetClientState); - mHandler.postDelayed(mResetClientState, CANCEL_TIMEOUT_LIMIT); } else if (newClient != null) { // For BiometricPrompt clients, do not start until // <Biometric>Service#startPreparedClient is called. BiometricService waits until all @@ -1225,6 +1229,7 @@ public abstract class BiometricServiceBase extends SystemService } else { clearEnumerateState(); if (mPendingClient != null) { + Slog.d(getTag(), "Enumerate finished, starting pending client"); startClient(mPendingClient, false /* initiatedByClient */); } } diff --git a/services/core/java/com/android/server/biometrics/face/FaceService.java b/services/core/java/com/android/server/biometrics/face/FaceService.java index c573bbb2e1f0..d67853ab0d1b 100644 --- a/services/core/java/com/android/server/biometrics/face/FaceService.java +++ b/services/core/java/com/android/server/biometrics/face/FaceService.java @@ -165,7 +165,7 @@ public class FaceService extends BiometricServiceBase { } }; - enrollInternal(client, UserHandle.getCallingUserId()); + enrollInternal(client, mCurrentUserId); } @Override // Binder call @@ -813,7 +813,7 @@ public class FaceService extends BiometricServiceBase { com.android.internal.R.integer.config_faceMaxTemplatesPerUser); final int enrolled = FaceService.this.getEnrolledTemplates(userId).size(); if (enrolled >= limit) { - Slog.w(TAG, "Too many faces registered"); + Slog.w(TAG, "Too many faces registered, user: " + userId); return true; } return false; diff --git a/services/core/java/com/android/server/location/GnssCapabilitiesProvider.java b/services/core/java/com/android/server/location/GnssCapabilitiesProvider.java index 98085b8e219b..b4b6160fadbe 100644 --- a/services/core/java/com/android/server/location/GnssCapabilitiesProvider.java +++ b/services/core/java/com/android/server/location/GnssCapabilitiesProvider.java @@ -75,9 +75,7 @@ public class GnssCapabilitiesProvider { /** * Updates the general capabilities exposed through {@link android.location.GnssCapabilities}. */ - void setTopHalCapabilities(int topHalCapabilities, - boolean hasGeofencingCapability, boolean hasMeasurementsCapability, - boolean hasNavMessagesCapability) { + void setTopHalCapabilities(int topHalCapabilities) { long gnssCapabilities = 0; if (hasCapability(topHalCapabilities, GnssLocationProvider.GPS_CAPABILITY_LOW_POWER_MODE)) { @@ -87,13 +85,13 @@ public class GnssCapabilitiesProvider { GnssLocationProvider.GPS_CAPABILITY_SATELLITE_BLACKLIST)) { gnssCapabilities |= GNSS_CAPABILITY_SATELLITE_BLACKLIST; } - if (hasGeofencingCapability) { + if (hasCapability(topHalCapabilities, GnssLocationProvider.GPS_CAPABILITY_GEOFENCING)) { gnssCapabilities |= GNSS_CAPABILITY_GEOFENCING; } - if (hasMeasurementsCapability) { + if (hasCapability(topHalCapabilities, GnssLocationProvider.GPS_CAPABILITY_MEASUREMENTS)) { gnssCapabilities |= GNSS_CAPABILITY_MEASUREMENTS; } - if (hasNavMessagesCapability) { + if (hasCapability(topHalCapabilities, GnssLocationProvider.GPS_CAPABILITY_NAV_MESSAGES)) { gnssCapabilities |= GNSS_CAPABILITY_NAV_MESSAGES; } diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java index be34adb1fca4..4504b2e38e2b 100644 --- a/services/core/java/com/android/server/location/GnssLocationProvider.java +++ b/services/core/java/com/android/server/location/GnssLocationProvider.java @@ -166,15 +166,12 @@ public class GnssLocationProvider extends AbstractLocationProvider implements private static final int GPS_CAPABILITY_MSA = 0x0000004; private static final int GPS_CAPABILITY_SINGLE_SHOT = 0x0000008; private static final int GPS_CAPABILITY_ON_DEMAND_TIME = 0x0000010; - - // The following three capability flags are removed in IGnssCallback.hal@2.0 and their values - // are marked reserved and not reused in 2.0 to avoid confusion with prior versions. public static final int GPS_CAPABILITY_GEOFENCING = 0x0000020; public static final int GPS_CAPABILITY_MEASUREMENTS = 0x0000040; public static final int GPS_CAPABILITY_NAV_MESSAGES = 0x0000080; - - static final int GPS_CAPABILITY_LOW_POWER_MODE = 0x0000100; - static final int GPS_CAPABILITY_SATELLITE_BLACKLIST = 0x0000200; + public static final int GPS_CAPABILITY_LOW_POWER_MODE = 0x0000100; + public static final int GPS_CAPABILITY_SATELLITE_BLACKLIST = 0x0000200; + public static final int GPS_CAPABILITY_MEASUREMENT_CORRECTIONS = 0x0000400; // The AGPS SUPL mode private static final int AGPS_SUPL_MODE_MSA = 0x02; @@ -1490,12 +1487,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements } @NativeEntryPoint - private void setTopHalCapabilities(int topHalCapabilities, boolean hasSubHalCapabilityFlags) { - // The IGnssCallback.hal@2.0 removed sub-HAL capability flags from the Capabilities enum - // and instead uses the sub-HAL non-null handle returned from IGnss.hal@2.0 to indicate - // support. Therefore, the 'hasSubHalCapabilityFlags' parameter is needed to tell if the - // 'capabilities' parameter includes the sub-HAL capability flags or not. Old HALs - // which explicitly set the sub-HAL capability bits must continue to work. + private void setTopHalCapabilities(int topHalCapabilities) { mHandler.post(() -> { mTopHalCapabilities = topHalCapabilities; @@ -1504,25 +1496,13 @@ public class GnssLocationProvider extends AbstractLocationProvider implements requestUtcTime(); } - boolean hasGeofencingCapability; - boolean hasMeasurementsCapability; - boolean hasNavMessagesCapability; - if (hasSubHalCapabilityFlags) { - hasGeofencingCapability = hasCapability(GPS_CAPABILITY_GEOFENCING); - hasMeasurementsCapability = hasCapability(GPS_CAPABILITY_MEASUREMENTS); - hasNavMessagesCapability = hasCapability(GPS_CAPABILITY_NAV_MESSAGES); - } else { - hasGeofencingCapability = mGnssGeofenceProvider.isHardwareGeofenceSupported(); - hasMeasurementsCapability = mGnssMeasurementsProvider.isAvailableInPlatform(); - hasNavMessagesCapability = mGnssNavigationMessageProvider.isAvailableInPlatform(); - } - - mGnssMeasurementsProvider.onCapabilitiesUpdated(hasMeasurementsCapability); - mGnssNavigationMessageProvider.onCapabilitiesUpdated(hasNavMessagesCapability); + mGnssMeasurementsProvider.onCapabilitiesUpdated( + hasCapability(GPS_CAPABILITY_MEASUREMENTS)); + mGnssNavigationMessageProvider.onCapabilitiesUpdated( + hasCapability(GPS_CAPABILITY_NAV_MESSAGES)); restartRequests(); - mGnssCapabilitiesProvider.setTopHalCapabilities(topHalCapabilities, - hasGeofencingCapability, hasMeasurementsCapability, hasNavMessagesCapability); + mGnssCapabilitiesProvider.setTopHalCapabilities(mTopHalCapabilities); }); } @@ -2184,18 +2164,12 @@ public class GnssLocationProvider extends AbstractLocationProvider implements if (hasCapability(GPS_CAPABILITY_NAV_MESSAGES)) s.append("NAV_MESSAGES "); if (hasCapability(GPS_CAPABILITY_LOW_POWER_MODE)) s.append("LOW_POWER_MODE "); if (hasCapability(GPS_CAPABILITY_SATELLITE_BLACKLIST)) s.append("SATELLITE_BLACKLIST "); - s.append(")\n"); - if (mGnssGeofenceProvider.isHardwareGeofenceSupported()) { - s.append(" hasSubHal=GEOFENCING\n"); - } - if (mGnssMeasurementsProvider.isAvailableInPlatform()) { - s.append(" hasSubHal=MEASUREMENTS\n"); - } - if (mGnssNavigationMessageProvider.isAvailableInPlatform()) { - s.append(" hasSubHal=NAV_MESSAGES\n"); + if (hasCapability(GPS_CAPABILITY_MEASUREMENT_CORRECTIONS)) { + s.append("MEASUREMENT_CORRECTIONS "); } + s.append(")\n"); if (mGnssMeasurementCorrectionsProvider.isAvailableInPlatform()) { - s.append(" hasSubHal=MEASUREMENT_CORRECTIONS ["); + s.append(" SubHal=MEASUREMENT_CORRECTIONS["); s.append(mGnssMeasurementCorrectionsProvider.toStringCapabilities()); s.append("]\n"); } diff --git a/services/core/java/com/android/server/media/AudioPlayerStateMonitor.java b/services/core/java/com/android/server/media/AudioPlayerStateMonitor.java index 648c782a7d1e..603d7cfb4525 100644 --- a/services/core/java/com/android/server/media/AudioPlayerStateMonitor.java +++ b/services/core/java/com/android/server/media/AudioPlayerStateMonitor.java @@ -18,14 +18,11 @@ package com.android.server.media; import android.annotation.NonNull; import android.content.Context; +import android.media.AudioManager; import android.media.AudioPlaybackConfiguration; -import android.media.IAudioService; -import android.media.IPlaybackConfigDispatcher; -import android.os.Binder; import android.os.Handler; import android.os.Looper; import android.os.Message; -import android.os.RemoteException; import android.os.UserHandle; import android.util.ArrayMap; import android.util.ArraySet; @@ -42,11 +39,11 @@ import java.util.Set; /** * Monitors the state changes of audio players. */ -class AudioPlayerStateMonitor extends IPlaybackConfigDispatcher.Stub { +class AudioPlayerStateMonitor { private static boolean DEBUG = MediaSessionService.DEBUG; private static String TAG = "AudioPlayerStateMonitor"; - private static AudioPlayerStateMonitor sInstance = new AudioPlayerStateMonitor(); + private static AudioPlayerStateMonitor sInstance; /** * Listener for handling the active state changes of audio players. @@ -96,96 +93,33 @@ class AudioPlayerStateMonitor extends IPlaybackConfigDispatcher.Stub { private final Map<OnAudioPlayerActiveStateChangedListener, MessageHandler> mListenerMap = new ArrayMap<>(); @GuardedBy("mLock") - private final Set<Integer> mActiveAudioUids = new ArraySet<>(); + @SuppressWarnings("WeakerAccess") /* synthetic access */ + final Set<Integer> mActiveAudioUids = new ArraySet<>(); @GuardedBy("mLock") - private ArrayMap<Integer, AudioPlaybackConfiguration> mPrevActiveAudioPlaybackConfigs = + @SuppressWarnings("WeakerAccess") /* synthetic access */ + ArrayMap<Integer, AudioPlaybackConfiguration> mPrevActiveAudioPlaybackConfigs = new ArrayMap<>(); // Sorted array of UIDs that had active audio playback. (i.e. playing an audio/video) // The UID whose audio playback becomes active at the last comes first. // TODO(b/35278867): Find and use unique identifier for apps because apps may share the UID. @GuardedBy("mLock") - private final IntArray mSortedAudioPlaybackClientUids = new IntArray(); + @SuppressWarnings("WeakerAccess") /* synthetic access */ + final IntArray mSortedAudioPlaybackClientUids = new IntArray(); - @GuardedBy("mLock") - private boolean mRegisteredToAudioService; - - static AudioPlayerStateMonitor getInstance() { - return sInstance; - } - - private AudioPlayerStateMonitor() { - } - - /** - * Called when the {@link AudioPlaybackConfiguration} is updated. - * <p>If an app starts audio playback, the app's local media session will be the media button - * session. If the app has multiple media sessions, the playback active local session will be - * picked. - * - * @param configs List of the current audio playback configuration - */ - @Override - public void dispatchPlaybackConfigChange(List<AudioPlaybackConfiguration> configs, - boolean flush) { - if (flush) { - Binder.flushPendingCommands(); - } - final long token = Binder.clearCallingIdentity(); - try { - synchronized (mLock) { - // Update mActiveAudioUids - mActiveAudioUids.clear(); - ArrayMap<Integer, AudioPlaybackConfiguration> activeAudioPlaybackConfigs = - new ArrayMap<>(); - for (AudioPlaybackConfiguration config : configs) { - if (config.isActive()) { - mActiveAudioUids.add(config.getClientUid()); - activeAudioPlaybackConfigs.put(config.getPlayerInterfaceId(), config); - } - } - - // Update mSortedAuioPlaybackClientUids. - for (int i = 0; i < activeAudioPlaybackConfigs.size(); ++i) { - AudioPlaybackConfiguration config = activeAudioPlaybackConfigs.valueAt(i); - final int uid = config.getClientUid(); - if (!mPrevActiveAudioPlaybackConfigs.containsKey( - config.getPlayerInterfaceId())) { - if (DEBUG) { - Log.d(TAG, "Found a new active media playback. " + - AudioPlaybackConfiguration.toLogFriendlyString(config)); - } - // New active audio playback. - int index = mSortedAudioPlaybackClientUids.indexOf(uid); - if (index == 0) { - // It's the lastly played music app already. Skip updating. - continue; - } else if (index > 0) { - mSortedAudioPlaybackClientUids.remove(index); - } - mSortedAudioPlaybackClientUids.add(0, uid); - } - } - // Notify the active state change of audio players. - for (AudioPlaybackConfiguration config : configs) { - final int pii = config.getPlayerInterfaceId(); - boolean wasActive = mPrevActiveAudioPlaybackConfigs.remove(pii) != null; - if (wasActive != config.isActive()) { - sendAudioPlayerActiveStateChangedMessageLocked( - config, /* isRemoved */ false); - } - } - for (AudioPlaybackConfiguration config : mPrevActiveAudioPlaybackConfigs.values()) { - sendAudioPlayerActiveStateChangedMessageLocked(config, /* isRemoved */ true); - } - - // Update mPrevActiveAudioPlaybackConfigs - mPrevActiveAudioPlaybackConfigs = activeAudioPlaybackConfigs; + static AudioPlayerStateMonitor getInstance(Context context) { + synchronized (AudioPlayerStateMonitor.class) { + if (sInstance == null) { + sInstance = new AudioPlayerStateMonitor(context); } - } finally { - Binder.restoreCallingIdentity(token); + return sInstance; } } + private AudioPlayerStateMonitor(Context context) { + AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); + am.registerAudioPlaybackCallback(new AudioManagerPlaybackListener(), null); + } + /** * Registers OnAudioPlayerActiveStateChangedListener. */ @@ -275,20 +209,6 @@ class AudioPlayerStateMonitor extends IPlaybackConfigDispatcher.Stub { } } - public void registerSelfIntoAudioServiceIfNeeded(IAudioService audioService) { - synchronized (mLock) { - try { - if (!mRegisteredToAudioService) { - audioService.registerPlaybackCallback(this); - mRegisteredToAudioService = true; - } - } catch (RemoteException e) { - Log.wtf(TAG, "Failed to register playback callback", e); - mRegisteredToAudioService = false; - } - } - } - @GuardedBy("mLock") private void sendAudioPlayerActiveStateChangedMessageLocked( final AudioPlaybackConfiguration config, final boolean isRemoved) { @@ -296,4 +216,59 @@ class AudioPlayerStateMonitor extends IPlaybackConfigDispatcher.Stub { messageHandler.sendAudioPlayerActiveStateChangedMessage(config, isRemoved); } } + + private class AudioManagerPlaybackListener extends AudioManager.AudioPlaybackCallback { + @Override + public void onPlaybackConfigChanged(List<AudioPlaybackConfiguration> configs) { + synchronized (mLock) { + // Update mActiveAudioUids + mActiveAudioUids.clear(); + ArrayMap<Integer, AudioPlaybackConfiguration> activeAudioPlaybackConfigs = + new ArrayMap<>(); + for (AudioPlaybackConfiguration config : configs) { + if (config.isActive()) { + mActiveAudioUids.add(config.getClientUid()); + activeAudioPlaybackConfigs.put(config.getPlayerInterfaceId(), config); + } + } + + // Update mSortedAuioPlaybackClientUids. + for (int i = 0; i < activeAudioPlaybackConfigs.size(); ++i) { + AudioPlaybackConfiguration config = activeAudioPlaybackConfigs.valueAt(i); + final int uid = config.getClientUid(); + if (!mPrevActiveAudioPlaybackConfigs.containsKey( + config.getPlayerInterfaceId())) { + if (DEBUG) { + Log.d(TAG, "Found a new active media playback. " + + AudioPlaybackConfiguration.toLogFriendlyString(config)); + } + // New active audio playback. + int index = mSortedAudioPlaybackClientUids.indexOf(uid); + if (index == 0) { + // It's the lastly played music app already. Skip updating. + continue; + } else if (index > 0) { + mSortedAudioPlaybackClientUids.remove(index); + } + mSortedAudioPlaybackClientUids.add(0, uid); + } + } + // Notify the active state change of audio players. + for (AudioPlaybackConfiguration config : configs) { + final int pii = config.getPlayerInterfaceId(); + boolean wasActive = mPrevActiveAudioPlaybackConfigs.remove(pii) != null; + if (wasActive != config.isActive()) { + sendAudioPlayerActiveStateChangedMessageLocked( + config, /* isRemoved */ false); + } + } + for (AudioPlaybackConfiguration config : mPrevActiveAudioPlaybackConfigs.values()) { + sendAudioPlayerActiveStateChangedMessageLocked(config, /* isRemoved */ true); + } + + // Update mPrevActiveAudioPlaybackConfigs + mPrevActiveAudioPlaybackConfigs = activeAudioPlaybackConfigs; + } + } + } } diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java index f822e82ecdfc..a43533f35cd9 100644 --- a/services/core/java/com/android/server/media/MediaRouterService.java +++ b/services/core/java/com/android/server/media/MediaRouterService.java @@ -117,7 +117,7 @@ public final class MediaRouterService extends IMediaRouterService.Stub mAudioService = IAudioService.Stub.asInterface( ServiceManager.getService(Context.AUDIO_SERVICE)); - mAudioPlayerStateMonitor = AudioPlayerStateMonitor.getInstance(); + mAudioPlayerStateMonitor = AudioPlayerStateMonitor.getInstance(context); mAudioPlayerStateMonitor.registerListener( new AudioPlayerStateMonitor.OnAudioPlayerActiveStateChangedListener() { static final long WAIT_MS = 500; @@ -168,7 +168,6 @@ public final class MediaRouterService extends IMediaRouterService.Stub } } }, mHandler); - mAudioPlayerStateMonitor.registerSelfIntoAudioServiceIfNeeded(mAudioService); AudioRoutesInfo audioRoutes = null; try { diff --git a/services/core/java/com/android/server/media/MediaSessionServiceImpl.java b/services/core/java/com/android/server/media/MediaSessionServiceImpl.java index 3acad7a9c70a..0cabf1d35206 100644 --- a/services/core/java/com/android/server/media/MediaSessionServiceImpl.java +++ b/services/core/java/com/android/server/media/MediaSessionServiceImpl.java @@ -168,7 +168,7 @@ public class MediaSessionServiceImpl extends MediaSessionService.ServiceImpl { mAudioManagerInternal = LocalServices.getService(AudioManagerInternal.class); mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); - mAudioPlayerStateMonitor = AudioPlayerStateMonitor.getInstance(); + mAudioPlayerStateMonitor = AudioPlayerStateMonitor.getInstance(mContext); mAudioPlayerStateMonitor.registerListener( (config, isRemoved) -> { if (isRemoved || !config.isActive() || config.getPlayerType() @@ -183,7 +183,6 @@ public class MediaSessionServiceImpl extends MediaSessionService.ServiceImpl { } } }, null /* handler */); - mAudioPlayerStateMonitor.registerSelfIntoAudioServiceIfNeeded(mAudioService); mContentResolver = mContext.getContentResolver(); mSettingsObserver = new SettingsObserver(); mSettingsObserver.observe(); diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index af58b195a491..c6f6c50a308d 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -3515,10 +3515,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { /** * Process state of UID changed; if needed, will trigger * {@link #updateRulesForDataUsageRestrictionsUL(int)} and - * {@link #updateRulesForPowerRestrictionsUL(int)} + * {@link #updateRulesForPowerRestrictionsUL(int)}. Returns true if the state was updated. */ @GuardedBy("mUidRulesFirstLock") - private void updateUidStateUL(int uid, int uidState) { + private boolean updateUidStateUL(int uid, int uidState) { Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateUidStateUL"); try { final int oldUidState = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); @@ -3537,15 +3537,16 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } updateRulesForPowerRestrictionsUL(uid); } - updateNetworkStats(uid, isUidStateForeground(uidState)); + return true; } } finally { Trace.traceEnd(Trace.TRACE_TAG_NETWORK); } + return false; } @GuardedBy("mUidRulesFirstLock") - private void removeUidStateUL(int uid) { + private boolean removeUidStateUL(int uid) { final int index = mUidState.indexOfKey(uid); if (index >= 0) { final int oldUidState = mUidState.valueAt(index); @@ -3560,9 +3561,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { updateRuleForRestrictPowerUL(uid); } updateRulesForPowerRestrictionsUL(uid); - updateNetworkStats(uid, false); + return true; } } + return false; } // adjust stats accounting based on foreground status @@ -4552,21 +4554,26 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } } } - }; void handleUidChanged(int uid, int procState, long procStateSeq) { Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidStateChanged"); try { + boolean updated; synchronized (mUidRulesFirstLock) { // We received a uid state change callback, add it to the history so that it // will be useful for debugging. mLogger.uidStateChanged(uid, procState, procStateSeq); // Now update the network policy rules as per the updated uid state. - updateUidStateUL(uid, procState); + updated = updateUidStateUL(uid, procState); // Updating the network rules is done, so notify AMS about this. mActivityManagerInternal.notifyNetworkPolicyRulesUpdated(uid, procStateSeq); } + // Do this without the lock held. handleUidChanged() and handleUidGone() are + // called from the handler, so there's no multi-threading issue. + if (updated) { + updateNetworkStats(uid, isUidStateForeground(procState)); + } } finally { Trace.traceEnd(Trace.TRACE_TAG_NETWORK); } @@ -4575,8 +4582,14 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { void handleUidGone(int uid) { Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidGone"); try { + boolean updated; synchronized (mUidRulesFirstLock) { - removeUidStateUL(uid); + updated = removeUidStateUL(uid); + } + // Do this without the lock held. handleUidChanged() and handleUidGone() are + // called from the handler, so there's no multi-threading issue. + if (updated) { + updateNetworkStats(uid, false); } } finally { Trace.traceEnd(Trace.TRACE_TAG_NETWORK); diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java index 0493ae908f12..aaf3df39d429 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java @@ -52,6 +52,7 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.statusbar.IStatusBar; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.statusbar.NotificationVisibility; +import com.android.internal.statusbar.RegisterStatusBarResult; import com.android.internal.statusbar.StatusBarIcon; import com.android.internal.util.DumpUtils; import com.android.server.LocalServices; @@ -63,7 +64,6 @@ import com.android.server.wm.WindowManagerService; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; -import java.util.List; /** * A note on locking: We rely on the fact that calls onto mBar are oneway or @@ -1037,37 +1037,27 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D // ================================================================================ // TODO(b/118592525): refactor it as an IStatusBar API. @Override - public void registerStatusBar(IStatusBar bar, List<String> iconSlots, - List<StatusBarIcon> iconList, int switches[], List<IBinder> binders, - Rect fullscreenStackBounds, Rect dockedStackBounds) { + public RegisterStatusBarResult registerStatusBar(IStatusBar bar) { enforceStatusBarService(); Slog.i(TAG, "registerStatusBar bar=" + bar); mBar = bar; mDeathRecipient.linkToDeath(); notifyBarAttachChanged(); + final ArrayMap<String, StatusBarIcon> icons; synchronized (mIcons) { - for (String slot : mIcons.keySet()) { - iconSlots.add(slot); - iconList.add(mIcons.get(slot)); - } + icons = new ArrayMap<>(mIcons); } synchronized (mLock) { // TODO(b/118592525): Currently, status bar only works on the default display. // Make it aware of multi-display if needed. final UiState state = mDisplayUiState.get(DEFAULT_DISPLAY); - switches[0] = gatherDisableActionsLocked(mCurrentUserId, 1); - switches[1] = state.mSystemUiVisibility; - switches[2] = state.mMenuVisible ? 1 : 0; - switches[3] = state.mImeWindowVis; - switches[4] = state.mImeBackDisposition; - switches[5] = state.mShowImeSwitcher ? 1 : 0; - switches[6] = gatherDisableActionsLocked(mCurrentUserId, 2); - switches[7] = state.mFullscreenStackSysUiVisibility; - switches[8] = state.mDockedStackSysUiVisibility; - binders.add(state.mImeToken); - fullscreenStackBounds.set(state.mFullscreenStackBounds); - dockedStackBounds.set(state.mDockedStackBounds); + return new RegisterStatusBarResult(icons, gatherDisableActionsLocked(mCurrentUserId, 1), + state.mSystemUiVisibility, state.mMenuVisible, state.mImeWindowVis, + state.mImeBackDisposition, state.mShowImeSwitcher, + gatherDisableActionsLocked(mCurrentUserId, 2), + state.mFullscreenStackSysUiVisibility, state.mDockedStackSysUiVisibility, + state.mImeToken, state.mFullscreenStackBounds, state.mDockedStackBounds); } } diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp index f447f475684d..019cb315bc61 100644 --- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp +++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp @@ -735,31 +735,18 @@ Return<void> GnssCallback::gnssNmeaCb( } Return<void> GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) { - return GnssCallback::gnssSetCapabilitesCbImpl(capabilities, - /* hasSubHalCapabilityFlags = */ true); -} + ALOGD("%s: %du\n", __func__, capabilities); -Return<void> GnssCallback::gnssSetCapabilitiesCb_2_0(uint32_t capabilities) { - return GnssCallback::gnssSetCapabilitesCbImpl(capabilities, - /* hasSubHalCapabilityFlags = */ false); -} - -Return <void> GnssCallback::gnssSetCapabilitesCbImpl(uint32_t capabilities, - bool hasSubHalCapabilityFlags) { - // The IGnssCallback.hal@2.0 removed sub-HAL capability flags from the Capabilities enum - // and instead uses the sub-HAL non-null handle returned from IGnss.hal@2.0 to indicate - // support. Therefore, the 'hasSubHalCapabilityFlags' parameter is needed to tell if the - // 'capabilities' parameter includes the sub-HAL capability flags or not. Old HALs - // which explicitly set the sub-HAL capability bits must continue to work. - ALOGD("%s: capabilities=%du, hasSubHalCapabilityFlags=%d\n", __func__, capabilities, - hasSubHalCapabilityFlags); JNIEnv* env = getJniEnv(); - env->CallVoidMethod(mCallbacksObj, method_setTopHalCapabilities, capabilities, - boolToJbool(hasSubHalCapabilityFlags)); + env->CallVoidMethod(mCallbacksObj, method_setTopHalCapabilities, capabilities); checkAndClearExceptionFromCallback(env, __FUNCTION__); return Void(); } +Return<void> GnssCallback::gnssSetCapabilitiesCb_2_0(uint32_t capabilities) { + return GnssCallback::gnssSetCapabilitesCb(capabilities); +} + Return<void> GnssCallback::gnssAcquireWakelockCb() { acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME); return Void(); @@ -1542,7 +1529,7 @@ static void android_location_GnssLocationProvider_init_once(JNIEnv* env, jclass method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "(I[I[F[F[F[F)V"); method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V"); method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V"); - method_setTopHalCapabilities = env->GetMethodID(clazz, "setTopHalCapabilities", "(IZ)V"); + method_setTopHalCapabilities = env->GetMethodID(clazz, "setTopHalCapabilities", "(I)V"); method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V"); method_setGnssHardwareModelName = env->GetMethodID(clazz, "setGnssHardwareModelName", "(Ljava/lang/String;)V"); diff --git a/services/net/java/android/net/ipmemorystore/OnBlobRetrievedListener.java b/services/net/java/android/net/ipmemorystore/OnBlobRetrievedListener.java index 9685ff6dd3ca..22978a262a11 100644 --- a/services/net/java/android/net/ipmemorystore/OnBlobRetrievedListener.java +++ b/services/net/java/android/net/ipmemorystore/OnBlobRetrievedListener.java @@ -30,12 +30,15 @@ public interface OnBlobRetrievedListener { /** Converts this OnBlobRetrievedListener to a parcelable object */ @NonNull - static IOnBlobRetrievedListener toAIDL(final OnBlobRetrievedListener listener) { + static IOnBlobRetrievedListener toAIDL(@NonNull final OnBlobRetrievedListener listener) { return new IOnBlobRetrievedListener.Stub() { @Override public void onBlobRetrieved(final StatusParcelable statusParcelable, final String l2Key, final String name, final Blob blob) { - listener.onBlobRetrieved(new Status(statusParcelable), l2Key, name, blob); + // NonNull, but still don't crash the system server if null + if (null != listener) { + listener.onBlobRetrieved(new Status(statusParcelable), l2Key, name, blob); + } } }; } diff --git a/services/net/java/android/net/ipmemorystore/OnL2KeyResponseListener.java b/services/net/java/android/net/ipmemorystore/OnL2KeyResponseListener.java index 80209c574203..9e7c1c869e1a 100644 --- a/services/net/java/android/net/ipmemorystore/OnL2KeyResponseListener.java +++ b/services/net/java/android/net/ipmemorystore/OnL2KeyResponseListener.java @@ -30,12 +30,15 @@ public interface OnL2KeyResponseListener { /** Converts this OnL2KeyResponseListener to a parcelable object */ @NonNull - static IOnL2KeyResponseListener toAIDL(final OnL2KeyResponseListener listener) { + static IOnL2KeyResponseListener toAIDL(@NonNull final OnL2KeyResponseListener listener) { return new IOnL2KeyResponseListener.Stub() { @Override public void onL2KeyResponse(final StatusParcelable statusParcelable, final String l2Key) { - listener.onL2KeyResponse(new Status(statusParcelable), l2Key); + // NonNull, but still don't crash the system server if null + if (null != listener) { + listener.onL2KeyResponse(new Status(statusParcelable), l2Key); + } } }; } diff --git a/services/net/java/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java b/services/net/java/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java index f0f6f4016139..59da26880bdd 100644 --- a/services/net/java/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java +++ b/services/net/java/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java @@ -31,15 +31,18 @@ public interface OnNetworkAttributesRetrievedListener { /** Converts this OnNetworkAttributesRetrievedListener to a parcelable object */ @NonNull static IOnNetworkAttributesRetrievedListener toAIDL( - final OnNetworkAttributesRetrievedListener listener) { + @NonNull final OnNetworkAttributesRetrievedListener listener) { return new IOnNetworkAttributesRetrievedListener.Stub() { @Override public void onNetworkAttributesRetrieved(final StatusParcelable statusParcelable, final String l2Key, final NetworkAttributesParcelable networkAttributesParcelable) { - listener.onNetworkAttributesRetrieved( - new Status(statusParcelable), l2Key, - new NetworkAttributes(networkAttributesParcelable)); + // NonNull, but still don't crash the system server if null + if (null != listener) { + listener.onNetworkAttributesRetrieved( + new Status(statusParcelable), l2Key, + new NetworkAttributes(networkAttributesParcelable)); + } } }; } diff --git a/services/net/java/android/net/ipmemorystore/OnSameL3NetworkResponseListener.java b/services/net/java/android/net/ipmemorystore/OnSameL3NetworkResponseListener.java index ba1e0e6f2b9f..0154fd259620 100644 --- a/services/net/java/android/net/ipmemorystore/OnSameL3NetworkResponseListener.java +++ b/services/net/java/android/net/ipmemorystore/OnSameL3NetworkResponseListener.java @@ -30,14 +30,18 @@ public interface OnSameL3NetworkResponseListener { /** Converts this OnSameL3NetworkResponseListener to a parcelable object */ @NonNull - static IOnSameL3NetworkResponseListener toAIDL(final OnSameL3NetworkResponseListener listener) { + static IOnSameL3NetworkResponseListener toAIDL( + @NonNull final OnSameL3NetworkResponseListener listener) { return new IOnSameL3NetworkResponseListener.Stub() { @Override public void onSameL3NetworkResponse(final StatusParcelable statusParcelable, final SameL3NetworkResponseParcelable sameL3NetworkResponseParcelable) { - listener.onSameL3NetworkResponse( - new Status(statusParcelable), - new SameL3NetworkResponse(sameL3NetworkResponseParcelable)); + // NonNull, but still don't crash the system server if null + if (null != listener) { + listener.onSameL3NetworkResponse( + new Status(statusParcelable), + new SameL3NetworkResponse(sameL3NetworkResponseParcelable)); + } } }; } diff --git a/services/net/java/android/net/ipmemorystore/OnStatusListener.java b/services/net/java/android/net/ipmemorystore/OnStatusListener.java index 0de16660ff5f..824b7b05bd5d 100644 --- a/services/net/java/android/net/ipmemorystore/OnStatusListener.java +++ b/services/net/java/android/net/ipmemorystore/OnStatusListener.java @@ -17,6 +17,7 @@ package android.net.ipmemorystore; import android.annotation.NonNull; +import android.annotation.Nullable; /** * A listener for the IpMemoryStore to return a status to a client. @@ -30,11 +31,13 @@ public interface OnStatusListener { /** Converts this OnStatusListener to a parcelable object */ @NonNull - static IOnStatusListener toAIDL(final OnStatusListener listener) { + static IOnStatusListener toAIDL(@Nullable final OnStatusListener listener) { return new IOnStatusListener.Stub() { @Override public void onComplete(final StatusParcelable statusParcelable) { - listener.onComplete(new Status(statusParcelable)); + if (null != listener) { + listener.onComplete(new Status(statusParcelable)); + } } }; } diff --git a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java index 46d076184eef..231025c61c8a 100644 --- a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java @@ -484,9 +484,6 @@ public class UserControllerTest { private void waitForHandlerToComplete(Handler handler, long waitTimeMs) throws InterruptedException { - if (!handler.hasMessagesOrCallbacks()) { // if nothing queued, do not wait. - return; - } final Object lock = new Object(); synchronized (lock) { handler.post(() -> { diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index bdd01e2f69fb..072eb88797f8 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -2682,7 +2682,7 @@ public class TelephonyManager { */ /** {@hide} */ @UnsupportedAppUsage - public static String getNetworkTypeName(int type) { + public static String getNetworkTypeName(@NetworkType int type) { switch (type) { case NETWORK_TYPE_GPRS: return "GPRS"; @@ -4812,6 +4812,22 @@ public class TelephonyManager { } } + /** + * Convert data state to string + * + * @return The data state in string format. + * @hide + */ + public static String dataStateToString(@DataState int state) { + switch (state) { + case DATA_DISCONNECTED: return "DISCONNECTED"; + case DATA_CONNECTING: return "CONNECTING"; + case DATA_CONNECTED: return "CONNECTED"; + case DATA_SUSPENDED: return "SUSPENDED"; + } + return "UNKNOWN(" + state + ")"; + } + /** * @hide */ diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java index 28af7cee8f38..33bb4cceb3a9 100644 --- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java +++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java @@ -26,7 +26,6 @@ import static org.junit.Assert.assertTrue; import android.content.Context; import android.content.pm.VersionedPackage; import android.os.Handler; -import android.os.RemoteException; import android.os.test.TestLooper; import android.util.AtomicFile; @@ -43,6 +42,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; @@ -635,43 +635,34 @@ public class PackageWatchdogTest { private boolean mIsEnabled; private List<String> mSupportedPackages = new ArrayList<>(); private List<String> mRequestedPackages = new ArrayList<>(); - private Runnable mStateChangedRunnable; private Consumer<String> mPassedConsumer; + private Consumer<List<String>> mSupportedConsumer; + private Runnable mNotifySyncRunnable; @Override - public void request(String packageName) throws RemoteException { - if (!mRequestedPackages.contains(packageName)) { - mRequestedPackages.add(packageName); + public void setEnabled(boolean enabled) { + mIsEnabled = enabled; + if (!mIsEnabled) { + mSupportedPackages.clear(); } } @Override - public void cancel(String packageName) throws RemoteException { - mRequestedPackages.remove(packageName); - } - - @Override - public void getSupportedPackages(Consumer<List<String>> consumer) throws RemoteException { - consumer.accept(mIsEnabled ? mSupportedPackages : Collections.emptyList()); - } - - @Override - public void getRequestedPackages(Consumer<List<String>> consumer) throws RemoteException { - // Pass copy to prevent ConcurrentModificationException during test - consumer.accept( - mIsEnabled ? new ArrayList<>(mRequestedPackages) : Collections.emptyList()); - } - - @Override - public void setEnabled(boolean enabled) { - mIsEnabled = enabled; - mStateChangedRunnable.run(); + public void setCallbacks(Consumer<String> passedConsumer, + Consumer<List<String>> supportedConsumer, Runnable notifySyncRunnable) { + mPassedConsumer = passedConsumer; + mSupportedConsumer = supportedConsumer; + mNotifySyncRunnable = notifySyncRunnable; } @Override - public void setCallbacks(Runnable stateChangedRunnable, Consumer<String> passedConsumer) { - mStateChangedRunnable = stateChangedRunnable; - mPassedConsumer = passedConsumer; + public void syncRequests(Set<String> packages) { + mRequestedPackages.clear(); + if (mIsEnabled) { + packages.retainAll(mSupportedPackages); + mRequestedPackages.addAll(packages); + } + mSupportedConsumer.accept(mSupportedPackages); } public void setSupportedPackages(List<String> packages) { diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 9b3796f57d30..140e9c324dfa 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -36,11 +36,14 @@ import android.content.pm.ParceledListSlice; import android.net.ConnectivityManager; import android.net.DhcpInfo; import android.net.Network; +import android.net.NetworkCapabilities; +import android.net.NetworkRequest; import android.net.wifi.hotspot2.IProvisioningCallback; import android.net.wifi.hotspot2.OsuProvider; import android.net.wifi.hotspot2.PasspointConfiguration; import android.net.wifi.hotspot2.ProvisioningCallback; import android.os.Binder; +import android.os.Build; import android.os.Handler; import android.os.IBinder; import android.os.Looper; @@ -56,6 +59,7 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.AsyncChannel; import com.android.internal.util.Protocol; +import com.android.server.net.NetworkPinner; import dalvik.system.CloseGuard; @@ -1895,12 +1899,27 @@ public class WifiManager { */ @Deprecated public boolean enableNetwork(int netId, boolean attemptConnect) { + final boolean pin = attemptConnect && mTargetSdkVersion < Build.VERSION_CODES.LOLLIPOP; + if (pin) { + NetworkRequest request = new NetworkRequest.Builder() + .clearCapabilities() + .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN) + .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) + .build(); + NetworkPinner.pin(mContext, request); + } + boolean success; try { success = mService.enableNetwork(netId, attemptConnect, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } + + if (pin && !success) { + NetworkPinner.unpin(); + } + return success; } |