summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xAndroid.bp1
-rw-r--r--apex/jobscheduler/framework/java/com/android/server/DeviceIdleInternal.java2
-rw-r--r--apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java27
-rw-r--r--apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java29
-rw-r--r--apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java2
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/controllers/DeviceIdleJobsController.java8
-rw-r--r--core/java/android/app/StatusBarManager.java2
-rw-r--r--core/java/android/app/admin/SystemUpdateInfo.java4
-rw-r--r--core/java/android/content/Intent.java9
-rw-r--r--core/java/android/os/BatteryManager.java7
-rw-r--r--core/java/android/os/FileUtils.java4
-rw-r--r--core/java/android/os/Trace.java4
-rw-r--r--core/java/android/os/UpdateEngine.java11
-rw-r--r--core/java/android/provider/Settings.java18
-rw-r--r--core/java/android/security/net/config/PinSet.java10
-rw-r--r--core/java/android/text/style/TextAppearanceSpan.java18
-rw-r--r--core/java/android/util/BoostFramework.java18
-rwxr-xr-xcore/java/android/widget/AbsListView.java16
-rw-r--r--core/java/android/widget/TextView.java6
-rw-r--r--core/java/com/android/internal/app/ChooserActivity.java7
-rw-r--r--core/java/com/android/internal/graphics/fonts/DynamicMetrics.java151
-rw-r--r--core/java/com/android/internal/ice/hardware/HIDLHelper.java44
-rw-r--r--core/java/com/android/internal/ice/hardware/LineageHardwareManager.java259
-rw-r--r--core/java/com/android/internal/ice/hardware/TouchscreenGesture.aidl20
-rw-r--r--core/java/com/android/internal/ice/hardware/TouchscreenGesture.java78
-rw-r--r--core/java/com/android/internal/notification/SystemNotificationChannels.java2
-rw-r--r--core/java/com/android/internal/os/DeviceKeyHandler.java31
-rw-r--r--core/proto/android/server/appstatetracker.proto5
-rw-r--r--core/res/res/drawable/toast_frame.xml2
-rw-r--r--core/res/res/values/config.xml4
-rw-r--r--core/res/res/values/ice_config.xml51
-rw-r--r--core/res/res/values/ice_symbols.xml35
-rw-r--r--data/fonts/Android.bp10
-rw-r--r--data/fonts/fonts.xml132
-rw-r--r--data/keyboards/Generic.kcm2
-rw-r--r--graphics/java/android/graphics/Paint.java2
-rw-r--r--graphics/java/android/graphics/Typeface.java30
-rw-r--r--packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v31/styles.xml4
-rw-r--r--packages/SettingsLib/res/drawable/ic_4g_plus_mobiledata.xml23
-rw-r--r--packages/SettingsLib/res/drawable/ic_lte_plus_mobiledata.xml27
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java9
-rw-r--r--packages/SystemUI/customization/res/font/clock.xml27
-rw-r--r--packages/SystemUI/customization/res/font/google_sans_clock.ttfbin0 -> 131700 bytes
-rw-r--r--packages/SystemUI/customization/res/layout/clock_default_large.xml2
-rw-r--r--packages/SystemUI/customization/res/layout/clock_default_small.xml2
-rw-r--r--packages/SystemUI/res/drawable-nodpi/udfps_icon_pressed.pngbin0 -> 108 bytes
-rw-r--r--packages/SystemUI/res/drawable/dialog_tri_state_down_bg.xml29
-rw-r--r--packages/SystemUI/res/drawable/dialog_tri_state_middle_bg.xml29
-rw-r--r--packages/SystemUI/res/drawable/dialog_tri_state_up_bg.xml29
-rw-r--r--packages/SystemUI/res/drawable/ic_qs_aod.xml11
-rw-r--r--packages/SystemUI/res/drawable/ic_qs_caffeine.xml27
-rw-r--r--packages/SystemUI/res/drawable/ic_qs_heads_up.xml36
-rw-r--r--packages/SystemUI/res/drawable/stat_sys_dnd.xml4
-rw-r--r--packages/SystemUI/res/drawable/stat_sys_ringer_silent.xml4
-rw-r--r--packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml6
-rw-r--r--packages/SystemUI/res/layout-land/volume_dialog.xml12
-rw-r--r--packages/SystemUI/res/layout/qs_footer_impl.xml2
-rw-r--r--packages/SystemUI/res/layout/tri_state_dialog.xml60
-rw-r--r--packages/SystemUI/res/layout/udfps_view.xml6
-rw-r--r--packages/SystemUI/res/layout/volume_dialog.xml11
-rw-r--r--packages/SystemUI/res/values/config.xml2
-rw-r--r--packages/SystemUI/res/values/ice_config.xml22
-rw-r--r--packages/SystemUI/res/values/ice_dimens.xml45
-rw-r--r--packages/SystemUI/res/values/ice_strings.xml32
-rw-r--r--packages/SystemUI/res/values/ice_styles.xml23
-rw-r--r--packages/SystemUI/res/values/styles.xml3
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java20
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java9
-rwxr-xr-xpackages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/SystemUIService.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsSurfaceView.java159
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt31
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinator.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/flags/Flags.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarInflaterView.java53
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java27
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java23
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/AODTile.java161
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/CaffeineTile.java253
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/HeadsUpTile.java137
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt25
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java39
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/PulsingGestureListener.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java16
-rwxr-xr-xpackages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/toast/SystemUIToast.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/tristate/TriStateUiController.java31
-rw-r--r--packages/SystemUI/src/com/android/systemui/tristate/TriStateUiControllerImpl.java503
-rw-r--r--packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java33
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt5
-rw-r--r--packages/overlays/Android.mk1
-rw-r--r--proto/src/metrics_constants/metrics_constants.proto3
-rw-r--r--services/core/java/com/android/server/BatteryService.java32
-rw-r--r--services/core/java/com/android/server/StorageManagerService.java2
-rw-r--r--services/core/java/com/android/server/am/UserController.java3
-rw-r--r--services/core/java/com/android/server/location/gnss/GnssLocationProvider.java10
-rwxr-xr-xservices/core/java/com/android/server/notification/NotificationManagerService.java4
-rw-r--r--services/core/java/com/android/server/notification/PreferencesHelper.java47
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java55
-rw-r--r--services/core/java/com/android/server/pm/Settings.java4
-rw-r--r--services/core/java/com/android/server/pm/ShortcutService.java2
-rw-r--r--services/core/java/com/android/server/pm/UserManagerService.java8
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java67
-rw-r--r--services/core/java/com/android/server/power/Notifier.java6
-rw-r--r--services/core/java/com/android/server/textservices/TextServicesManagerService.java26
-rw-r--r--services/core/java/com/android/server/webkit/SystemImpl.java2
-rw-r--r--services/core/java/com/android/server/wm/AlertWindowNotification.java15
-rw-r--r--services/core/java/com/android/server/wm/RemoteDisplayChangeController.java10
-rw-r--r--services/core/java/com/android/server/wm/Session.java3
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java4
-rw-r--r--telephony/java/android/telephony/CarrierConfigManager.java2
126 files changed, 3239 insertions, 274 deletions
diff --git a/Android.bp b/Android.bp
index 429a0c471645..1762197eb9ed 100755
--- a/Android.bp
+++ b/Android.bp
@@ -246,6 +246,7 @@ java_library {
"com.android.sysprop.init",
"com.android.sysprop.localization",
"PlatformProperties",
+ "vendor.lineage.touch-V1.0-java",
],
sdk_version: "core_platform",
installable: false,
diff --git a/apex/jobscheduler/framework/java/com/android/server/DeviceIdleInternal.java b/apex/jobscheduler/framework/java/com/android/server/DeviceIdleInternal.java
index caf7e7f4a4ed..7ec603de40fd 100644
--- a/apex/jobscheduler/framework/java/com/android/server/DeviceIdleInternal.java
+++ b/apex/jobscheduler/framework/java/com/android/server/DeviceIdleInternal.java
@@ -73,6 +73,8 @@ public interface DeviceIdleInternal {
boolean isAppOnWhitelist(int appid);
+ int[] getPowerSaveWhitelistSystemAppIds();
+
int[] getPowerSaveWhitelistUserAppIds();
int[] getPowerSaveTempWhitelistAppIds();
diff --git a/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java b/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java
index fab5b5fd6933..606f0df0dfda 100644
--- a/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java
+++ b/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java
@@ -109,6 +109,12 @@ public class AppStateTrackerImpl implements AppStateTracker {
final SparseBooleanArray mActiveUids = new SparseBooleanArray();
/**
+ * System exemption list in the device idle controller.
+ */
+ @GuardedBy("mLock")
+ private int[] mPowerExemptSystemAppIds = new int[0];
+
+ /**
* System except-idle + user exemption list in the device idle controller.
*/
@GuardedBy("mLock")
@@ -1075,6 +1081,7 @@ public class AppStateTrackerImpl implements AppStateTracker {
* Called by device idle controller to update the power save exemption lists.
*/
public void setPowerSaveExemptionListAppIds(
+ int[] powerSaveExemptionListSystemAppIdArray,
int[] powerSaveExemptionListExceptIdleAppIdArray,
int[] powerSaveExemptionListUserAppIdArray,
int[] tempExemptionListAppIdArray) {
@@ -1082,6 +1089,7 @@ public class AppStateTrackerImpl implements AppStateTracker {
final int[] previousExemptionList = mPowerExemptAllAppIds;
final int[] previousTempExemptionList = mTempExemptAppIds;
+ mPowerExemptSystemAppIds = powerSaveExemptionListSystemAppIdArray;
mPowerExemptAllAppIds = powerSaveExemptionListExceptIdleAppIdArray;
mTempExemptAppIds = tempExemptionListAppIdArray;
mPowerExemptUserAppIds = powerSaveExemptionListUserAppIdArray;
@@ -1302,6 +1310,18 @@ public class AppStateTrackerImpl implements AppStateTracker {
}
/**
+ * @return whether or not a UID is in either the user defined power-save exemption list or the
+ system full exemption list (not including except-idle)
+ */
+ public boolean isUidPowerSaveIdleExempt(int uid) {
+ final int appId = UserHandle.getAppId(uid);
+ synchronized (mLock) {
+ return ArrayUtils.contains(mPowerExemptUserAppIds, appId)
+ || ArrayUtils.contains(mPowerExemptSystemAppIds, appId);
+ }
+ }
+
+ /**
* @return whether a UID is in the temp power-save exemption list or not.
*
* Note clients normally shouldn't need to access it. It's only for dumpsys.
@@ -1338,6 +1358,9 @@ public class AppStateTrackerImpl implements AppStateTracker {
pw.print("Active uids: ");
dumpUids(pw, mActiveUids);
+ pw.print("System exemption list appids: ");
+ pw.println(Arrays.toString(mPowerExemptSystemAppIds));
+
pw.print("Except-idle + user exemption list appids: ");
pw.println(Arrays.toString(mPowerExemptAllAppIds));
@@ -1415,6 +1438,10 @@ public class AppStateTrackerImpl implements AppStateTracker {
}
}
+ for (int appId : mPowerExemptSystemAppIds) {
+ proto.write(AppStateTrackerProto.POWER_SAVE_SYSTEM_EXEMPT_APP_IDS, appId);
+ }
+
for (int appId : mPowerExemptAllAppIds) {
proto.write(AppStateTrackerProto.POWER_SAVE_EXEMPT_APP_IDS, appId);
}
diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
index 40d1b4c9b267..40a51bd3470a 100644
--- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
+++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
@@ -563,6 +563,12 @@ public class DeviceIdleController extends SystemService
private final SparseBooleanArray mPowerSaveWhitelistSystemAppIds = new SparseBooleanArray();
/**
+ * Current system app IDs that are in the complete power save white list. This array can
+ * be shared with others because it will not be modified once set.
+ */
+ private int[] mPowerSaveWhitelistSystemAppIdArray = new int[0];
+
+ /**
* App IDs that have been white-listed to opt out of power save restrictions, except
* for device idle modes.
*/
@@ -2089,6 +2095,11 @@ public class DeviceIdleController extends SystemService
return DeviceIdleController.this.isAppOnWhitelistInternal(appid);
}
+ @Override
+ public int[] getPowerSaveWhitelistSystemAppIds() {
+ return DeviceIdleController.this.getPowerSaveSystemWhitelistAppIds();
+ }
+
/**
* Returns the array of app ids whitelisted by user. Take care not to
* modify this, as it is a reference to the original copy. But the reference
@@ -2271,6 +2282,12 @@ public class DeviceIdleController extends SystemService
}
}
+ int[] getPowerSaveSystemWhitelistAppIds() {
+ synchronized (this) {
+ return mPowerSaveWhitelistSystemAppIdArray;
+ }
+ }
+
int[] getPowerSaveWhitelistUserAppIds() {
synchronized (this) {
return mPowerSaveWhitelistUserAppIdArray;
@@ -2281,6 +2298,16 @@ public class DeviceIdleController extends SystemService
return new File(Environment.getDataDirectory(), "system");
}
+ /** Returns the keys of a SparseBooleanArray, paying no attention to its values. */
+ private static int[] keysToIntArray(final SparseBooleanArray sparseArray) {
+ final int size = sparseArray.size();
+ final int[] array = new int[size];
+ for (int i = 0; i < size; i++) {
+ array[i] = sparseArray.keyAt(i);
+ }
+ return array;
+ }
+
@Override
public void onStart() {
final PackageManager pm = getContext().getPackageManager();
@@ -2317,6 +2344,7 @@ public class DeviceIdleController extends SystemService
} catch (PackageManager.NameNotFoundException e) {
}
}
+ mPowerSaveWhitelistSystemAppIdArray = keysToIntArray(mPowerSaveWhitelistSystemAppIds);
mConstants = mInjector.getConstants(this);
@@ -4222,6 +4250,7 @@ public class DeviceIdleController extends SystemService
private void passWhiteListsToForceAppStandbyTrackerLocked() {
mAppStateTracker.setPowerSaveExemptionListAppIds(
+ mPowerSaveWhitelistSystemAppIdArray,
mPowerSaveWhitelistExceptIdleAppIdArray,
mPowerSaveWhitelistUserAppIdArray,
mTempWhitelistAppIdArray);
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
index 37ce0d29d0e1..a65e86d888de 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -2861,7 +2861,7 @@ public class AlarmManagerService extends SystemService {
} else if (workSource == null && (UserHandle.isCore(callingUid)
|| UserHandle.isSameApp(callingUid, mSystemUiUid)
|| ((mAppStateTracker != null)
- && mAppStateTracker.isUidPowerSaveUserExempt(callingUid)))) {
+ && mAppStateTracker.isUidPowerSaveIdleExempt(callingUid)))) {
flags |= FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED;
flags &= ~(FLAG_ALLOW_WHILE_IDLE | FLAG_PRIORITIZE);
}
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/DeviceIdleJobsController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/DeviceIdleJobsController.java
index abbe177c5d49..01f0b30cc48a 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/DeviceIdleJobsController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/DeviceIdleJobsController.java
@@ -74,6 +74,7 @@ public final class DeviceIdleJobsController extends StateController {
* True when in device idle mode, so we don't want to schedule any jobs.
*/
private boolean mDeviceIdleMode;
+ private int[] mPowerSaveWhitelistSystemAppIds;
private int[] mDeviceIdleWhitelistAppIds;
private int[] mPowerSaveTempWhitelistAppIds;
@@ -133,6 +134,8 @@ public final class DeviceIdleJobsController extends StateController {
mLocalDeviceIdleController =
LocalServices.getService(DeviceIdleInternal.class);
mDeviceIdleWhitelistAppIds = mLocalDeviceIdleController.getPowerSaveWhitelistUserAppIds();
+ mPowerSaveWhitelistSystemAppIds =
+ mLocalDeviceIdleController.getPowerSaveWhitelistSystemAppIds();
mPowerSaveTempWhitelistAppIds =
mLocalDeviceIdleController.getPowerSaveTempWhitelistAppIds();
mDeviceIdleUpdateFunctor = new DeviceIdleUpdateFunctor();
@@ -196,8 +199,9 @@ public final class DeviceIdleJobsController extends StateController {
* Checks if the given job's scheduling app id exists in the device idle user whitelist.
*/
boolean isWhitelistedLocked(JobStatus job) {
- return Arrays.binarySearch(mDeviceIdleWhitelistAppIds,
- UserHandle.getAppId(job.getSourceUid())) >= 0;
+ final int appId = UserHandle.getAppId(job.getSourceUid());
+ return Arrays.binarySearch(mDeviceIdleWhitelistAppIds, appId) >= 0
+ || Arrays.binarySearch(mPowerSaveWhitelistSystemAppIds, appId) >= 0;
}
/**
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java
index 3c0a724b9ff7..5bde079d085e 100644
--- a/core/java/android/app/StatusBarManager.java
+++ b/core/java/android/app/StatusBarManager.java
@@ -231,6 +231,8 @@ public class StatusBarManager {
public static final int CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER = 2;
/** @hide */
public static final int CAMERA_LAUNCH_SOURCE_QUICK_AFFORDANCE = 3;
+ /** @hide */
+ public static final int CAMERA_LAUNCH_SOURCE_SCREEN_GESTURE = 4;
/**
* Session flag for {@link #registerSessionListener} indicating the listener
diff --git a/core/java/android/app/admin/SystemUpdateInfo.java b/core/java/android/app/admin/SystemUpdateInfo.java
index b88bf76c96ca..fdf2b3f54311 100644
--- a/core/java/android/app/admin/SystemUpdateInfo.java
+++ b/core/java/android/app/admin/SystemUpdateInfo.java
@@ -132,7 +132,7 @@ public final class SystemUpdateInfo implements Parcelable {
out.startTag(null, tag);
out.attributeLong(null, ATTR_RECEIVED_TIME, mReceivedTime);
out.attributeInt(null, ATTR_SECURITY_PATCH_STATE, mSecurityPatchState);
- out.attribute(null, ATTR_ORIGINAL_BUILD , Build.FINGERPRINT);
+ out.attribute(null, ATTR_ORIGINAL_BUILD , Build.VERSION.INCREMENTAL);
out.endTag(null, tag);
}
@@ -141,7 +141,7 @@ public final class SystemUpdateInfo implements Parcelable {
public static SystemUpdateInfo readFromXml(TypedXmlPullParser parser) {
// If an OTA has been applied (build fingerprint has changed), discard stale info.
final String buildFingerprint = parser.getAttributeValue(null, ATTR_ORIGINAL_BUILD );
- if (!Build.FINGERPRINT.equals(buildFingerprint)) {
+ if (!Build.VERSION.INCREMENTAL.equals(buildFingerprint)) {
return null;
}
try {
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 336bd4b60b59..149659f858b6 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -5091,6 +5091,15 @@ public class Intent implements Parcelable, Cloneable {
public static final String ACTION_SHOW_FOREGROUND_SERVICE_MANAGER =
"android.intent.action.SHOW_FOREGROUND_SERVICE_MANAGER";
+ /**
+ * Broadcast action: notify the system that the user has performed a gesture on the screen
+ * to launch the camera. Broadcast should be protected to receivers holding the
+ * {@link Manifest.permission#STATUS_BAR_SERVICE} permission.
+ * @hide
+ */
+ public static final String ACTION_SCREEN_CAMERA_GESTURE =
+ "android.intent.action.SCREEN_CAMERA_GESTURE";
+
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// Standard intent categories (see addCategory()).
diff --git a/core/java/android/os/BatteryManager.java b/core/java/android/os/BatteryManager.java
index 76f857bd91b7..f0b251f66022 100644
--- a/core/java/android/os/BatteryManager.java
+++ b/core/java/android/os/BatteryManager.java
@@ -163,6 +163,13 @@ public class BatteryManager {
@SystemApi
public static final String EXTRA_EVENT_TIMESTAMP = "android.os.extra.EVENT_TIMESTAMP";
+ /**
+ * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+ * boolean value to indicate OEM fast charging
+ * {@hide}
+ */
+ public static final String EXTRA_OEM_FAST_CHARGER = "oem_fast_charger";
+
// values for "status" field in the ACTION_BATTERY_CHANGED Intent
public static final int BATTERY_STATUS_UNKNOWN = Constants.BATTERY_STATUS_UNKNOWN;
public static final int BATTERY_STATUS_CHARGING = Constants.BATTERY_STATUS_CHARGING;
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index edfcb3d6f12a..0621ebc9d942 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -1299,11 +1299,13 @@ public final class FileUtils {
public static long roundStorageSize(long size) {
long val = 1;
long pow = 1;
- while ((val * pow) < size) {
+ long pow1024 = 1;
+ while ((val * pow1024) < size) {
val <<= 1;
if (val > 512) {
val = 1;
pow *= 1000;
+ pow1024 *= 1024;
}
}
return val * pow;
diff --git a/core/java/android/os/Trace.java b/core/java/android/os/Trace.java
index ac2156e9e46e..580e632b8d96 100644
--- a/core/java/android/os/Trace.java
+++ b/core/java/android/os/Trace.java
@@ -160,6 +160,10 @@ public final class Trace {
@UnsupportedAppUsage
@SystemApi(client = MODULE_LIBRARIES)
public static boolean isTagEnabled(long traceTag) {
+ if (!Build.IS_DEBUGGABLE) {
+ return false;
+ }
+
long tags = nativeGetEnabledTags();
return (tags & traceTag) != 0;
}
diff --git a/core/java/android/os/UpdateEngine.java b/core/java/android/os/UpdateEngine.java
index b7e3068a437c..16bb78e345ba 100644
--- a/core/java/android/os/UpdateEngine.java
+++ b/core/java/android/os/UpdateEngine.java
@@ -462,6 +462,17 @@ public class UpdateEngine {
}
/**
+ * @hide
+ */
+ public void setPerformanceMode(boolean enable) {
+ try {
+ mUpdateEngine.setPerformanceMode(enable);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Unbinds the last bound callback function.
*/
public boolean unbind() {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index d107972f909f..7e99af2ce4f1 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -5155,6 +5155,12 @@ public final class Settings {
public static final String ANIMATOR_DURATION_SCALE = Global.ANIMATOR_DURATION_SCALE;
/**
+ * Whether or not to vibrate when a touchscreen gesture is detected
+ * @hide
+ */
+ public static final String TOUCHSCREEN_GESTURE_HAPTIC_FEEDBACK = "touchscreen_gesture_haptic_feedback";
+
+ /**
* Control whether the accelerometer will be used to change screen
* orientation. If 0, it will not be used unless explicitly requested
* by the application; if 1, it will be used by default unless explicitly
@@ -5517,6 +5523,12 @@ public final class Settings {
public static final String DESKTOP_MODE = "desktop_mode";
/**
+ * Enable statusbar double tap gesture to put device to sleep
+ * @hide
+ */
+ public static final String DOUBLE_TAP_SLEEP_GESTURE = "double_tap_sleep_gesture";
+
+ /**
* IMPORTANT: If you add a new public settings you also have to add it to
* PUBLIC_SETTINGS below. If the new setting is hidden you have to add
* it to PRIVATE_SETTINGS below. Also add a validator that can validate
@@ -11115,6 +11127,12 @@ public final class Settings {
public static void setLocationProviderEnabled(ContentResolver cr,
String provider, boolean enabled) {
}
+
+ /**
+ * Whether to show swipe up hint in gestural nav mode
+ * @hide
+ */
+ public static final String NAVIGATION_BAR_HINT = "navigation_bar_hint";
}
/**
diff --git a/core/java/android/security/net/config/PinSet.java b/core/java/android/security/net/config/PinSet.java
index d3c975eb3101..e1942e513510 100644
--- a/core/java/android/security/net/config/PinSet.java
+++ b/core/java/android/security/net/config/PinSet.java
@@ -19,6 +19,7 @@ package android.security.net.config;
import android.util.ArraySet;
import java.util.Collections;
import java.util.Set;
+import java.util.stream.Collectors;
/** @hide */
public final class PinSet {
@@ -26,6 +27,7 @@ public final class PinSet {
new PinSet(Collections.<Pin>emptySet(), Long.MAX_VALUE);
public final long expirationTime;
public final Set<Pin> pins;
+ private final Set<String> algorithms;
public PinSet(Set<Pin> pins, long expirationTime) {
if (pins == null) {
@@ -33,14 +35,12 @@ public final class PinSet {
}
this.pins = pins;
this.expirationTime = expirationTime;
+ this.algorithms = pins.stream()
+ .map(pin -> pin.digestAlgorithm)
+ .collect(Collectors.toCollection(ArraySet::new));
}
Set<String> getPinAlgorithms() {
- // TODO: Cache this.
- Set<String> algorithms = new ArraySet<String>();
- for (Pin pin : pins) {
- algorithms.add(pin.digestAlgorithm);
- }
return algorithms;
}
}
diff --git a/core/java/android/text/style/TextAppearanceSpan.java b/core/java/android/text/style/TextAppearanceSpan.java
index adb379a397b7..0987142e3973 100644
--- a/core/java/android/text/style/TextAppearanceSpan.java
+++ b/core/java/android/text/style/TextAppearanceSpan.java
@@ -29,6 +29,8 @@ import android.text.ParcelableSpan;
import android.text.TextPaint;
import android.text.TextUtils;
+import com.android.internal.graphics.fonts.DynamicMetrics;
+
/**
* Sets the text appearance using the given
* {@link android.R.styleable#TextAppearance TextAppearance} attributes.
@@ -487,17 +489,17 @@ public class TextAppearanceSpan extends MetricAffectingSpan implements Parcelabl
styledTypeface = null;
}
+ Typeface finalTypeface = null;
if (styledTypeface != null) {
- final Typeface readyTypeface;
if (mTextFontWeight >= 0) {
final int weight = Math.min(FontStyle.FONT_WEIGHT_MAX, mTextFontWeight);
final boolean italic = (style & Typeface.ITALIC) != 0;
- readyTypeface = ds.setTypeface(Typeface.create(styledTypeface, weight, italic));
+ finalTypeface = ds.setTypeface(Typeface.create(styledTypeface, weight, italic));
} else {
- readyTypeface = styledTypeface;
+ finalTypeface = styledTypeface;
}
- int fake = style & ~readyTypeface.getStyle();
+ int fake = style & ~finalTypeface.getStyle();
if ((fake & Typeface.BOLD) != 0) {
ds.setFakeBoldText(true);
@@ -507,7 +509,7 @@ public class TextAppearanceSpan extends MetricAffectingSpan implements Parcelabl
ds.setTextSkewX(-0.25f);
}
- ds.setTypeface(readyTypeface);
+ ds.setTypeface(finalTypeface);
}
if (mTextSize > 0) {
@@ -526,6 +528,12 @@ public class TextAppearanceSpan extends MetricAffectingSpan implements Parcelabl
ds.setLetterSpacing(mLetterSpacing);
}
+ if ((!mHasLetterSpacing || mLetterSpacing == 0.0f) &&
+ mTextSize > 0 && finalTypeface != null &&
+ finalTypeface.isSystemFont()) {
+ ds.setLetterSpacing(DynamicMetrics.calcTracking(mTextSize));
+ }
+
if (mFontFeatureSettings != null) {
ds.setFontFeatureSettings(mFontFeatureSettings);
}
diff --git a/core/java/android/util/BoostFramework.java b/core/java/android/util/BoostFramework.java
index 7bab65a86802..b5a740c501ab 100644
--- a/core/java/android/util/BoostFramework.java
+++ b/core/java/android/util/BoostFramework.java
@@ -68,7 +68,6 @@ public class BoostFramework {
private static Method sperfHintAcqRelFunc = null;
private static Method sperfHintRenewFunc = null;
private static Method sPerfEventFunc = null;
- private static Method sPerfGetPerfHalVerFunc = null;
private static Method sPerfSyncRequest = null;
private static Method sIOPStart = null;
@@ -287,15 +286,6 @@ public class BoostFramework {
sperfHintRenewFunc = sPerfClass.getMethod("perfHintRenew", argClasses);
try {
- argClasses = new Class[] {};
- sPerfGetPerfHalVerFunc = sPerfClass.getMethod("perfGetHalVer", argClasses);
-
- } catch (Exception e) {
- Log.i(TAG, "BoostFramework() : Exception_1 = perfGetHalVer not supported");
- sPerfGetPerfHalVerFunc = null;
- }
-
- try {
argClasses = new Class[] {int.class, int.class, String.class, int.class, String.class};
sUXEngineEvents = sPerfClass.getDeclaredMethod("perfUXEngine_events",
argClasses);
@@ -398,14 +388,6 @@ public class BoostFramework {
/** @hide */
public double getPerfHalVersion() {
double retVal = PERF_HAL_V22;
- try {
- if (sPerfGetPerfHalVerFunc != null) {
- Object ret = sPerfGetPerfHalVerFunc.invoke(mPerf);
- retVal = (double)ret;
- }
- } catch(Exception e) {
- Log.e(TAG,"Exception " + e);
- }
return retVal;
}
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 7010350005b6..a2c992e3f4d5 100755
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -689,6 +689,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
private int mMinimumVelocity;
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 124051740)
private int mMaximumVelocity;
+ private int mDecacheThreshold;
private float mVelocityScale = 1.0f;
final boolean[] mIsScrap = new boolean[1];
@@ -1017,6 +1018,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
+ mDecacheThreshold = mMaximumVelocity / 2;
mOverscrollDistance = configuration.getScaledOverscrollDistance();
mOverflingDistance = configuration.getScaledOverflingDistance();
@@ -4889,7 +4891,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
// Keep the fling alive a little longer
postDelayed(this, FLYWHEEL_TIMEOUT);
} else {
- endFling();
+ endFling(false); // Don't disable the scrolling cache right after it was enabled
mTouchMode = TOUCH_MODE_SCROLL;
reportScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
}
@@ -4905,6 +4907,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
// Use AbsListView#fling(int) instead
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
void start(int initialVelocity) {
+ if (Math.abs(initialVelocity) > mDecacheThreshold) {
+ // For long flings, scrolling cache causes stutter, so don't use it
+ clearScrollingCache();
+ }
+
int initialY = initialVelocity < 0 ? Integer.MAX_VALUE : 0;
mLastFlingY = initialY;
mScroller.setInterpolator(null);
@@ -4985,6 +4992,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
// To interrupt a fling early you should use smoothScrollBy(0,0) instead
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
void endFling() {
+ endFling(true);
+ }
+
+ void endFling(boolean clearCache) {
mTouchMode = TOUCH_MODE_REST;
removeCallbacks(this);
@@ -4993,7 +5004,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
if (!mSuppressIdleStateChangeCall) {
reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
}
- clearScrollingCache();
+ if (clearCache)
+ clearScrollingCache();
mScroller.abortAnimation();
if (mFlingStrictSpan != null) {
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 7d59d26b5121..1c4a770b0a7a 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -206,6 +206,7 @@ import android.widget.RemoteViews.RemoteView;
import com.android.internal.accessibility.util.AccessibilityUtils;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.graphics.fonts.DynamicMetrics;
import com.android.internal.inputmethod.EditableInputConnection;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -4270,6 +4271,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
setLetterSpacing(attributes.mLetterSpacing);
}
+ if ((!attributes.mHasLetterSpacing || attributes.mLetterSpacing == 0.0f) &&
+ DynamicMetrics.shouldModifyFont(mTextPaint.getTypeface())) {
+ setLetterSpacing(DynamicMetrics.calcTracking(mTextPaint.getTextSize()));
+ }
+
if (attributes.mFontFeatureSettings != null) {
setFontFeatureSettings(attributes.mFontFeatureSettings);
}
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 09c1efb2c638..6d7f5d6cd5f4 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -1416,15 +1416,18 @@ public class ChooserActivity extends ResolverActivity implements
final ViewGroup actionRow =
(ViewGroup) contentPreviewLayout.findViewById(R.id.chooser_action_row);
+ String action = targetIntent.getAction();
+
//TODO: addActionButton(actionRow, createCopyButton());
if (shouldNearbyShareBeIncludedAsActionButton()) {
addActionButton(actionRow, createNearbyButton(targetIntent));
}
- addActionButton(actionRow, createEditButton(targetIntent));
+ if (!Intent.ACTION_SEND_MULTIPLE.equals(action)) {
+ addActionButton(actionRow, createEditButton(targetIntent));
+ }
mPreviewCoord = new ContentPreviewCoordinator(contentPreviewLayout, false);
- String action = targetIntent.getAction();
if (Intent.ACTION_SEND.equals(action)) {
Uri uri = targetIntent.getParcelableExtra(Intent.EXTRA_STREAM, android.net.Uri.class);
if (!validForContentPreview(uri)) {
diff --git a/core/java/com/android/internal/graphics/fonts/DynamicMetrics.java b/core/java/com/android/internal/graphics/fonts/DynamicMetrics.java
new file mode 100644
index 000000000000..5d723fd5f364
--- /dev/null
+++ b/core/java/com/android/internal/graphics/fonts/DynamicMetrics.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2022 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.graphics.fonts;
+
+import android.app.ActivityThread;
+import android.content.ComponentCallbacks;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.Typeface;
+
+public class DynamicMetrics {
+ // https://rsms.me/inter/dynmetrics/
+ private static final float A = -0.0223f;
+ private static final float B = 0.185f;
+ private static final float C = -0.1745f;
+
+ private static float sDensity = 0.0f;
+
+ // Precalculated tracking LUT up to 32 dp, in steps of 0.5 dp to minimize rounding errors.
+ // Sizes are close enough that we can cast them to ints for lookup.
+ // In most cases, we should never have to calculate tracking at runtime because of this.
+ private static final float[] TRACKING_LUT = {
+ /* 0.0dp */ 0.1627f,
+ /* 0.5dp */ 0.147242871675558f,
+ /* 1.0dp */ 0.1330772180324039f,
+ /* 1.5dp */ 0.12009513371985438f,
+ /* 2.0dp */ 0.10819772909994156f,
+ /* 2.5dp */ 0.09729437696617904f,
+ /* 3.0dp */ 0.08730202220051463f,
+ /* 3.5dp */ 0.0781445491098568f,
+ /* 4.0dp */ 0.06975220162292829f,
+ /* 4.5dp */ 0.062061051930857966f,
+ /* 5.0dp */ 0.055012513523938045f,
+ /* 5.5dp */ 0.04855289491515605f,
+ /* 6.0dp */ 0.04263299065103837f,
+ /* 6.5dp */ 0.03720770649437408f,
+ /* 7.0dp */ 0.032235715923688846f,
+ /* 7.5dp */ 0.027679145332890072f,
+ /* 8.0dp */ 0.02350328553312564f,
+ /* 8.5dp */ 0.019676327359252226f,
+ /* 9.0dp */ 0.016169119366923862f,
+ /* 9.5dp */ 0.012954945774584309f,
+ /* 10.0dp */ 0.010009322958860013f,
+ /* 10.5dp */ 0.007309812953179257f,
+ /* 11.0dp */ 0.004835852528962955f,
+ /* 11.5dp */ 0.002568596557431524f,
+ /* 12.0dp */ 0.0004907744588531701f,
+ /* 12.5dp */ -0.0014134413542490412f,
+ /* 13.0dp */ -0.0031585560420509667f,
+ /* 13.5dp */ -0.004757862828932768f,
+ /* 14.0dp */ -0.006223544263193034f,
+ /* 14.5dp */ -0.007566765016306747f,
+ /* 15.0dp */ -0.008797756928615424f,
+ /* 15.5dp */ -0.00992589694927596f,
+ /* 16.0dp */ -0.010959778564167369f,
+ /* 16.5dp */ -0.01190727725584982f,
+ /* 17.0dp */ -0.012775610494210232f,
+ /* 17.5dp */ -0.013571392714766779f,
+ /* 18.0dp */ -0.014300685703423587f,
+ /* 18.5dp */ -0.014969044771476151f,
+ /* 19.0dp */ -0.01558156107260065f,
+ /* 19.5dp */ -0.01614290038417221f,
+ /* 20.0dp */ -0.016657338648324763f,
+ /* 20.5dp */ -0.017128794543482675f,
+ /* 21.0dp */ -0.01756085933447426f,
+ /* 21.5dp */ -0.017956824228607303f,
+ /* 22.0dp */ -0.018319705446088512f,
+ /* 22.5dp */ -0.018652267195758174f,
+ /* 23.0dp */ -0.01895704273115516f,
+ /* 23.5dp */ -0.01923635364730468f,
+ /* 24.0dp */ -0.019492327565219923f,
+ /* 24.5dp */ -0.01972691433882746f,
+ /* 25.0dp */ -0.019941900907770843f,
+ /* 25.5dp */ -0.02013892490923212f,
+ /* 26.0dp */ -0.020319487152457818f,
+ /* 26.5dp */ -0.02048496305101277f,
+ /* 27.0dp */ -0.020636613099845737f,
+ /* 27.5dp */ -0.02077559247697482f,
+ /* 28.0dp */ -0.020902959842932358f,
+ /* 28.5dp */ -0.021019685404998267f,
+ /* 29.0dp */ -0.021126658307650148f,
+ /* 29.5dp */ -0.0212246934055262f,
+ /* 30.0dp */ -0.02131453747049323f,
+ /* 30.5dp */ -0.02139687488010142f,
+ /* 31.0dp */ -0.021472332830757092f,
+ /* 31.5dp */ -0.0215414861153242f,
+ /* 32.0dp */ -0.02160486150154747f,
+ };
+
+ private static final ComponentCallbacks callbacks = new ComponentCallbacks() {
+ @Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ sDensity = getDensity();
+ }
+
+ @Override
+ public void onLowMemory() {}
+ };
+
+ private DynamicMetrics() {}
+
+ public static float calcTracking(float sizePx) {
+ if (sDensity == 0.0f) {
+ Context context = ActivityThread.currentApplication();
+ if (context == null) {
+ return 0.0f;
+ }
+
+ sDensity = getDensity();
+ context.registerComponentCallbacks(callbacks);
+ }
+
+ // Pixels -> sp
+ float sizeDp = sizePx / sDensity;
+ int lutIndex = (int) (sizeDp * 2); // 0.5dp steps
+
+ // Precalculated lookup
+ if (lutIndex < TRACKING_LUT.length) {
+ return TRACKING_LUT[lutIndex];
+ }
+
+ return A + B * (float) Math.exp(C * sizeDp);
+ }
+
+ public static boolean shouldModifyFont(Typeface typeface) {
+ return typeface == null || typeface.isSystemFont();
+ }
+
+ private static float getDensity() {
+ Context context = ActivityThread.currentApplication();
+ if (context == null) {
+ return 1.0f;
+ }
+
+ return context.getResources().getDisplayMetrics().scaledDensity;
+ }
+}
diff --git a/core/java/com/android/internal/ice/hardware/HIDLHelper.java b/core/java/com/android/internal/ice/hardware/HIDLHelper.java
new file mode 100644
index 000000000000..a596c0e5e3da
--- /dev/null
+++ b/core/java/com/android/internal/ice/hardware/HIDLHelper.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2019 The LineageOS 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.ice.hardware;
+
+import android.util.Range;
+
+import java.util.ArrayList;
+
+class HIDLHelper {
+
+ static TouchscreenGesture[] fromHIDLGestures(
+ ArrayList<vendor.lineage.touch.V1_0.Gesture> gestures) {
+ int size = gestures.size();
+ TouchscreenGesture[] r = new TouchscreenGesture[size];
+ for (int i = 0; i < size; i++) {
+ vendor.lineage.touch.V1_0.Gesture g = gestures.get(i);
+ r[i] = new TouchscreenGesture(g.id, g.name, g.keycode);
+ }
+ return r;
+ }
+
+ static vendor.lineage.touch.V1_0.Gesture toHIDLGesture(TouchscreenGesture gesture) {
+ vendor.lineage.touch.V1_0.Gesture g = new vendor.lineage.touch.V1_0.Gesture();
+ g.id = gesture.id;
+ g.name = gesture.name;
+ g.keycode = gesture.keycode;
+ return g;
+ }
+
+}
diff --git a/core/java/com/android/internal/ice/hardware/LineageHardwareManager.java b/core/java/com/android/internal/ice/hardware/LineageHardwareManager.java
new file mode 100644
index 000000000000..1c0797784183
--- /dev/null
+++ b/core/java/com/android/internal/ice/hardware/LineageHardwareManager.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2015-2016 The CyanogenMod Project
+ * 2017-2019 The LineageOS 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.ice.hardware;
+
+import android.content.Context;
+import android.hidl.base.V1_0.IBase;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.Range;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
+
+import com.android.internal.ice.hardware.HIDLHelper;
+
+import vendor.lineage.touch.V1_0.IGloveMode;
+import vendor.lineage.touch.V1_0.IKeyDisabler;
+import vendor.lineage.touch.V1_0.IStylusMode;
+import vendor.lineage.touch.V1_0.ITouchscreenGesture;
+
+import java.io.UnsupportedEncodingException;
+import java.lang.IllegalArgumentException;
+import java.lang.reflect.Field;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+/**
+ * Manages access to LineageOS hardware extensions
+ *
+ * <p>
+ * This manager requires the HARDWARE_ABSTRACTION_ACCESS permission.
+ * <p>
+ * To get the instance of this class, utilize LineageHardwareManager#getInstance(Context context)
+ */
+public final class LineageHardwareManager {
+ private static final String TAG = "LineageHardwareManager";
+
+ // The VisibleForTesting annotation is to ensure Proguard doesn't remove these
+ // fields, as they might be used via reflection. When the @Keep annotation in
+ // the support library is properly handled in the platform, we should change this.
+
+ /**
+ * High touch sensitivity for touch panels
+ */
+ @VisibleForTesting
+ public static final int FEATURE_HIGH_TOUCH_SENSITIVITY = 0x10;
+
+ /**
+ * Hardware navigation key disablement
+ */
+ @VisibleForTesting
+ public static final int FEATURE_KEY_DISABLE = 0x20;
+
+ /**
+ * Touchscreen hovering
+ */
+ @VisibleForTesting
+ public static final int FEATURE_TOUCH_HOVERING = 0x800;
+
+ /**
+ * Touchscreen gesture
+ */
+ @VisibleForTesting
+ public static final int FEATURE_TOUCHSCREEN_GESTURES = 0x80000;
+
+ private static final List<Integer> BOOLEAN_FEATURES = Arrays.asList(
+ FEATURE_HIGH_TOUCH_SENSITIVITY,
+ FEATURE_KEY_DISABLE,
+ FEATURE_TOUCH_HOVERING
+ );
+
+ private static LineageHardwareManager sLineageHardwareManagerInstance;
+
+ private Context mContext;
+
+ // HIDL hals
+ private HashMap<Integer, IBase> mHIDLMap = new HashMap<Integer, IBase>();
+
+ /**
+ * @hide to prevent subclassing from outside of the framework
+ */
+ private LineageHardwareManager(Context context) {
+ Context appContext = context.getApplicationContext();
+ if (appContext != null) {
+ mContext = appContext;
+ } else {
+ mContext = context;
+ }
+ }
+
+ /**
+ * Determine if a Lineage Hardware feature is supported on this device
+ *
+ * @param feature The Lineage Hardware feature to query
+ *
+ * @return true if the feature is supported, false otherwise.
+ */
+ public boolean isSupported(int feature) {
+ return isSupportedHIDL(feature);
+ }
+
+ private boolean isSupportedHIDL(int feature) {
+ if (!mHIDLMap.containsKey(feature)) {
+ mHIDLMap.put(feature, getHIDLService(feature));
+ }
+ return mHIDLMap.get(feature) != null;
+ }
+
+ private IBase getHIDLService(int feature) {
+ try {
+ switch (feature) {
+ case FEATURE_HIGH_TOUCH_SENSITIVITY:
+ return IGloveMode.getService(true);
+ case FEATURE_KEY_DISABLE:
+ return IKeyDisabler.getService(true);
+ case FEATURE_TOUCH_HOVERING:
+ return IStylusMode.getService(true);
+ case FEATURE_TOUCHSCREEN_GESTURES:
+ return ITouchscreenGesture.getService(true);
+ }
+ } catch (NoSuchElementException | RemoteException e) {
+ }
+ return null;
+ }
+
+ /**
+ * Get or create an instance of the {@link com.android.internal.custom.hardware.LineageHardwareManager}
+ * @param context
+ * @return {@link LineageHardwareManager}
+ */
+ public static LineageHardwareManager getInstance(Context context) {
+ if (sLineageHardwareManagerInstance == null) {
+ sLineageHardwareManagerInstance = new LineageHardwareManager(context);
+ }
+ return sLineageHardwareManagerInstance;
+ }
+
+ /**
+ * Determine if the given feature is enabled or disabled.
+ *
+ * Only used for features which have simple enable/disable controls.
+ *
+ * @param feature the Lineage Hardware feature to query
+ *
+ * @return true if the feature is enabled, false otherwise.
+ */
+ public boolean get(int feature) {
+ if (!BOOLEAN_FEATURES.contains(feature)) {
+ throw new IllegalArgumentException(feature + " is not a boolean");
+ }
+
+ try {
+ if (isSupportedHIDL(feature)) {
+ IBase obj = mHIDLMap.get(feature);
+ switch (feature) {
+ case FEATURE_HIGH_TOUCH_SENSITIVITY:
+ IGloveMode gloveMode = (IGloveMode) obj;
+ return gloveMode.isEnabled();
+ case FEATURE_KEY_DISABLE:
+ IKeyDisabler keyDisabler = (IKeyDisabler) obj;
+ return keyDisabler.isEnabled();
+ case FEATURE_TOUCH_HOVERING:
+ IStylusMode stylusMode = (IStylusMode) obj;
+ return stylusMode.isEnabled();
+ }
+ }
+ } catch (RemoteException e) {
+ }
+ return false;
+ }
+
+ /**
+ * Enable or disable the given feature
+ *
+ * Only used for features which have simple enable/disable controls.
+ *
+ * @param feature the Lineage Hardware feature to set
+ * @param enable true to enable, false to disale
+ *
+ * @return true if the feature is enabled, false otherwise.
+ */
+ public boolean set(int feature, boolean enable) {
+ if (!BOOLEAN_FEATURES.contains(feature)) {
+ throw new IllegalArgumentException(feature + " is not a boolean");
+ }
+
+ try {
+ if (isSupportedHIDL(feature)) {
+ IBase obj = mHIDLMap.get(feature);
+ switch (feature) {
+ case FEATURE_HIGH_TOUCH_SENSITIVITY:
+ IGloveMode gloveMode = (IGloveMode) obj;
+ return gloveMode.setEnabled(enable);
+ case FEATURE_KEY_DISABLE:
+ IKeyDisabler keyDisabler = (IKeyDisabler) obj;
+ return keyDisabler.setEnabled(enable);
+ case FEATURE_TOUCH_HOVERING:
+ IStylusMode stylusMode = (IStylusMode) obj;
+ return stylusMode.setEnabled(enable);
+ }
+ }
+ } catch (RemoteException e) {
+ }
+ return false;
+ }
+
+ /**
+ * @return a list of available touchscreen gestures on the devices
+ */
+ public TouchscreenGesture[] getTouchscreenGestures() {
+ try {
+ if (isSupportedHIDL(FEATURE_TOUCHSCREEN_GESTURES)) {
+ ITouchscreenGesture touchscreenGesture = (ITouchscreenGesture)
+ mHIDLMap.get(FEATURE_TOUCHSCREEN_GESTURES);
+ return HIDLHelper.fromHIDLGestures(touchscreenGesture.getSupportedGestures());
+ }
+ } catch (RemoteException e) {
+ }
+ return null;
+ }
+
+ /**
+ * @return true if setting the activation status was successful
+ */
+ public boolean setTouchscreenGestureEnabled(
+ TouchscreenGesture gesture, boolean state) {
+ try {
+ if (isSupportedHIDL(FEATURE_TOUCHSCREEN_GESTURES)) {
+ ITouchscreenGesture touchscreenGesture = (ITouchscreenGesture)
+ mHIDLMap.get(FEATURE_TOUCHSCREEN_GESTURES);
+ return touchscreenGesture.setGestureEnabled(
+ HIDLHelper.toHIDLGesture(gesture), state);
+ }
+ } catch (RemoteException e) {
+ }
+ return false;
+ }
+}
diff --git a/core/java/com/android/internal/ice/hardware/TouchscreenGesture.aidl b/core/java/com/android/internal/ice/hardware/TouchscreenGesture.aidl
new file mode 100644
index 000000000000..e922eee9a1b6
--- /dev/null
+++ b/core/java/com/android/internal/ice/hardware/TouchscreenGesture.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2016 The CyanogenMod Project
+ * 2017 The LineageOS 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.ice.hardware;
+
+parcelable TouchscreenGesture;
diff --git a/core/java/com/android/internal/ice/hardware/TouchscreenGesture.java b/core/java/com/android/internal/ice/hardware/TouchscreenGesture.java
new file mode 100644
index 000000000000..166dd3223d2c
--- /dev/null
+++ b/core/java/com/android/internal/ice/hardware/TouchscreenGesture.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2016 The CyanogenMod Project
+ * 2017 The LineageOS 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.ice.hardware;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Touchscreen gestures API
+ *
+ * A device may implement several touchscreen gestures for use while
+ * the display is turned off, such as drawing alphabets and shapes.
+ * These gestures can be interpreted by userspace to activate certain
+ * actions and launch certain apps, such as to skip music tracks,
+ * to turn on the flashlight, or to launch the camera app.
+ *
+ * This *should always* be supported by the hardware directly.
+ * A lot of recent touch controllers have a firmware option for this.
+ *
+ * This API provides support for enumerating the gestures
+ * supported by the touchscreen.
+ *
+ * A TouchscreenGesture is referenced by it's identifier and carries an
+ * associated name (up to the user to translate this value).
+ */
+public class TouchscreenGesture implements Parcelable {
+
+ public final int id;
+ public final String name;
+ public final int keycode;
+
+ public TouchscreenGesture(int id, String name, int keycode) {
+ this.id = id;
+ this.name = name;
+ this.keycode = keycode;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel parcel, int flags) {
+ parcel.writeInt(id);
+ parcel.writeString(name);
+ parcel.writeInt(keycode);
+ }
+
+ /** @hide */
+ public static final Parcelable.Creator<TouchscreenGesture> CREATOR =
+ new Parcelable.Creator<TouchscreenGesture>() {
+
+ public TouchscreenGesture createFromParcel(Parcel in) {
+ return new TouchscreenGesture(in.readInt(), in.readString(), in.readInt());
+ }
+
+ @Override
+ public TouchscreenGesture[] newArray(int size) {
+ return new TouchscreenGesture[size];
+ }
+ };
+}
diff --git a/core/java/com/android/internal/notification/SystemNotificationChannels.java b/core/java/com/android/internal/notification/SystemNotificationChannels.java
index 681b46a01c8d..89e6d1f50307 100644
--- a/core/java/com/android/internal/notification/SystemNotificationChannels.java
+++ b/core/java/com/android/internal/notification/SystemNotificationChannels.java
@@ -113,7 +113,7 @@ public class SystemNotificationChannels {
final NotificationChannel developerImportant = new NotificationChannel(
DEVELOPER_IMPORTANT,
context.getString(R.string.notification_channel_developer_important),
- NotificationManager.IMPORTANCE_HIGH);
+ NotificationManager.IMPORTANCE_MIN);
developer.setBlockable(true);
channelsList.add(developerImportant);
diff --git a/core/java/com/android/internal/os/DeviceKeyHandler.java b/core/java/com/android/internal/os/DeviceKeyHandler.java
new file mode 100644
index 000000000000..8902337f3ebb
--- /dev/null
+++ b/core/java/com/android/internal/os/DeviceKeyHandler.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2012 The CyanogenMod 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.os;
+
+import android.view.KeyEvent;
+
+public interface DeviceKeyHandler {
+
+ /**
+ * Invoked when an unknown key was detected by the system, letting the device handle
+ * this special keys prior to pass the key to the active app.
+ *
+ * @param event The key event to be handled
+ * @return null if event is consumed, KeyEvent to be handled otherwise
+ */
+ public KeyEvent handleKeyEvent(KeyEvent event);
+}
diff --git a/core/proto/android/server/appstatetracker.proto b/core/proto/android/server/appstatetracker.proto
index f5583d4f476f..0d0fb097d963 100644
--- a/core/proto/android/server/appstatetracker.proto
+++ b/core/proto/android/server/appstatetracker.proto
@@ -25,7 +25,7 @@ option java_multiple_files = true;
// Dump from com.android.server.AppStateTracker.
//
-// Next ID: 14
+// Next ID: 15
message AppStateTrackerProto {
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
@@ -41,6 +41,9 @@ message AppStateTrackerProto {
// UIDs currently in the foreground.
repeated int32 foreground_uids = 11;
+ // App ids that are in power-save system exemption list.
+ repeated int32 power_save_system_exempt_app_ids = 14;
+
// App ids that are in power-save exemption list.
repeated int32 power_save_exempt_app_ids = 3;
diff --git a/core/res/res/drawable/toast_frame.xml b/core/res/res/drawable/toast_frame.xml
index a8cdef6d05f1..34987394b2ec 100644
--- a/core/res/res/drawable/toast_frame.xml
+++ b/core/res/res/drawable/toast_frame.xml
@@ -17,7 +17,7 @@
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
- <solid android:color="?android:attr/colorSurface" />
+ <solid android:color="?android:attr/colorBackgroundFloating" />
<corners android:radius="28dp" />
</shape>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index ee8f3e5c2d25..b350a5dc49ab 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -856,11 +856,11 @@
<integer name="config_defaultNightDisplayCustomEndTime">21600000</integer>
<!-- Minimum color temperature, in Kelvin, supported by Night display. -->
- <integer name="config_nightDisplayColorTemperatureMin">2596</integer>
+ <integer name="config_nightDisplayColorTemperatureMin">1600</integer>
<!-- Default color temperature, in Kelvin, to tint the screen when Night display is
activated. -->
- <integer name="config_nightDisplayColorTemperatureDefault">2850</integer>
+ <integer name="config_nightDisplayColorTemperatureDefault">2650</integer>
<!-- Maximum color temperature, in Kelvin, supported by Night display. -->
<integer name="config_nightDisplayColorTemperatureMax">4082</integer>
diff --git a/core/res/res/values/ice_config.xml b/core/res/res/values/ice_config.xml
new file mode 100644
index 000000000000..6016dc84e9a2
--- /dev/null
+++ b/core/res/res/values/ice_config.xml
@@ -0,0 +1,51 @@
+<!--
+ Copyright (C) 2022 Project ICE
+
+ 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.
+-->
+<resources>
+ <!-- The list of components which should be automatically disabled for a specific device.
+ Note: this MUST not be used to randomly disable components, ask for approval first! -->
+ <string-array name="config_deviceDisabledComponents" translatable="false">
+ </string-array>
+
+ <!-- The list of components which should be automatically disabled for all devices. -->
+ <string-array name="config_globallyDisabledComponents" translatable="false">
+ </string-array>
+
+ <!-- The list of components which should be forced to be enabled. -->
+ <string-array name="config_forceEnabledComponents" translatable="false">
+ </string-array>
+
+ <!-- Paths to the libraries that contain device specific key handlers -->
+ <string-array name="config_deviceKeyHandlerLibs" translatable="false">
+ </string-array>
+
+ <!-- Names of the key handler classes -->
+ <string-array name="config_deviceKeyHandlerClasses" translatable="false">
+ </string-array>
+
+ <!-- Path to fast charging status file to detect whether an oem fast charger is active -->
+ <string name="config_oemFastChargerStatusPath" translatable="false"></string>
+
+ <!-- Expected value from fast charging status file -->
+ <string name="config_oemFastChargerStatusValue" translatable="false">1</string>
+
+ <!-- Whether device has an alert slider -->
+ <bool name="config_hasAlertSlider" translatable="false">false</bool>
+
+ <!-- The location of the device's alert slider:
+ 0: Left side
+ 1: Right side -->
+ <integer name="config_alertSliderLocation">0</integer>
+</resources>
diff --git a/core/res/res/values/ice_symbols.xml b/core/res/res/values/ice_symbols.xml
new file mode 100644
index 000000000000..394ebe9a115c
--- /dev/null
+++ b/core/res/res/values/ice_symbols.xml
@@ -0,0 +1,35 @@
+<!--
+ Copyright (C) 2022 Project ICE
+
+ 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.
+-->
+<resources>
+ <!-- Package Manager -->
+ <java-symbol type="array" name="config_deviceDisabledComponents" />
+ <java-symbol type="array" name="config_globallyDisabledComponents" />
+ <java-symbol type="array" name="config_forceEnabledComponents" />
+
+ <!-- Device keyhandlers -->
+ <java-symbol type="array" name="config_deviceKeyHandlerLibs" />
+ <java-symbol type="array" name="config_deviceKeyHandlerClasses" />
+
+ <!-- Path to fast charging status file to detect whether an oem fast charger is active -->
+ <java-symbol type="string" name="config_oemFastChargerStatusPath" />
+
+ <!-- Expected value from fast charging status file -->
+ <java-symbol type="string" name="config_oemFastChargerStatusValue" />
+
+ <!-- Alert Slider -->
+ <java-symbol type="bool" name="config_hasAlertSlider" />
+ <java-symbol type="integer" name="config_alertSliderLocation" />
+</resources>
diff --git a/data/fonts/Android.bp b/data/fonts/Android.bp
index f90a74d939f4..81716878df3a 100644
--- a/data/fonts/Android.bp
+++ b/data/fonts/Android.bp
@@ -30,16 +30,6 @@ license {
}
prebuilt_font {
- name: "DroidSansMono.ttf",
- src: "DroidSansMono.ttf",
- required: [
- // Roboto-Regular.ttf provides DroidSans.ttf as a symlink to itself
- // Roboto-Regular.ttf provides DroidSans-Bold.ttf as a symlink to itself
- "Roboto-Regular.ttf",
- ],
-}
-
-prebuilt_font {
name: "AndroidClock.ttf",
src: "AndroidClock.ttf",
}
diff --git a/data/fonts/fonts.xml b/data/fonts/fonts.xml
index f8c015f28a50..af451169e549 100644
--- a/data/fonts/fonts.xml
+++ b/data/fonts/fonts.xml
@@ -25,88 +25,92 @@
<!-- first font is default -->
<family name="sans-serif">
<font weight="100" style="normal">Roboto-Regular.ttf
- <axis tag="ital" stylevalue="0" />
+ <axis tag="slnt" stylevalue="0" />
<axis tag="wdth" stylevalue="100" />
<axis tag="wght" stylevalue="100" />
</font>
<font weight="200" style="normal">Roboto-Regular.ttf
- <axis tag="ital" stylevalue="0" />
+ <axis tag="slnt" stylevalue="0" />
<axis tag="wdth" stylevalue="100" />
<axis tag="wght" stylevalue="200" />
</font>
<font weight="300" style="normal">Roboto-Regular.ttf
- <axis tag="ital" stylevalue="0" />
+ <axis tag="slnt" stylevalue="0" />
<axis tag="wdth" stylevalue="100" />
<axis tag="wght" stylevalue="300" />
</font>
- <font weight="400" style="normal">RobotoStatic-Regular.ttf</font>
+ <font weight="400" style="normal">Roboto-Regular.ttf
+ <axis tag="slnt" stylevalue="0" />
+ <axis tag="wdth" stylevalue="100" />
+ <axis tag="wght" stylevalue="400" />
+ </font>
<font weight="500" style="normal">Roboto-Regular.ttf
- <axis tag="ital" stylevalue="0" />
+ <axis tag="slnt" stylevalue="0" />
<axis tag="wdth" stylevalue="100" />
<axis tag="wght" stylevalue="500" />
</font>
<font weight="600" style="normal">Roboto-Regular.ttf
- <axis tag="ital" stylevalue="0" />
+ <axis tag="slnt" stylevalue="0" />
<axis tag="wdth" stylevalue="100" />
<axis tag="wght" stylevalue="600" />
</font>
<font weight="700" style="normal">Roboto-Regular.ttf
- <axis tag="ital" stylevalue="0" />
+ <axis tag="slnt" stylevalue="0" />
<axis tag="wdth" stylevalue="100" />
<axis tag="wght" stylevalue="700" />
</font>
<font weight="800" style="normal">Roboto-Regular.ttf
- <axis tag="ital" stylevalue="0" />
+ <axis tag="slnt" stylevalue="0" />
<axis tag="wdth" stylevalue="100" />
<axis tag="wght" stylevalue="800" />
</font>
<font weight="900" style="normal">Roboto-Regular.ttf
- <axis tag="ital" stylevalue="0" />
+ <axis tag="slnt" stylevalue="0" />
<axis tag="wdth" stylevalue="100" />
<axis tag="wght" stylevalue="900" />
</font>
<font weight="100" style="italic">Roboto-Regular.ttf
- <axis tag="ital" stylevalue="1" />
+ <axis tag="slnt" stylevalue="-10" />
<axis tag="wdth" stylevalue="100" />
<axis tag="wght" stylevalue="100" />
</font>
<font weight="200" style="italic">Roboto-Regular.ttf
- <axis tag="ital" stylevalue="1" />
+ <axis tag="slnt" stylevalue="-10" />
<axis tag="wdth" stylevalue="100" />
<axis tag="wght" stylevalue="200" />
</font>
<font weight="300" style="italic">Roboto-Regular.ttf
- <axis tag="ital" stylevalue="1" />
+ <axis tag="slnt" stylevalue="-10" />
<axis tag="wdth" stylevalue="100" />
<axis tag="wght" stylevalue="300" />
</font>
<font weight="400" style="italic">Roboto-Regular.ttf
- <axis tag="ital" stylevalue="1" />
+ <axis tag="slnt" stylevalue="-10" />
<axis tag="wdth" stylevalue="100" />
<axis tag="wght" stylevalue="400" />
</font>
<font weight="500" style="italic">Roboto-Regular.ttf
- <axis tag="ital" stylevalue="1" />
+ <axis tag="slnt" stylevalue="-10" />
<axis tag="wdth" stylevalue="100" />
<axis tag="wght" stylevalue="500" />
</font>
<font weight="600" style="italic">Roboto-Regular.ttf
- <axis tag="ital" stylevalue="1" />
+ <axis tag="slnt" stylevalue="-10" />
<axis tag="wdth" stylevalue="100" />
<axis tag="wght" stylevalue="600" />
</font>
<font weight="700" style="italic">Roboto-Regular.ttf
- <axis tag="ital" stylevalue="1" />
+ <axis tag="slnt" stylevalue="-10" />
<axis tag="wdth" stylevalue="100" />
<axis tag="wght" stylevalue="700" />
</font>
<font weight="800" style="italic">Roboto-Regular.ttf
- <axis tag="ital" stylevalue="1" />
+ <axis tag="slnt" stylevalue="-10" />
<axis tag="wdth" stylevalue="100" />
<axis tag="wght" stylevalue="800" />
</font>
<font weight="900" style="italic">Roboto-Regular.ttf
- <axis tag="ital" stylevalue="1" />
+ <axis tag="slnt" stylevalue="-10" />
<axis tag="wdth" stylevalue="100" />
<axis tag="wght" stylevalue="900" />
</font>
@@ -271,6 +275,98 @@
<alias name="source-sans-pro-semi-bold" to="source-sans-pro" weight="600"/>
<!-- fallback fonts -->
+ <family>
+ <font weight="100" style="normal">RobotoFallback-VF.ttf
+ <axis tag="ital" stylevalue="0"/>
+ <axis tag="wdth" stylevalue="100"/>
+ <axis tag="wght" stylevalue="100"/>
+ </font>
+ <font weight="100" style="italic">RobotoFallback-VF.ttf
+ <axis tag="ital" stylevalue="1"/>
+ <axis tag="wdth" stylevalue="100"/>
+ <axis tag="wght" stylevalue="100"/>
+ </font>
+ <font weight="200" style="normal">RobotoFallback-VF.ttf
+ <axis tag="ital" stylevalue="0"/>
+ <axis tag="wdth" stylevalue="100"/>
+ <axis tag="wght" stylevalue="200"/>
+ </font>
+ <font weight="200" style="italic">RobotoFallback-VF.ttf
+ <axis tag="ital" stylevalue="1"/>
+ <axis tag="wdth" stylevalue="100"/>
+ <axis tag="wght" stylevalue="200"/>
+ </font>
+ <font weight="300" style="normal">RobotoFallback-VF.ttf
+ <axis tag="ital" stylevalue="0"/>
+ <axis tag="wdth" stylevalue="100"/>
+ <axis tag="wght" stylevalue="300"/>
+ </font>
+ <font weight="300" style="italic">RobotoFallback-VF.ttf
+ <axis tag="ital" stylevalue="1"/>
+ <axis tag="wdth" stylevalue="100"/>
+ <axis tag="wght" stylevalue="300"/>
+ </font>
+ <font weight="400" style="normal">RobotoFallback-VF.ttf
+ <axis tag="ital" stylevalue="0"/>
+ <axis tag="wdth" stylevalue="100"/>
+ <axis tag="wght" stylevalue="400"/>
+ </font>
+ <font weight="400" style="italic">RobotoFallback-VF.ttf
+ <axis tag="ital" stylevalue="1"/>
+ <axis tag="wdth" stylevalue="100"/>
+ <axis tag="wght" stylevalue="400"/>
+ </font>
+ <font weight="500" style="normal">RobotoFallback-VF.ttf
+ <axis tag="ital" stylevalue="0"/>
+ <axis tag="wdth" stylevalue="100"/>
+ <axis tag="wght" stylevalue="500"/>
+ </font>
+ <font weight="500" style="italic">RobotoFallback-VF.ttf
+ <axis tag="ital" stylevalue="1"/>
+ <axis tag="wdth" stylevalue="100"/>
+ <axis tag="wght" stylevalue="500"/>
+ </font>
+ <font weight="600" style="normal">RobotoFallback-VF.ttf
+ <axis tag="ital" stylevalue="0"/>
+ <axis tag="wdth" stylevalue="100"/>
+ <axis tag="wght" stylevalue="600"/>
+ </font>
+ <font weight="600" style="italic">RobotoFallback-VF.ttf
+ <axis tag="ital" stylevalue="1"/>
+ <axis tag="wdth" stylevalue="100"/>
+ <axis tag="wght" stylevalue="600"/>
+ </font>
+ <font weight="700" style="normal">RobotoFallback-VF.ttf
+ <axis tag="ital" stylevalue="0"/>
+ <axis tag="wdth" stylevalue="100"/>
+ <axis tag="wght" stylevalue="700"/>
+ </font>
+ <font weight="700" style="italic">RobotoFallback-VF.ttf
+ <axis tag="ital" stylevalue="1"/>
+ <axis tag="wdth" stylevalue="100"/>
+ <axis tag="wght" stylevalue="700"/>
+ </font>
+ <font weight="800" style="normal">RobotoFallback-VF.ttf
+ <axis tag="ital" stylevalue="0"/>
+ <axis tag="wdth" stylevalue="100"/>
+ <axis tag="wght" stylevalue="800"/>
+ </font>
+ <font weight="800" style="italic">RobotoFallback-VF.ttf
+ <axis tag="ital" stylevalue="1"/>
+ <axis tag="wdth" stylevalue="100"/>
+ <axis tag="wght" stylevalue="800"/>
+ </font>
+ <font weight="900" style="normal">RobotoFallback-VF.ttf
+ <axis tag="ital" stylevalue="0"/>
+ <axis tag="wdth" stylevalue="100"/>
+ <axis tag="wght" stylevalue="900"/>
+ </font>
+ <font weight="900" style="italic">RobotoFallback-VF.ttf
+ <axis tag="ital" stylevalue="1"/>
+ <axis tag="wdth" stylevalue="100"/>
+ <axis tag="wght" stylevalue="900"/>
+ </font>
+ </family>
<family lang="und-Arab" variant="elegant">
<font weight="400" style="normal" postScriptName="NotoNaskhArabic">
NotoNaskhArabic-Regular.ttf
diff --git a/data/keyboards/Generic.kcm b/data/keyboards/Generic.kcm
index fe6eeeb66e40..3c7178022261 100644
--- a/data/keyboards/Generic.kcm
+++ b/data/keyboards/Generic.kcm
@@ -498,7 +498,7 @@ key PLUS {
### Non-printing keys ###
key ESCAPE {
- base: none
+ base: fallback BACK
alt, meta: fallback HOME
ctrl: fallback MENU
}
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index f438a03b1434..6621d1f23166 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -260,7 +260,7 @@ public class Paint {
// These flags are always set on a new/reset paint, even if flags 0 is passed.
static final int HIDDEN_DEFAULT_PAINT_FLAGS = DEV_KERN_TEXT_FLAG | EMBEDDED_BITMAP_TEXT_FLAG
- | FILTER_BITMAP_FLAG;
+ | FILTER_BITMAP_FLAG | SUBPIXEL_TEXT_FLAG;
/**
* Font hinter option that disables font hinting.
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index a2f5301e353f..64ac679de31e 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -212,6 +212,8 @@ public class Typeface {
private @IntRange(from = 0, to = FontStyle.FONT_WEIGHT_MAX) final int mWeight;
+ private boolean mIsSystemDefault;
+
// Value for weight and italic. Indicates the value is resolved by font metadata.
// Must be the same as the C++ constant in core/jni/android/graphics/FontFamily.cpp
/** @hide */
@@ -237,6 +239,7 @@ public class Typeface {
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
private static void setDefault(Typeface t) {
+ t.mIsSystemDefault = true;
synchronized (SYSTEM_FONT_MAP_LOCK) {
sDefaultTypeface = t;
nativeSetDefault(t.native_instance);
@@ -933,7 +936,7 @@ public class Typeface {
}
}
- typeface = new Typeface(nativeCreateFromTypeface(ni, style));
+ typeface = new Typeface(nativeCreateFromTypeface(ni, style), family.mIsSystemDefault);
styles.put(style, typeface);
}
return typeface;
@@ -1001,7 +1004,8 @@ public class Typeface {
}
typeface = new Typeface(
- nativeCreateFromTypefaceWithExactStyle(base.native_instance, weight, italic));
+ nativeCreateFromTypefaceWithExactStyle(base.native_instance, weight, italic),
+ base.mIsSystemDefault);
innerCache.put(key, typeface);
}
return typeface;
@@ -1011,7 +1015,8 @@ public class Typeface {
public static Typeface createFromTypefaceWithVariation(@Nullable Typeface family,
@NonNull List<FontVariationAxis> axes) {
final Typeface base = family == null ? Typeface.DEFAULT : family;
- return new Typeface(nativeCreateFromTypefaceWithVariation(base.native_instance, axes));
+ return new Typeface(nativeCreateFromTypefaceWithVariation(base.native_instance, axes),
+ base.mIsSystemDefault);
}
/**
@@ -1174,6 +1179,12 @@ public class Typeface {
mCleaner = sRegistry.registerNativeAllocation(this, native_instance);
mStyle = nativeGetStyle(ni);
mWeight = nativeGetWeight(ni);
+ mIsSystemDefault = false;
+ }
+
+ private Typeface(long ni, boolean isSystemDefault) {
+ this(ni);
+ mIsSystemDefault = isSystemDefault;
}
private static Typeface getSystemDefaultTypeface(@NonNull String familyName) {
@@ -1189,6 +1200,7 @@ public class Typeface {
for (Map.Entry<String, FontFamily[]> entry : fallbacks.entrySet()) {
outSystemFontMap.put(entry.getKey(), createFromFamilies(entry.getValue()));
}
+ outSystemFontMap.get("sans-serif").mIsSystemDefault = true;
for (int i = 0; i < aliases.size(); ++i) {
final FontConfig.Alias alias = aliases.get(i);
@@ -1203,7 +1215,8 @@ public class Typeface {
}
final int weight = alias.getWeight();
final Typeface newFace = weight == 400 ? base :
- new Typeface(nativeCreateWeightAlias(base.native_instance, weight));
+ new Typeface(nativeCreateWeightAlias(base.native_instance, weight),
+ base.mIsSystemDefault);
outSystemFontMap.put(alias.getName(), newFace);
}
}
@@ -1230,6 +1243,7 @@ public class Typeface {
for (Map.Entry<String, Typeface> entry : fontMap.entrySet()) {
nativePtrs[i++] = entry.getValue().native_instance;
writeString(namesBytes, entry.getKey());
+ writeInt(namesBytes, entry.getValue().mIsSystemDefault ? 1 : 0);
}
int typefacesBytesCount = nativeWriteTypefaces(null, nativePtrs);
// int (typefacesBytesCount), typefaces, namesBytes
@@ -1271,7 +1285,8 @@ public class Typeface {
buffer.position(buffer.position() + typefacesBytesCount);
for (long nativePtr : nativePtrs) {
String name = readString(buffer);
- out.put(name, new Typeface(nativePtr));
+ boolean isSystemDefault = buffer.getInt() == 1;
+ out.put(name, new Typeface(nativePtr, isSystemDefault));
}
return nativePtrs;
}
@@ -1496,6 +1511,11 @@ public class Typeface {
return families;
}
+ /** @hide */
+ public boolean isSystemFont() {
+ return mIsSystemDefault;
+ }
+
private static native long nativeCreateFromTypeface(long native_instance, int style);
private static native long nativeCreateFromTypefaceWithExactStyle(
long native_instance, int weight, boolean italic);
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v31/styles.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v31/styles.xml
index d0b6c4d54bb1..737d6ac69d40 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v31/styles.xml
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/values-v31/styles.xml
@@ -19,10 +19,12 @@
<item name="android:fontFamily">@string/settingslib_config_headlineFontFamily</item>
<item name="android:textSize">20dp</item>
<item name="android:textColor">@color/settingslib_text_color_primary_device_default</item>
+ <item name="android:letterSpacing">-0.016657338648324763</item>
</style>
<style name="CollapsingToolbarTitle.Expanded" parent="CollapsingToolbarTitle.Collapsed">
<item name="android:textSize">36dp</item>
<item name="android:textColor">@color/settingslib_text_color_primary_device_default</item>
+ <item name="android:letterSpacing">-0.02195411335559237</item>
</style>
-</resources> \ No newline at end of file
+</resources>
diff --git a/packages/SettingsLib/res/drawable/ic_4g_plus_mobiledata.xml b/packages/SettingsLib/res/drawable/ic_4g_plus_mobiledata.xml
index 1d048ae44049..1272ea7a30e1 100644
--- a/packages/SettingsLib/res/drawable/ic_4g_plus_mobiledata.xml
+++ b/packages/SettingsLib/res/drawable/ic_4g_plus_mobiledata.xml
@@ -14,20 +14,17 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="19.41dp"
- android:height="15dp"
- android:viewportWidth="22"
- android:viewportHeight="17">
-
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M5.32,10.13h1.11v1.03H5.32v2.31H4.11v-2.31H0.35v-0.75l3.7-6.9h1.27V10.13z M1.69,10.13h2.42V5.4L1.69,10.13z" />
+ android:width="27dp"
+ android:height="16dp"
+ android:viewportWidth="27.0"
+ android:viewportHeight="16.0">
<path
- android:fillColor="#FFFFFFFF"
- android:pathData="M14.15,12.24l-0.22,0.27c-0.63,0.73-1.55,1.1-2.76,1.1c-1.08,0-1.92-0.36-2.53-1.07c-0.61-0.71-0.93-1.72-0.94-3.02V7.56 c0-1.39,0.28-2.44,0.84-3.13s1.39-1.04,2.51-1.04c0.95,0,1.69,0.26,2.23,0.79s0.83,1.28,0.89,2.26H12.9 c-0.05-0.62-0.22-1.1-0.52-1.45s-0.74-0.52-1.34-0.52c-0.72,0-1.24,0.23-1.57,0.7S8.97,6.37,8.96,7.4v2.03 c0,1,0.19,1.77,0.57,2.31c0.38,0.54,0.93,0.8,1.65,0.8c0.67,0,1.19-0.16,1.54-0.49l0.18-0.17V9.59h-1.82V8.52h3.07V12.24z" />
+ android:fillColor="#FF000000"
+ android:pathData="M2,10.98V9.81l4.28,-6.83h1.6v6.59h1.19v1.41H7.88V13H6.4v-2.02H2zM3.68,9.57H6.4V5.33H6.31L3.68,9.57z"/>
<path
- android:fillColor="#FFFFFFFF"
- android:pathData="M 19.3 5.74 L 19.3 3.39 L 18 3.39 L 18 5.74 L 15.65 5.74 L 15.65 7.04 L 18 7.04 L 18 9.39 L 19.3 9.39 L 19.3 7.04 L 21.65 7.04 L 21.65 5.74 Z" />
+ android:fillColor="#FF000000"
+ android:pathData="M15,13.22c-0.88,0 -1.66,-0.21 -2.34,-0.64c-0.67,-0.44 -1.2,-1.05 -1.6,-1.83c-0.38,-0.79 -0.57,-1.71 -0.57,-2.76c0,-1.05 0.21,-1.96 0.62,-2.74c0.41,-0.79 0.97,-1.4 1.67,-1.83c0.7,-0.44 1.5,-0.66 2.39,-0.66c1.09,0 2.01,0.25 2.74,0.76c0.75,0.5 1.22,1.21 1.41,2.11l-1.47,0.39c-0.17,-0.56 -0.48,-1 -0.94,-1.32c-0.45,-0.33 -1.03,-0.49 -1.75,-0.49c-0.57,0 -1.09,0.14 -1.57,0.43c-0.48,0.29 -0.85,0.71 -1.13,1.27c-0.28,0.56 -0.42,1.25 -0.42,2.07c0,0.81 0.14,1.5 0.41,2.07c0.28,0.56 0.65,0.98 1.11,1.27c0.47,0.29 0.98,0.43 1.54,0.43c0.57,0 1.06,-0.11 1.47,-0.34c0.42,-0.23 0.75,-0.55 0.99,-0.94c0.25,-0.4 0.41,-0.85 0.46,-1.36h-2.88V7.79h4.37c0,0.87 0,1.74 0,2.6c0,0.87 0,1.74 0,2.6h-1.41v-1.4h-0.08c-0.28,0.49 -0.67,0.88 -1.18,1.18C16.34,13.07 15.73,13.22 15,13.22z"/>
<path
- android:pathData="M 0 0 H 22 V 17 H 0 V 0 Z" />
+ android:fillColor="#FF000000"
+ android:pathData="M24.62 5.24 24.62 2.89 23.32 2.89 23.32 5.24 20.97 5.24 20.97 6.54 23.32 6.54 23.32 8.89 24.62 8.89 24.62 6.54 26.97 6.54 26.97 5.24Z"/>
</vector>
diff --git a/packages/SettingsLib/res/drawable/ic_lte_plus_mobiledata.xml b/packages/SettingsLib/res/drawable/ic_lte_plus_mobiledata.xml
index e5cdff33fe98..d1f4b6fd818b 100644
--- a/packages/SettingsLib/res/drawable/ic_lte_plus_mobiledata.xml
+++ b/packages/SettingsLib/res/drawable/ic_lte_plus_mobiledata.xml
@@ -14,23 +14,20 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="22.94dp"
- android:height="15dp"
- android:viewportWidth="26"
- android:viewportHeight="17">
-
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M1.59,12.4h3.9v1.07H0.33V3.52h1.26V12.4z" />
+ android:width="31dp"
+ android:height="16dp"
+ android:viewportWidth="31.0"
+ android:viewportHeight="16.0">
<path
- android:fillColor="#FFFFFFFF"
- android:pathData="M11.35,4.6H8.73v8.88H7.48V4.6H4.87V3.52h6.48V4.6z" />
+ android:fillColor="#FF000000"
+ android:pathData="M2,13V2.98h1.53v8.57H8.3V13H2z"/>
<path
- android:fillColor="#FFFFFFFF"
- android:pathData="M17.59,8.88h-3.52v3.53h4.1v1.07h-5.35V3.52h5.28V4.6h-4.03V7.8h3.52V8.88z" />
+ android:fillColor="#FF000000"
+ android:pathData="M11.24,13V4.43H8.19V2.98h7.63v1.46h-3.05V13H11.24z"/>
<path
- android:fillColor="#FFFFFFFF"
- android:pathData="M 23.32 5.74 L 23.32 3.39 L 22.02 3.39 L 22.02 5.74 L 19.67 5.74 L 19.67 7.04 L 22.02 7.04 L 22.02 9.39 L 23.32 9.39 L 23.32 7.04 L 25.67 7.04 L 25.67 5.74 Z" />
+ android:fillColor="#FF000000"
+ android:pathData="M17.41,13V2.98h6.36v1.46h-4.83v2.65h4.4v1.46h-4.4v3.01h4.83V13H17.41z"/>
<path
- android:pathData="M 0 0 H 26 V 17 H 0 V 0 Z" />
+ android:fillColor="#FF000000"
+ android:pathData="M28.72 5.24 28.72 2.89 27.42 2.89 27.42 5.24 25.07 5.24 25.07 6.54 27.42 6.54 27.42 8.89 28.72 8.89 28.72 6.54 31.07 6.54 31.07 5.24Z"/>
</vector>
diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java
index 132a631e25cc..21fb26976c1b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java
+++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java
@@ -27,6 +27,7 @@ import static android.os.BatteryManager.EXTRA_MAX_CHARGING_VOLTAGE;
import static android.os.BatteryManager.EXTRA_PLUGGED;
import static android.os.BatteryManager.EXTRA_PRESENT;
import static android.os.BatteryManager.EXTRA_STATUS;
+import static android.os.BatteryManager.EXTRA_OEM_FAST_CHARGER;
import android.content.Context;
import android.content.Intent;
@@ -51,15 +52,17 @@ public class BatteryStatus {
public final int plugged;
public final int health;
public final int maxChargingWattage;
+ public final boolean oemFastChargeStatus;
public final boolean present;
public BatteryStatus(int status, int level, int plugged, int health,
- int maxChargingWattage, boolean present) {
+ int maxChargingWattage, boolean oemFastChargeStatus, boolean present) {
this.status = status;
this.level = level;
this.plugged = plugged;
this.health = health;
this.maxChargingWattage = maxChargingWattage;
+ this.oemFastChargeStatus = oemFastChargeStatus;
this.present = present;
}
@@ -68,6 +71,7 @@ public class BatteryStatus {
plugged = batteryChangedIntent.getIntExtra(EXTRA_PLUGGED, 0);
level = batteryChangedIntent.getIntExtra(EXTRA_LEVEL, 0);
health = batteryChangedIntent.getIntExtra(EXTRA_HEALTH, BATTERY_HEALTH_UNKNOWN);
+ oemFastChargeStatus = batteryChangedIntent.getBooleanExtra(EXTRA_OEM_FAST_CHARGER, false);
present = batteryChangedIntent.getBooleanExtra(EXTRA_PRESENT, true);
final int maxChargingMicroAmp = batteryChangedIntent.getIntExtra(EXTRA_MAX_CHARGING_CURRENT,
@@ -162,6 +166,9 @@ public class BatteryStatus {
* @return the charing speed
*/
public final int getChargingSpeed(Context context) {
+ if (oemFastChargeStatus) {
+ return CHARGING_FAST;
+ }
final int slowThreshold = context.getResources().getInteger(
R.integer.config_chargingSlowlyThreshold);
final int fastThreshold = context.getResources().getInteger(
diff --git a/packages/SystemUI/customization/res/font/clock.xml b/packages/SystemUI/customization/res/font/clock.xml
new file mode 100644
index 000000000000..5122fe74719b
--- /dev/null
+++ b/packages/SystemUI/customization/res/font/clock.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2020, 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.
+*/
+-->
+
+<!--
+** AOD/LockScreen Clock font.
+** Should include all numeric glyphs in all supported locales.
+** Recommended: font with variable width to support AOD => LS animations
+-->
+<font-family xmlns:android="http://schemas.android.com/apk/res/android">
+ <font android:font="@font/google_sans_clock"/>
+</font-family> \ No newline at end of file
diff --git a/packages/SystemUI/customization/res/font/google_sans_clock.ttf b/packages/SystemUI/customization/res/font/google_sans_clock.ttf
new file mode 100644
index 000000000000..5e683a05088c
--- /dev/null
+++ b/packages/SystemUI/customization/res/font/google_sans_clock.ttf
Binary files differ
diff --git a/packages/SystemUI/customization/res/layout/clock_default_large.xml b/packages/SystemUI/customization/res/layout/clock_default_large.xml
index 0139d50dcfba..415f964a215f 100644
--- a/packages/SystemUI/customization/res/layout/clock_default_large.xml
+++ b/packages/SystemUI/customization/res/layout/clock_default_large.xml
@@ -23,7 +23,7 @@
android:layout_gravity="center"
android:gravity="center_horizontal"
android:textSize="@dimen/large_clock_text_size"
- android:fontFamily="@*android:string/config_clockFontFamily"
+ android:fontFamily="@font/clock"
android:typeface="monospace"
android:elegantTextHeight="false"
chargeAnimationDelay="200"
diff --git a/packages/SystemUI/customization/res/layout/clock_default_small.xml b/packages/SystemUI/customization/res/layout/clock_default_small.xml
index ff6d7f9e2240..eb86ae50cbc9 100644
--- a/packages/SystemUI/customization/res/layout/clock_default_small.xml
+++ b/packages/SystemUI/customization/res/layout/clock_default_small.xml
@@ -23,7 +23,7 @@
android:layout_gravity="start"
android:gravity="start"
android:textSize="@dimen/small_clock_text_size"
- android:fontFamily="@*android:string/config_clockFontFamily"
+ android:fontFamily="@font/clock"
android:elegantTextHeight="false"
android:ellipsize="none"
android:singleLine="true"
diff --git a/packages/SystemUI/res/drawable-nodpi/udfps_icon_pressed.png b/packages/SystemUI/res/drawable-nodpi/udfps_icon_pressed.png
new file mode 100644
index 000000000000..4102e28c1300
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/udfps_icon_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/dialog_tri_state_down_bg.xml b/packages/SystemUI/res/drawable/dialog_tri_state_down_bg.xml
new file mode 100644
index 000000000000..7dddc9d0e930
--- /dev/null
+++ b/packages/SystemUI/res/drawable/dialog_tri_state_down_bg.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 CypherOS
+
+ 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.
+-->
+<layer-list
+ xmlns:android="http://schemas.android.com/apk/res/android">
+ <item>
+ <shape>
+ <solid android:color="#ff1d1d1d" />
+ <corners
+ android:topLeftRadius="@dimen/tri_state_down_top_left_radius"
+ android:topRightRadius="@dimen/tri_state_down_top_right_radius"
+ android:bottomLeftRadius="@dimen/tri_state_down_bottom_left_radius"
+ android:bottomRightRadius="@dimen/tri_state_down_bottom_right_radius" />
+ </shape>
+ </item>
+</layer-list> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/dialog_tri_state_middle_bg.xml b/packages/SystemUI/res/drawable/dialog_tri_state_middle_bg.xml
new file mode 100644
index 000000000000..7cde6be2808c
--- /dev/null
+++ b/packages/SystemUI/res/drawable/dialog_tri_state_middle_bg.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 CypherOS
+
+ 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.
+-->
+<layer-list
+ xmlns:android="http://schemas.android.com/apk/res/android">
+ <item>
+ <shape>
+ <solid android:color="#ff1d1d1d" />
+ <corners
+ android:topLeftRadius="@dimen/tri_state_mid_top_left_radius"
+ android:topRightRadius="@dimen/tri_state_mid_top_right_radius"
+ android:bottomLeftRadius="@dimen/tri_state_mid_bottom_left_radius"
+ android:bottomRightRadius="@dimen/tri_state_mid_bottom_right_radius" />
+ </shape>
+ </item>
+</layer-list> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/dialog_tri_state_up_bg.xml b/packages/SystemUI/res/drawable/dialog_tri_state_up_bg.xml
new file mode 100644
index 000000000000..69757a77ee86
--- /dev/null
+++ b/packages/SystemUI/res/drawable/dialog_tri_state_up_bg.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 CypherOS
+
+ 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.
+-->
+<layer-list
+ xmlns:android="http://schemas.android.com/apk/res/android">
+ <item>
+ <shape>
+ <solid android:color="#ff1d1d1d" />
+ <corners
+ android:topLeftRadius="@dimen/tri_state_up_top_left_radius"
+ android:topRightRadius="@dimen/tri_state_up_top_right_radius"
+ android:bottomLeftRadius="@dimen/tri_state_up_bottom_left_radius"
+ android:bottomRightRadius="@dimen/tri_state_up_bottom_right_radius" />
+ </shape>
+ </item>
+</layer-list> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_qs_aod.xml b/packages/SystemUI/res/drawable/ic_qs_aod.xml
new file mode 100644
index 000000000000..4bb2d4ac566b
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_aod.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#ffffff"
+ android:pathData="M17,19 L17,5 L7,5 L7,19 L17,19 M17,1 C18.1046,1,19,1.89543,19,3 L19,21 C19,22.1046,18.1046,23,17,23 L7,23 C5.89,23,5,22.1,5,21 L5,3 C5,1.89,5.89,1,7,1 L17,1 M9,7 L15,7 L15,9 L9,9 L9,7" />
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_caffeine.xml b/packages/SystemUI/res/drawable/ic_qs_caffeine.xml
new file mode 100644
index 000000000000..2c3ba974a7e1
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_caffeine.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (c) 2015 The CyanogenMod Project
+ Copyright (c) 2017 The LineageOS 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="48dp"
+ android:height="48dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M2,21H20V19H2M20,8H18V5H20M20,3H4V13A4,4 0 0,0 8,17H14A4,4 0 0,0 18,13V10H20A2,2 0 0,0 22,8V5C22,3.89 21.1,3 20,3Z" />
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_heads_up.xml b/packages/SystemUI/res/drawable/ic_qs_heads_up.xml
new file mode 100644
index 000000000000..b107602787c1
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_heads_up.xml
@@ -0,0 +1,36 @@
+<!--
+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="64dp"
+ android:height="64dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+
+ <path
+ android:pathData="M0,0h24v24H0V0z" />
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M18,16v-5c0-3.07-1.64-5.64-4.5-6.32V4c0-0.83-0.68-1.5-1.51-1.5S10.5,3.17,10.5,4v0.68C7.63,5.36,6,7.92,6,11v5 l-1.3,1.29C4.07,17.92,4.51,19,5.4,19h13.17c0.89,0,1.34-1.08,0.71-1.71L18,16z" />
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M11.99,22c1.1,0,2-0.9,2-2h-4C9.99,21.1,10.88,22,11.99,22z" />
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M6.77,4.73C7.19,4.35,7.2,3.7,6.8,3.3l0,0c-0.38-0.38-1-0.39-1.39-0.02C3.7,4.84,2.52,6.96,2.14,9.34 C2.05,9.95,2.52,10.5,3.14,10.5h0c0.48,0,0.9-0.35,0.98-0.83C4.42,7.73,5.38,6,6.77,4.73z" />
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M18.6,3.28c-0.4-0.37-1.02-0.36-1.4,0.02l0,0c-0.4,0.4-0.38,1.04,0.03,1.42c1.38,1.27,2.35,3,2.65,4.94 c0.07,0.48,0.49,0.83,0.98,0.83c0.61,0,1.09-0.55,0.99-1.16C21.47,6.96,20.3,4.85,18.6,3.28z" />
+</vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_dnd.xml b/packages/SystemUI/res/drawable/stat_sys_dnd.xml
index aa352b42cf04..da861eb72845 100644
--- a/packages/SystemUI/res/drawable/stat_sys_dnd.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_dnd.xml
@@ -17,6 +17,6 @@
*/
-->
<inset xmlns:android="http://schemas.android.com/apk/res/android"
- android:insetLeft="2.5dp"
- android:insetRight="2.5dp"
+ android:insetLeft="0dp"
+ android:insetRight="0dp"
android:drawable="@*android:drawable/ic_qs_dnd" /> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/stat_sys_ringer_silent.xml b/packages/SystemUI/res/drawable/stat_sys_ringer_silent.xml
index a8f0cc3a1d92..1a0599107f69 100644
--- a/packages/SystemUI/res/drawable/stat_sys_ringer_silent.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_ringer_silent.xml
@@ -14,8 +14,8 @@ Copyright (C) 2015 The Android Open Source Project
limitations under the License.
-->
<inset xmlns:android="http://schemas.android.com/apk/res/android"
- android:insetLeft="3dp"
- android:insetRight="3dp">
+ android:insetLeft="0.5dp"
+ android:insetRight="0.5dp">
<vector android:width="18dp"
android:height="18dp"
android:viewportWidth="24.0"
diff --git a/packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml b/packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml
index 21a4c1703d31..5d196846822a 100644
--- a/packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml
@@ -14,6 +14,6 @@
limitations under the License.
-->
<inset xmlns:android="http://schemas.android.com/apk/res/android"
- android:insetLeft="2.5dp"
- android:insetRight="2.5dp"
- android:drawable="@drawable/ic_volume_ringer_vibrate" /> \ No newline at end of file
+ android:insetLeft="0dp"
+ android:insetRight="0dp"
+ android:drawable="@drawable/ic_volume_ringer_vibrate" />
diff --git a/packages/SystemUI/res/layout-land/volume_dialog.xml b/packages/SystemUI/res/layout-land/volume_dialog.xml
index 3b70dc060e84..116877b44eaa 100644
--- a/packages/SystemUI/res/layout-land/volume_dialog.xml
+++ b/packages/SystemUI/res/layout-land/volume_dialog.xml
@@ -20,8 +20,6 @@
android:id="@+id/volume_dialog_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:gravity="right"
- android:layout_gravity="right"
android:background="@android:color/transparent"
android:theme="@style/volume_dialog_theme">
@@ -30,9 +28,8 @@
android:id="@+id/volume_dialog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:gravity="right"
- android:layout_gravity="right"
- android:layout_marginRight="@dimen/volume_dialog_panel_transparent_padding_right"
+ android:paddingLeft="@dimen/volume_dialog_panel_transparent_padding_left"
+ android:paddingRight="@dimen/volume_dialog_panel_transparent_padding_right"
android:orientation="vertical"
android:clipToPadding="false"
android:clipChildren="false">
@@ -43,8 +40,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
- android:clipChildren="false"
- android:gravity="right">
+ android:clipChildren="false">
<include layout="@layout/volume_ringer_drawer" />
@@ -149,4 +145,4 @@
android:layout_gravity="bottom | right"
android:layout_marginRight="@dimen/volume_tool_tip_right_margin"/>
-</FrameLayout> \ No newline at end of file
+</FrameLayout>
diff --git a/packages/SystemUI/res/layout/qs_footer_impl.xml b/packages/SystemUI/res/layout/qs_footer_impl.xml
index b1d3ed05333b..f0f8c0c79b17 100644
--- a/packages/SystemUI/res/layout/qs_footer_impl.xml
+++ b/packages/SystemUI/res/layout/qs_footer_impl.xml
@@ -64,7 +64,7 @@
android:layout_width="@dimen/qs_footer_action_button_size"
android:layout_height="@dimen/qs_footer_action_button_size"
android:layout_gravity="center_vertical|end"
- android:background="?android:attr/selectableItemBackground"
+ android:background="?android:attr/actionBarItemBackground"
android:clickable="true"
android:contentDescription="@string/accessibility_quick_settings_edit"
android:focusable="true"
diff --git a/packages/SystemUI/res/layout/tri_state_dialog.xml b/packages/SystemUI/res/layout/tri_state_dialog.xml
new file mode 100644
index 000000000000..cf3890d59a88
--- /dev/null
+++ b/packages/SystemUI/res/layout/tri_state_dialog.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 CypherOS
+
+ 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.
+-->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:paddingLeft="@dimen/tri_state_dialog_padding"
+ android:paddingTop="@dimen/tri_state_dialog_padding"
+ android:paddingRight="@dimen/tri_state_dialog_padding"
+ android:paddingBottom="@dimen/tri_state_dialog_padding"
+ android:clipToPadding="false"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true">
+
+ <LinearLayout
+ android:layout_gravity="center|right"
+ android:orientation="horizontal"
+ android:id="@+id/tri_state_layout"
+ android:background="@drawable/dialog_tri_state_middle_bg"
+ android:layout_width="wrap_content"
+ android:layout_height="48.0dip"
+ android:translationZ="@dimen/tri_state_dialog_elevation">
+
+ <FrameLayout
+ android:layout_width="54.0dip"
+ android:layout_height="fill_parent">
+
+ <ImageView
+ android:layout_gravity="center"
+ android:id="@+id/tri_state_icon"
+ android:layout_marginLeft="2.0dip"
+ android:layout_width="@dimen/tri_state_dialog_icon_size"
+ android:layout_height="@dimen/tri_state_dialog_icon_size" />
+ </FrameLayout>
+
+ <TextView
+ android:gravity="center_vertical"
+ android:id="@+id/tri_state_text"
+ android:layout_width="wrap_content"
+ android:layout_height="fill_parent"
+ style="@style/TriStateUiText" />
+
+ <FrameLayout
+ android:layout_width="18.0dip"
+ android:layout_height="fill_parent" />
+ </LinearLayout>
+</LinearLayout> \ No newline at end of file
diff --git a/packages/SystemUI/res/layout/udfps_view.xml b/packages/SystemUI/res/layout/udfps_view.xml
index 257d238f5c54..0fcbfa161ddf 100644
--- a/packages/SystemUI/res/layout/udfps_view.xml
+++ b/packages/SystemUI/res/layout/udfps_view.xml
@@ -28,4 +28,10 @@
android:layout_width="match_parent"
android:layout_height="match_parent"/>
+ <com.android.systemui.biometrics.UdfpsSurfaceView
+ android:id="@+id/hbm_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="invisible"/>
+
</com.android.systemui.biometrics.UdfpsView>
diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml
index 6a192d4b7e05..c73050575a1c 100644
--- a/packages/SystemUI/res/layout/volume_dialog.xml
+++ b/packages/SystemUI/res/layout/volume_dialog.xml
@@ -20,8 +20,6 @@
android:id="@+id/volume_dialog_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:gravity="right"
- android:layout_gravity="right"
android:clipToPadding="false"
android:theme="@style/volume_dialog_theme">
@@ -30,9 +28,8 @@
android:id="@+id/volume_dialog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:gravity="right"
- android:layout_gravity="right"
- android:layout_marginRight="@dimen/volume_dialog_panel_transparent_padding_right"
+ android:paddingLeft="@dimen/volume_dialog_panel_transparent_padding_left"
+ android:paddingRight="@dimen/volume_dialog_panel_transparent_padding_right"
android:orientation="vertical"
android:clipToPadding="false"
android:clipChildren="false">
@@ -73,7 +70,6 @@
<include layout="@layout/volume_dnd_icon"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginRight="@dimen/volume_dialog_stream_padding"
android:layout_marginTop="6dp"/>
</FrameLayout>
@@ -145,7 +141,6 @@
android:layout="@layout/volume_tool_tip_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_gravity="bottom | right"
android:layout_marginRight="@dimen/volume_tool_tip_right_margin"/>
-</FrameLayout> \ No newline at end of file
+</FrameLayout>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index ca2426854ada..6cfa07467478 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -81,7 +81,7 @@
<!-- Tiles native to System UI. Order should match "quick_settings_tiles_default" -->
<string name="quick_settings_tiles_stock" translatable="false">
- internet,bt,flashlight,dnd,alarm,airplane,controls,wallet,rotation,battery,cast,screenrecord,mictoggle,cameratoggle,location,hotspot,inversion,saver,dark,work,night,reverse,reduce_brightness,qr_code_scanner,onehanded,color_correction,dream
+ internet,bt,flashlight,dnd,alarm,airplane,nfc,controls,wallet,rotation,battery,cast,screenrecord,mictoggle,cameratoggle,location,hotspot,inversion,saver,dark,work,night,reverse,reduce_brightness,qr_code_scanner,onehanded,color_correction,dream,aod,caffeine,heads_up
</string>
<!-- The tiles to display in QuickSettings -->
diff --git a/packages/SystemUI/res/values/ice_config.xml b/packages/SystemUI/res/values/ice_config.xml
new file mode 100644
index 000000000000..563d63f7ac2a
--- /dev/null
+++ b/packages/SystemUI/res/values/ice_config.xml
@@ -0,0 +1,22 @@
+<!--
+ Copyright (C) 2022 Project ICE
+
+ 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.
+-->
+<resources>
+ <!-- Color of the UDFPS pressed view -->
+ <color name="config_udfpsColor">#ffffffff</color>
+
+ <!-- Allow devices override audio panel location to the left side -->
+ <bool name="config_audioPanelOnLeftSide">false</bool>
+</resources>
diff --git a/packages/SystemUI/res/values/ice_dimens.xml b/packages/SystemUI/res/values/ice_dimens.xml
new file mode 100644
index 000000000000..59368978decd
--- /dev/null
+++ b/packages/SystemUI/res/values/ice_dimens.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2022 Project ICE
+
+ 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.
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Alert Slider -->
+ <dimen name="tri_state_down_dialog_position">0px</dimen>
+ <dimen name="tri_state_down_dialog_position_l">0px</dimen>
+ <dimen name="tri_state_middle_dialog_position">0px</dimen>
+ <dimen name="tri_state_middle_dialog_position_l">0px</dimen>
+ <dimen name="tri_state_up_dialog_position">0px</dimen>
+ <dimen name="tri_state_up_dialog_position_l">0px</dimen>
+ <dimen name="tri_state_up_dialog_position_deep">0px</dimen>
+ <dimen name="tri_state_up_dialog_position_deep_land">0px</dimen>
+ <dimen name="tri_state_dialog_elevation">4.0dip</dimen>
+ <dimen name="tri_state_dialog_icon_size">24.0dip</dimen>
+ <dimen name="tri_state_dialog_padding">8.0dip</dimen>
+ <dimen name="tri_state_down_bottom_left_radius">24.0dip</dimen>
+ <dimen name="tri_state_down_bottom_right_radius">24.0dip</dimen>
+ <dimen name="tri_state_down_top_left_radius">24.0dip</dimen>
+ <dimen name="tri_state_down_top_right_radius">0.0dip</dimen>
+ <dimen name="tri_state_mid_bottom_left_radius">24.0dip</dimen>
+ <dimen name="tri_state_mid_bottom_right_radius">24.0dip</dimen>
+ <dimen name="tri_state_mid_top_left_radius">24.0dip</dimen>
+ <dimen name="tri_state_mid_top_right_radius">24.0dip</dimen>
+ <dimen name="tri_state_up_bottom_left_radius">24.0dip</dimen>
+ <dimen name="tri_state_up_bottom_right_radius">0.0dip</dimen>
+ <dimen name="tri_state_up_top_left_radius">24.0dip</dimen>
+ <dimen name="tri_state_up_top_right_radius">24.0dip</dimen>
+
+ <!-- Volume panel -->
+ <dimen name="volume_dialog_panel_transparent_padding_left">8dp</dimen>
+</resources>
diff --git a/packages/SystemUI/res/values/ice_strings.xml b/packages/SystemUI/res/values/ice_strings.xml
new file mode 100644
index 000000000000..71c70b9ca36b
--- /dev/null
+++ b/packages/SystemUI/res/values/ice_strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+ Copyright (C) 2022 Project ICE
+
+ 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.
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Custom QS tiles -->
+ <!-- AOD QS tile -->
+ <string name="quick_settings_aod_label">AOD</string>
+ <string name="quick_settings_aod_off_powersave_label">AOD off\nBattery saver</string>
+
+ <!-- Caffeine QS tile -->
+ <string name="quick_settings_caffeine_label">Caffeine</string>
+ <string name="accessibility_quick_settings_caffeine_off">Caffeine off.</string>
+ <string name="accessibility_quick_settings_caffeine_on">Caffeine on.</string>
+
+ <!-- Heads up QS tile -->
+ <string name="quick_settings_heads_up_label">Heads up</string>
+ <string name="accessibility_quick_settings_heads_up_off">Heads up off.</string>
+ <string name="accessibility_quick_settings_heads_up_on">Heads up on.</string>
+</resources>
diff --git a/packages/SystemUI/res/values/ice_styles.xml b/packages/SystemUI/res/values/ice_styles.xml
new file mode 100644
index 000000000000..652258a68746
--- /dev/null
+++ b/packages/SystemUI/res/values/ice_styles.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2022 Project ICE
+
+ 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.
+-->
+<resources>
+ <!-- Alert Slider -->
+ <style name="TriStateUiText">
+ <item name="android:textSize">11.0sp</item>
+ <item name="android:fontFamily">sans-serif-medium</item>
+ </style>
+</resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index dcbdc359a1a8..f051256a684d 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -117,7 +117,6 @@
<style name="TextAppearance.QS.TileLabel">
<item name="android:textSize">@dimen/qs_tile_text_size</item>
- <item name="android:letterSpacing">0.01</item>
<item name="android:lineHeight">20sp</item>
<item name="android:fontFamily">@*android:string/config_bodyFontFamilyMedium</item>
</style>
@@ -137,7 +136,6 @@
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
<item name="android:textColor">?android:attr/textColorPrimary</item>
<item name="android:textSize">14sp</item>
- <item name="android:letterSpacing">0.01</item>
</style>
<style name="TextAppearance.QS.SecurityFooter" parent="@style/TextAppearance.QS.Status">
@@ -592,7 +590,6 @@
<style name="TextAppearance.QSEdit" >
<item name="android:textSize">14sp</item>
- <item name="android:letterSpacing">0.01</item>
<item name="android:lineHeight">20sp</item>
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
<item name="android:textColor">?android:attr/textColorSecondary</item>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
index 62babadc45d8..9793ed72c087 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -1,10 +1,13 @@
package com.android.keyguard;
+import static com.android.systemui.shared.recents.utilities.Utilities.isTablet;
+
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
+import android.content.res.Configuration;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
@@ -92,6 +95,18 @@ public class KeyguardClockSwitch extends RelativeLayout {
super(context, attrs);
}
+ @Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+
+ if (mDisplayedClockSize != null) {
+ boolean landscape = newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE;
+ boolean useLargeClock = mDisplayedClockSize == LARGE &&
+ (!landscape || isTablet(mContext));
+ updateClockViews(useLargeClock, /* animate */ true);
+ }
+ }
+
/**
* Apply dp changes on font/scale change
*/
@@ -240,11 +255,14 @@ public class KeyguardClockSwitch extends RelativeLayout {
if (mDisplayedClockSize != null && clockSize == mDisplayedClockSize) {
return false;
}
+ boolean landscape = getResources().getConfiguration().orientation
+ == Configuration.ORIENTATION_LANDSCAPE;
+ boolean useLargeClock = clockSize == LARGE && (!landscape || isTablet(mContext));
// let's make sure clock is changed only after all views were laid out so we can
// translate them properly
if (mChildrenAreLaidOut) {
- updateClockViews(clockSize == LARGE, animate);
+ updateClockViews(useLargeClock, animate);
}
mDisplayedClockSize = clockSize;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
index 65a71664e245..31d22eb38a24 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
@@ -49,6 +49,7 @@ import com.android.internal.graphics.ColorUtils;
import com.android.settingslib.Utils;
import com.android.systemui.R;
import com.android.systemui.animation.Interpolators;
+import com.android.systemui.keyguard.KeyguardSliceProvider;
import com.android.systemui.util.wakelock.KeepAwakeAnimationListener;
import java.io.PrintWriter;
@@ -445,13 +446,15 @@ public class KeyguardSliceView extends LinearLayout {
private void updatePadding() {
boolean hasText = !TextUtils.isEmpty(getText());
+ boolean isDate = Uri.parse(KeyguardSliceProvider.KEYGUARD_DATE_URI).equals(getTag());
int padding = (int) getContext().getResources()
.getDimension(R.dimen.widget_horizontal_padding) / 2;
+ int iconPadding = (int) mContext.getResources()
+ .getDimension(R.dimen.widget_icon_padding);
// orientation is vertical, so add padding to top & bottom
- setPadding(0, padding, 0, hasText ? padding : 0);
+ setPadding(!isDate ? iconPadding : 0, padding, 0, hasText ? padding : 0);
- setCompoundDrawablePadding((int) mContext.getResources()
- .getDimension(R.dimen.widget_icon_padding));
+ setCompoundDrawablePadding(iconPadding);
}
@Override
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index ea47496d0986..21372f7759de 100755
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -2195,7 +2195,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
// Take a guess at initial SIM state, battery status and PLMN until we get an update
- mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0, 0, true);
+ mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0, 0, false, true);
// Watch for interesting updates
final IntentFilter filter = new IntentFilter();
@@ -3476,6 +3476,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
return true;
}
+ // change in oem fast charging while plugged in
+ if (nowPluggedIn && current.oemFastChargeStatus != old.oemFastChargeStatus) {
+ return true;
+ }
+
// Battery either showed up or disappeared
if (wasPresent != nowPresent) {
return true;
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIService.java b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
index 50e03992df49..9f131446217d 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIService.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
@@ -83,7 +83,7 @@ public class SystemUIService extends Service {
throw new RuntimeException();
}
- if (Build.IS_DEBUGGABLE) {
+ if (Build.IS_ENG) {
// b/71353150 - looking for leaked binder proxies
BinderInternal.nSetBinderProxyCountEnabled(true);
BinderInternal.nSetBinderProxyCountWatermarks(1000,900);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt
index 4b57d455a137..dd782805cc59 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt
@@ -28,6 +28,7 @@ import android.util.AttributeSet
import android.view.View
import android.view.animation.PathInterpolator
import com.android.internal.graphics.ColorUtils
+import com.android.settingslib.Utils
import com.android.systemui.animation.Interpolators
import com.android.systemui.surfaceeffects.ripple.RippleShader
@@ -85,7 +86,7 @@ class AuthRippleView(context: Context?, attrs: AttributeSet?) : View(context, at
}
init {
- rippleShader.color = 0xffffffff.toInt() // default color
+ rippleShader.color = Utils.getColorAttr(context, android.R.attr.colorAccent).defaultColor
rippleShader.progress = 0f
rippleShader.sparkleStrength = RIPPLE_SPARKLE_STRENGTH
ripplePaint.shader = rippleShader
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsSurfaceView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsSurfaceView.java
new file mode 100644
index 000000000000..2488132b508b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsSurfaceView.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2021 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.biometrics;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.RectF;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+
+import com.android.systemui.R;
+
+/**
+ * Surface View for providing the Global High-Brightness Mode (GHBM) illumination for UDFPS.
+ */
+public class UdfpsSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
+ private static final String TAG = "UdfpsSurfaceView";
+
+ /**
+ * Notifies {@link UdfpsView} when to enable GHBM illumination.
+ */
+ interface GhbmIlluminationListener {
+ /**
+ * @param surface the surface for which GHBM should be enabled.
+ * @param onDisplayConfigured a runnable that should be run after GHBM is enabled.
+ */
+ void enableGhbm(@NonNull Surface surface, @Nullable Runnable onDisplayConfigured);
+ }
+
+ @NonNull private final SurfaceHolder mHolder;
+ @NonNull private final Paint mSensorPaint;
+
+ @Nullable private GhbmIlluminationListener mGhbmIlluminationListener;
+ @Nullable private Runnable mOnDisplayConfigured;
+ boolean mAwaitingSurfaceToStartIllumination;
+ boolean mHasValidSurface;
+
+ private Drawable mUdfpsIconPressed;
+
+ public UdfpsSurfaceView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+
+ // Make this SurfaceView draw on top of everything else in this window. This allows us to
+ // 1) Always show the HBM circle on top of everything else, and
+ // 2) Properly composite this view with any other animations in the same window no matter
+ // what contents are added in which order to this view hierarchy.
+ setZOrderOnTop(true);
+
+ mHolder = getHolder();
+ mHolder.addCallback(this);
+ mHolder.setFormat(PixelFormat.RGBA_8888);
+
+ mSensorPaint = new Paint(0 /* flags */);
+ mSensorPaint.setAntiAlias(true);
+ mSensorPaint.setColor(context.getColor(R.color.config_udfpsColor));
+ mSensorPaint.setStyle(Paint.Style.FILL);
+
+ mUdfpsIconPressed = context.getDrawable(R.drawable.udfps_icon_pressed);
+ }
+
+ @Override public void surfaceCreated(SurfaceHolder holder) {
+ mHasValidSurface = true;
+ if (mAwaitingSurfaceToStartIllumination) {
+ doIlluminate(mOnDisplayConfigured);
+ mOnDisplayConfigured = null;
+ mAwaitingSurfaceToStartIllumination = false;
+ }
+ }
+
+ @Override
+ public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+ // Unused.
+ }
+
+ @Override public void surfaceDestroyed(SurfaceHolder holder) {
+ mHasValidSurface = false;
+ }
+
+ void setGhbmIlluminationListener(@Nullable GhbmIlluminationListener listener) {
+ mGhbmIlluminationListener = listener;
+ }
+
+ /**
+ * Note: there is no corresponding method to stop GHBM illumination. It is expected that
+ * {@link UdfpsView} will hide this view, which would destroy the surface and remove the
+ * illumination dot.
+ */
+ void startGhbmIllumination(@Nullable Runnable onDisplayConfigured) {
+ if (mGhbmIlluminationListener == null) {
+ Log.e(TAG, "startIllumination | mGhbmIlluminationListener is null");
+ return;
+ }
+
+ if (mHasValidSurface) {
+ doIlluminate(onDisplayConfigured);
+ } else {
+ mAwaitingSurfaceToStartIllumination = true;
+ mOnDisplayConfigured = onDisplayConfigured;
+ }
+ }
+
+ private void doIlluminate(@Nullable Runnable onDisplayConfigured) {
+ if (mGhbmIlluminationListener == null) {
+ Log.e(TAG, "doIlluminate | mGhbmIlluminationListener is null");
+ return;
+ }
+
+ mGhbmIlluminationListener.enableGhbm(mHolder.getSurface(), onDisplayConfigured);
+ }
+
+ /**
+ * Immediately draws the illumination dot on this SurfaceView's surface.
+ */
+ void drawIlluminationDot(@NonNull RectF sensorRect) {
+ if (!mHasValidSurface) {
+ Log.e(TAG, "drawIlluminationDot | the surface is destroyed or was never created.");
+ return;
+ }
+ Canvas canvas = null;
+ try {
+ canvas = mHolder.lockCanvas();
+ mUdfpsIconPressed.setBounds(
+ Math.round(sensorRect.left),
+ Math.round(sensorRect.top),
+ Math.round(sensorRect.right),
+ Math.round(sensorRect.bottom)
+ );
+ mUdfpsIconPressed.draw(canvas);
+ canvas.drawOval(sensorRect, mSensorPaint);
+ } finally {
+ // Make sure the surface is never left in a bad state.
+ if (canvas != null) {
+ mHolder.unlockCanvasAndPost(canvas);
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt
index 4a8877edfa53..97590822a3fb 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt
@@ -25,6 +25,7 @@ import android.graphics.RectF
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
+import android.view.Surface
import android.widget.FrameLayout
import com.android.systemui.R
import com.android.systemui.doze.DozeReceiver
@@ -60,6 +61,8 @@ class UdfpsView(
a.getFloat(R.styleable.UdfpsView_sensorTouchAreaCoefficient, 0f)
}
+ private var ghbmView: UdfpsSurfaceView? = null
+
/** View controller (can be different for enrollment, BiometricPrompt, Keyguard, etc.). */
var animationViewController: UdfpsAnimationViewController<*>? = null
@@ -86,6 +89,10 @@ class UdfpsView(
return (animationViewController == null || !animationViewController!!.shouldPauseAuth())
}
+ override fun onFinishInflate() {
+ ghbmView = findViewById(R.id.hbm_view)
+ }
+
override fun dozeTimeTick() {
animationViewController?.dozeTimeTick()
}
@@ -153,12 +160,34 @@ class UdfpsView(
fun configureDisplay(onDisplayConfigured: Runnable) {
isDisplayConfigured = true
animationViewController?.onDisplayConfiguring()
- mUdfpsDisplayMode?.enable(onDisplayConfigured)
+ val gView = ghbmView
+ if (gView != null) {
+ gView.setGhbmIlluminationListener(this::doIlluminate)
+ gView.visibility = VISIBLE
+ gView.startGhbmIllumination(onDisplayConfigured)
+ } else {
+ doIlluminate(null /* surface */, onDisplayConfigured)
+ }
+ }
+
+ private fun doIlluminate(surface: Surface?, onDisplayConfigured: Runnable?) {
+ if (ghbmView != null && surface == null) {
+ Log.e(TAG, "doIlluminate | surface must be non-null for GHBM")
+ }
+
+ mUdfpsDisplayMode?.enable {
+ onDisplayConfigured?.run()
+ ghbmView?.drawIlluminationDot(RectF(sensorRect))
+ }
}
fun unconfigureDisplay() {
isDisplayConfigured = false
animationViewController?.onDisplayUnconfigured()
+ ghbmView?.let { view ->
+ view.setGhbmIlluminationListener(null)
+ view.visibility = INVISIBLE
+ }
mUdfpsDisplayMode?.disable(null /* onDisabled */)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinator.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinator.kt
index 8029ba844850..c4c23124b39e 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinator.kt
@@ -68,12 +68,6 @@ interface ControlActionCoordinator {
fun setValue(cvh: ControlViewHolder, templateId: String, newValue: Float)
/**
- * Actions may have been put on hold while the device is unlocked. Invoke this action if
- * present.
- */
- fun runPendingAction(controlId: String)
-
- /**
* User interaction with a control may be blocked for a period of time while actions are being
* executed by the application. When the response returns, run this method to enable further
* user interaction.
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt
index 99a10a33ab0f..d167eecb137d 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt
@@ -64,7 +64,6 @@ class ControlActionCoordinatorImpl @Inject constructor(
private val featureFlags: FeatureFlags,
) : ControlActionCoordinator {
private var dialog: Dialog? = null
- private var pendingAction: Action? = null
private var actionsInProgress = mutableSetOf<String>()
private val isLocked: Boolean
get() = !keyguardStateController.isUnlocked()
@@ -166,15 +165,6 @@ class ControlActionCoordinatorImpl @Inject constructor(
)
}
- override fun runPendingAction(controlId: String) {
- if (isLocked) return
- if (pendingAction?.controlId == controlId) {
- showSettingsDialogIfNeeded(pendingAction!!)
- pendingAction?.invoke()
- pendingAction = null
- }
- }
-
@MainThread
override fun enableActionOnTouch(controlId: String) {
actionsInProgress.remove(controlId)
@@ -196,17 +186,11 @@ class ControlActionCoordinatorImpl @Inject constructor(
val authRequired = action.authIsRequired || !allowTrivialControls
if (keyguardStateController.isShowing() && authRequired) {
- if (isLocked) {
- broadcastSender.closeSystemDialogs()
-
- // pending actions will only run after the control state has been refreshed
- pendingAction = action
- }
activityStarter.dismissKeyguardThenExecute({
Log.d(ControlsUiController.TAG, "Device unlocked, invoking controls action")
action.invoke()
true
- }, { pendingAction = null }, true /* afterKeyguardGone */)
+ }, null, true /* afterKeyguardGone */)
} else {
showSettingsDialogIfNeeded(action)
action.invoke()
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
index 6a9aaf865251..42dcff71bbf8 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
@@ -174,8 +174,6 @@ class ControlViewHolder(
controlActionCoordinator.longPress(this@ControlViewHolder)
true
})
-
- controlActionCoordinator.runPendingAction(cws.ci.controlId)
}
val wasLoading = isLoading
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index b95c3f3c0ee7..18ec037150e6 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -327,11 +327,16 @@ public class DozeTriggers implements DozeMachine.Part {
}
gentleWakeUp(pulseReason);
} else if (isPickup) {
+ final State state = mMachine.getState();
if (shouldDropPickupEvent()) {
mDozeLog.traceSensorEventDropped(pulseReason, "keyguard occluded");
return;
}
- gentleWakeUp(pulseReason);
+ if (state == State.DOZE_AOD) {
+ gentleWakeUp(pulseReason);
+ } else {
+ requestPulse(pulseReason, true, null);
+ }
} else if (isUdfpsLongPress) {
if (canPulse(mMachine.getState(), true)) {
mDozeLog.d("updfsLongPress - setting aodInterruptRunnable to run when "
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index 20ae64cf5985..d12d475f4847 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -300,7 +300,7 @@ object Flags {
val MEDIA_TAP_TO_TRANSFER = unreleasedFlag(900, "media_tap_to_transfer", teamfood = true)
// TODO(b/254512502): Tracking Bug
- val MEDIA_SESSION_ACTIONS = unreleasedFlag(901, "media_session_actions")
+ val MEDIA_SESSION_ACTIONS = releasedFlag(901, "media_session_actions")
// TODO(b/254512726): Tracking Bug
val MEDIA_NEARBY_DEVICES = releasedFlag(903, "media_nearby_devices")
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 9d535e7c8458..5546b70ae83e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -1954,6 +1954,8 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
if (mLockPatternUtils.isLockScreenDisabled(KeyguardUpdateMonitor.getCurrentUser())
&& !lockedOrMissing && !forceShow) {
if (DEBUG) Log.d(TAG, "doKeyguard: not showing because lockscreen is off");
+ setShowingLocked(false, mAodShowing);
+ hideLocked();
return;
}
}
@@ -2707,7 +2709,9 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
// only play "unlock" noises if not on a call (since the incall UI
// disables the keyguard)
if (TelephonyManager.EXTRA_STATE_IDLE.equals(mPhoneState)) {
- playSounds(false);
+ if (mShowing && mDeviceInteractive) {
+ playSounds(false);
+ }
}
setShowingLocked(false);
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarInflaterView.java
index 59bb2278edfe..84ac3eab9673 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarInflaterView.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarInflaterView.java
@@ -18,11 +18,17 @@ package com.android.systemui.navigationbar;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
import android.annotation.Nullable;
+import android.app.ActivityManager;
import android.content.Context;
+import android.content.om.IOverlayManager;
import android.content.res.Configuration;
import android.graphics.drawable.Icon;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.provider.Settings;
import android.util.AttributeSet;
import android.util.Log;
import android.util.SparseArray;
@@ -43,12 +49,13 @@ import com.android.systemui.navigationbar.buttons.ReverseLinearLayout;
import com.android.systemui.navigationbar.buttons.ReverseLinearLayout.ReverseRelativeLayout;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.shared.system.QuickStepContract;
+import com.android.systemui.tuner.TunerService;
import java.io.PrintWriter;
import java.util.Objects;
public class NavigationBarInflaterView extends FrameLayout
- implements NavigationModeController.ModeChangedListener {
+ implements NavigationModeController.ModeChangedListener, TunerService.Tunable {
private static final String TAG = "NavBarInflater";
@@ -83,6 +90,11 @@ public class NavigationBarInflaterView extends FrameLayout
private static final String ABSOLUTE_SUFFIX = "A";
private static final String ABSOLUTE_VERTICAL_CENTERED_SUFFIX = "C";
+ private static final String KEY_NAVIGATION_HINT =
+ Settings.Secure.NAVIGATION_BAR_HINT;
+ private static final String OVERLAY_NAVIGATION_HIDE_HINT =
+ "android.ice.overlay.hidenav";
+
protected LayoutInflater mLayoutInflater;
protected LayoutInflater mLandscapeInflater;
@@ -102,6 +114,8 @@ public class NavigationBarInflaterView extends FrameLayout
private OverviewProxyService mOverviewProxyService;
private int mNavBarMode = NAV_BAR_MODE_3BUTTON;
+ private boolean mIsHintEnabled;
+
public NavigationBarInflaterView(Context context, AttributeSet attrs) {
super(context, attrs);
createInflaters();
@@ -143,12 +157,22 @@ public class NavigationBarInflaterView extends FrameLayout
: mOverviewProxyService.shouldShowSwipeUpUI()
? R.string.config_navBarLayoutQuickstep
: R.string.config_navBarLayout;
+ if (!mIsHintEnabled && defaultResource == R.string.config_navBarLayoutHandle) {
+ return getContext().getString(defaultResource).replace(HOME_HANDLE, "");
+ }
return getContext().getString(defaultResource);
}
@Override
public void onNavigationModeChanged(int mode) {
mNavBarMode = mode;
+ updateHint();
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ Dependency.get(TunerService.class).addTunable(this, KEY_NAVIGATION_HINT);
}
@Override
@@ -157,6 +181,15 @@ public class NavigationBarInflaterView extends FrameLayout
super.onDetachedFromWindow();
}
+ @Override
+ public void onTuningChanged(String key, String newValue) {
+ if (KEY_NAVIGATION_HINT.equals(key)) {
+ mIsHintEnabled = TunerService.parseIntegerSwitch(newValue, true);
+ updateHint();
+ onLikelyDefaultLayoutChange();
+ }
+ }
+
public void onLikelyDefaultLayoutChange() {
// Reevaluate new layout
final String newValue = getDefaultLayout();
@@ -210,6 +243,24 @@ public class NavigationBarInflaterView extends FrameLayout
}
}
+ private void updateHint() {
+ final IOverlayManager iom = IOverlayManager.Stub.asInterface(
+ ServiceManager.getService(Context.OVERLAY_SERVICE));
+ final boolean state = mNavBarMode == NAV_BAR_MODE_GESTURAL && !mIsHintEnabled;
+ final int userId = ActivityManager.getCurrentUser();
+ try {
+ iom.setEnabled(OVERLAY_NAVIGATION_HIDE_HINT, state, userId);
+ if (state) {
+ // As overlays are also used to apply navigation mode, it is needed to set
+ // our customization overlay to highest priority to ensure it is applied.
+ iom.setHighestPriority(OVERLAY_NAVIGATION_HIDE_HINT, userId);
+ }
+ } catch (IllegalArgumentException | RemoteException e) {
+ Log.e(TAG, "Failed to " + (state ? "enable" : "disable")
+ + " overlay " + OVERLAY_NAVIGATION_HIDE_HINT + " for user " + userId);
+ }
+ }
+
private void initiallyFill(ButtonDispatcher buttonDispatcher) {
addAll(buttonDispatcher, mHorizontal.findViewById(R.id.ends_group));
addAll(buttonDispatcher, mHorizontal.findViewById(R.id.center_group));
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
index 100853caa2d7..20cf0d67903f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
@@ -660,7 +660,7 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, P
final String defaultTileList = res.getString(R.string.quick_settings_tiles_default);
tiles.addAll(Arrays.asList(defaultTileList.split(",")));
- if (Build.IS_DEBUGGABLE
+ if (Build.IS_ENG
&& GarbageMonitor.ADD_MEMORY_TILE_TO_DEFAULT_ON_DEBUGGABLE_BUILDS) {
tiles.add(GarbageMonitor.MemoryTile.TILE_SPEC);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index 946fe542741f..dbdbcae6856f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -18,10 +18,12 @@ import static android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import android.content.Context;
+import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Rect;
+import android.provider.AlarmClock;
import android.util.AttributeSet;
import android.util.Pair;
import android.view.DisplayCutout;
@@ -38,8 +40,10 @@ import androidx.annotation.Nullable;
import com.android.internal.policy.SystemBarUtils;
import com.android.settingslib.Utils;
+import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.battery.BatteryMeterView;
+import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider;
import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager;
import com.android.systemui.statusbar.phone.StatusIconContainer;
@@ -66,6 +70,8 @@ public class QuickStatusBarHeader extends FrameLayout {
private TouchAnimator mIconsAlphaAnimator;
private TouchAnimator mIconsAlphaAnimatorFixed;
+ private final ActivityStarter mActivityStarter;
+
protected QuickQSPanel mHeaderQsPanel;
private View mDatePrivacyView;
private View mDateView;
@@ -113,6 +119,7 @@ public class QuickStatusBarHeader extends FrameLayout {
public QuickStatusBarHeader(Context context, AttributeSet attrs) {
super(context, attrs);
+ mActivityStarter = Dependency.get(ActivityStarter.class);
}
/**
@@ -144,6 +151,9 @@ public class QuickStatusBarHeader extends FrameLayout {
mClockContainer = findViewById(R.id.clock_container);
mClockView = findViewById(R.id.clock);
+ mClockView.setOnClickListener(
+ v -> mActivityStarter.postStartActivityDismissingKeyguard(
+ new Intent(AlarmClock.ACTION_SHOW_ALARMS), 0));
mDatePrivacySeparator = findViewById(R.id.space);
// Tint for the battery icons are handled in setupHost()
mBatteryRemainingIcon = findViewById(R.id.batteryRemainingIcon);
@@ -388,10 +398,12 @@ public class QuickStatusBarHeader extends FrameLayout {
// Animates the icons and battery indicator from alpha 0 to 1, when the chip is visible
mIconsAlphaAnimator = mIconsAlphaAnimatorFixed;
mIconsAlphaAnimator.setPosition(mKeyguardExpansionFraction);
+ setBatteryRemainingOnClick(false);
} else {
mIconsAlphaAnimator = null;
mIconContainer.setAlpha(1);
mBatteryRemainingIcon.setAlpha(1);
+ setBatteryRemainingOnClick(true);
}
}
@@ -552,6 +564,9 @@ public class QuickStatusBarHeader extends FrameLayout {
public void updateEverything() {
post(() -> setClickable(!mExpanded));
+ if (mExpanded) {
+ setBatteryRemainingOnClick(true);
+ }
}
private void setContentMargins(View view, int marginStart, int marginEnd) {
@@ -570,4 +585,16 @@ public class QuickStatusBarHeader extends FrameLayout {
mStatusIconsView.setScrollY(scrollY);
mDatePrivacyView.setScrollY(scrollY);
}
+
+ private void setBatteryRemainingOnClick(boolean enable) {
+ if (enable) {
+ mBatteryRemainingIcon.setOnClickListener(
+ v -> mActivityStarter.postStartActivityDismissingKeyguard(
+ new Intent(Intent.ACTION_POWER_USAGE_SUMMARY), 0));
+ mBatteryRemainingIcon.setClickable(true);
+ } else {
+ mBatteryRemainingIcon.setOnClickListener(null);
+ mBatteryRemainingIcon.setClickable(false);
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
index 467df1994d44..2ac17179e72a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
@@ -127,8 +127,6 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader
protected void onViewAttached() {
mPrivacyIconsController.onParentVisible();
mPrivacyIconsController.setChipVisibilityListener(this);
- mIconContainer.addIgnoredSlot(
- getResources().getString(com.android.internal.R.string.status_bar_alarm_clock));
mIconContainer.setShouldRestrictIcons(false);
mStatusBarIconController.addIconGroup(mIconManager);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
index a92c7e3c8554..6b66f71870ba 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
@@ -29,8 +29,10 @@ import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.external.CustomTile;
import com.android.systemui.qs.tiles.AirplaneModeTile;
import com.android.systemui.qs.tiles.AlarmTile;
+import com.android.systemui.qs.tiles.AODTile;
import com.android.systemui.qs.tiles.BatterySaverTile;
import com.android.systemui.qs.tiles.BluetoothTile;
+import com.android.systemui.qs.tiles.CaffeineTile;
import com.android.systemui.qs.tiles.CameraToggleTile;
import com.android.systemui.qs.tiles.CastTile;
import com.android.systemui.qs.tiles.CellularTile;
@@ -41,6 +43,7 @@ import com.android.systemui.qs.tiles.DeviceControlsTile;
import com.android.systemui.qs.tiles.DndTile;
import com.android.systemui.qs.tiles.DreamTile;
import com.android.systemui.qs.tiles.FlashlightTile;
+import com.android.systemui.qs.tiles.HeadsUpTile;
import com.android.systemui.qs.tiles.HotspotTile;
import com.android.systemui.qs.tiles.InternetTile;
import com.android.systemui.qs.tiles.LocationTile;
@@ -98,6 +101,9 @@ public class QSFactoryImpl implements QSFactory {
private final Provider<QRCodeScannerTile> mQRCodeScannerTileProvider;
private final Provider<OneHandedModeTile> mOneHandedModeTileProvider;
private final Provider<DreamTile> mDreamTileProvider;
+ private final Provider<AODTile> mAODTileProvider;
+ private final Provider<CaffeineTile> mCaffeineTileProvider;
+ private final Provider<HeadsUpTile> mHeadsUpTileProvider;
private final Lazy<QSHost> mQsHostLazy;
private final Provider<CustomTile.Builder> mCustomTileBuilderProvider;
@@ -135,7 +141,10 @@ public class QSFactoryImpl implements QSFactory {
Provider<QRCodeScannerTile> qrCodeScannerTileProvider,
Provider<OneHandedModeTile> oneHandedModeTileProvider,
Provider<ColorCorrectionTile> colorCorrectionTileProvider,
- Provider<DreamTile> dreamTileProvider) {
+ Provider<DreamTile> dreamTileProvider,
+ Provider<AODTile> aodTileProvider,
+ Provider<CaffeineTile> caffeineTileProvider,
+ Provider<HeadsUpTile> headsUpTileProvider) {
mQsHostLazy = qsHostLazy;
mCustomTileBuilderProvider = customTileBuilderProvider;
@@ -169,6 +178,9 @@ public class QSFactoryImpl implements QSFactory {
mOneHandedModeTileProvider = oneHandedModeTileProvider;
mColorCorrectionTileProvider = colorCorrectionTileProvider;
mDreamTileProvider = dreamTileProvider;
+ mAODTileProvider = aodTileProvider;
+ mCaffeineTileProvider = caffeineTileProvider;
+ mHeadsUpTileProvider = headsUpTileProvider;
}
/** Creates a tile with a type based on {@code tileSpec} */
@@ -184,8 +196,8 @@ public class QSFactoryImpl implements QSFactory {
@Nullable
protected QSTileImpl createTileInternal(String tileSpec) {
- // Stock tiles.
switch (tileSpec) {
+ // Stock tiles.
case "wifi":
return mWifiTileProvider.get();
case "internet":
@@ -244,6 +256,13 @@ public class QSFactoryImpl implements QSFactory {
return mColorCorrectionTileProvider.get();
case "dream":
return mDreamTileProvider.get();
+ // Additional tiles.
+ case "aod":
+ return mAODTileProvider.get();
+ case "caffeine":
+ return mCaffeineTileProvider.get();
+ case "heads_up":
+ return mHeadsUpTileProvider.get();
}
// Custom tiles
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AODTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AODTile.java
new file mode 100644
index 000000000000..37e5716ce5f5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AODTile.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2018 The OmniROM Project
+ * 2020-2021 The LineageOS 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.qs.tiles;
+
+import android.content.Intent;
+import android.os.Handler;
+import android.os.Looper;
+import android.provider.Settings;
+import android.service.quicksettings.Tile;
+import android.view.View;
+
+import androidx.annotation.Nullable;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.systemui.R;
+import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.plugins.FalsingManager;
+import com.android.systemui.plugins.qs.QSTile.BooleanState;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.qs.QSHost;
+import com.android.systemui.qs.SettingObserver;
+import com.android.systemui.qs.logging.QSLogger;
+import com.android.systemui.qs.tileimpl.QSTileImpl;
+import com.android.systemui.settings.UserTracker;
+import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.util.settings.SecureSettings;
+
+import javax.inject.Inject;
+
+public class AODTile extends QSTileImpl<BooleanState> implements
+ BatteryController.BatteryStateChangeCallback {
+
+ private final Icon mIcon = ResourceIcon.get(R.drawable.ic_qs_aod);
+ private final BatteryController mBatteryController;
+
+ private final SettingObserver mSetting;
+
+ @Inject
+ public AODTile(
+ QSHost host,
+ @Background Looper backgroundLooper,
+ @Main Handler mainHandler,
+ FalsingManager falsingManager,
+ MetricsLogger metricsLogger,
+ StatusBarStateController statusBarStateController,
+ ActivityStarter activityStarter,
+ QSLogger qsLogger,
+ SecureSettings secureSettings,
+ BatteryController batteryController,
+ UserTracker userTracker
+ ) {
+ super(host, backgroundLooper, mainHandler, falsingManager, metricsLogger,
+ statusBarStateController, activityStarter, qsLogger);
+
+ mSetting = new SettingObserver(secureSettings, mHandler, Settings.Secure.DOZE_ALWAYS_ON,
+ userTracker.getUserId()) {
+ @Override
+ protected void handleValueChanged(int value, boolean observedChange) {
+ handleRefreshState(value);
+ }
+ };
+
+ mBatteryController = batteryController;
+ batteryController.observe(getLifecycle(), this);
+ }
+
+ @Override
+ public void onPowerSaveChanged(boolean isPowerSave) {
+ refreshState();
+ }
+
+ @Override
+ protected void handleDestroy() {
+ super.handleDestroy();
+ mSetting.setListening(false);
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_dozeAlwaysOnDisplayAvailable);
+ }
+
+ @Override
+ public BooleanState newTileState() {
+ BooleanState state = new BooleanState();
+ state.handlesLongClick = false;
+ return state;
+ }
+
+ @Override
+ public void handleSetListening(boolean listening) {
+ super.handleSetListening(listening);
+ mSetting.setListening(listening);
+ }
+
+ @Override
+ protected void handleUserSwitch(int newUserId) {
+ mSetting.setUserId(newUserId);
+ handleRefreshState(mSetting.getValue());
+ }
+
+ @Override
+ protected void handleClick(@Nullable View view) {
+ mSetting.setValue(mState.value ? 0 : 1);
+ }
+
+ @Override
+ public Intent getLongClickIntent() {
+ return null;
+ }
+
+ @Override
+ public CharSequence getTileLabel() {
+ if (mBatteryController.isAodPowerSave()) {
+ return mContext.getString(R.string.quick_settings_aod_off_powersave_label);
+ }
+ return mContext.getString(R.string.quick_settings_aod_label);
+ }
+
+ @Override
+ protected void handleUpdateState(BooleanState state, Object arg) {
+ final int value = arg instanceof Integer ? (Integer) arg : mSetting.getValue();
+ final boolean enable = value != 0;
+ if (state.slash == null) {
+ state.slash = new SlashState();
+ }
+ state.icon = mIcon;
+ state.value = enable;
+ state.slash.isSlashed = state.value;
+ state.label = mContext.getString(R.string.quick_settings_aod_label);
+ if (mBatteryController.isAodPowerSave()) {
+ state.state = Tile.STATE_UNAVAILABLE;
+ } else {
+ state.state = enable ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
+ }
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsEvent.ICE;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CaffeineTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CaffeineTile.java
new file mode 100644
index 000000000000..340de5648a1b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CaffeineTile.java
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2016 The CyanogenMod Project
+ * Copyright (c) 2017 The LineageOS 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.qs.tiles;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.CountDownTimer;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.PowerManager;
+import android.os.SystemClock;
+import android.service.quicksettings.Tile;
+import android.view.View;
+
+import androidx.annotation.Nullable;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.systemui.R;
+import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.plugins.FalsingManager;
+import com.android.systemui.plugins.qs.QSTile.BooleanState;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.qs.QSHost;
+import com.android.systemui.qs.logging.QSLogger;
+import com.android.systemui.qs.tileimpl.QSTileImpl;
+
+import javax.inject.Inject;
+
+/** Quick settings tile: Caffeine **/
+public class CaffeineTile extends QSTileImpl<BooleanState> {
+
+ private final Icon mIcon = ResourceIcon.get(R.drawable.ic_qs_caffeine);
+
+ private final PowerManager.WakeLock mWakeLock;
+ private int mSecondsRemaining;
+ private int mDuration;
+ private static int[] DURATIONS = new int[] {
+ 5 * 60, // 5 min
+ 10 * 60, // 10 min
+ 30 * 60, // 30 min
+ -1, // infinity
+ };
+ private static final int INFINITE_DURATION_INDEX = DURATIONS.length - 1;
+ private CountDownTimer mCountdownTimer = null;
+ public long mLastClickTime = -1;
+ private final Receiver mReceiver = new Receiver();
+
+ @Inject
+ public CaffeineTile(
+ QSHost host,
+ @Background Looper backgroundLooper,
+ @Main Handler mainHandler,
+ FalsingManager falsingManager,
+ MetricsLogger metricsLogger,
+ StatusBarStateController statusBarStateController,
+ ActivityStarter activityStarter,
+ QSLogger qsLogger
+ ) {
+ super(host, backgroundLooper, mainHandler, falsingManager, metricsLogger,
+ statusBarStateController, activityStarter, qsLogger);
+ mWakeLock = mContext.getSystemService(PowerManager.class).newWakeLock(
+ PowerManager.FULL_WAKE_LOCK, "CaffeineTile");
+ mReceiver.init();
+ }
+
+ @Override
+ public BooleanState newTileState() {
+ return new BooleanState();
+ }
+
+ @Override
+ protected void handleDestroy() {
+ super.handleDestroy();
+ stopCountDown();
+ mReceiver.destroy();
+ if (mWakeLock.isHeld()) {
+ mWakeLock.release();
+ }
+ }
+
+ @Override
+ public void handleSetListening(boolean listening) {
+ }
+
+ @Override
+ protected void handleClick(@Nullable View view) {
+ // If last user clicks < 5 seconds
+ // we cycle different duration
+ // otherwise toggle on/off
+ if (mWakeLock.isHeld() && (mLastClickTime != -1) &&
+ (SystemClock.elapsedRealtime() - mLastClickTime < 5000)) {
+ // cycle duration
+ mDuration++;
+ if (mDuration >= DURATIONS.length) {
+ // all durations cycled, turn if off
+ mDuration = -1;
+ stopCountDown();
+ if (mWakeLock.isHeld()) {
+ mWakeLock.release();
+ }
+ } else {
+ // change duration
+ startCountDown(DURATIONS[mDuration]);
+ if (!mWakeLock.isHeld()) {
+ mWakeLock.acquire();
+ }
+ }
+ } else {
+ // toggle
+ if (mWakeLock.isHeld()) {
+ mWakeLock.release();
+ stopCountDown();
+ } else {
+ mWakeLock.acquire();
+ mDuration = 0;
+ startCountDown(DURATIONS[mDuration]);
+ }
+ }
+ mLastClickTime = SystemClock.elapsedRealtime();
+ refreshState();
+ }
+
+ @Override
+ protected void handleLongClick(@Nullable View view) {
+ if (mWakeLock.isHeld()) {
+ if (mDuration == INFINITE_DURATION_INDEX) {
+ return;
+ }
+ } else {
+ mWakeLock.acquire();
+ }
+ mDuration = INFINITE_DURATION_INDEX;
+ startCountDown(DURATIONS[INFINITE_DURATION_INDEX]);
+ refreshState();
+ }
+
+ @Override
+ public Intent getLongClickIntent() {
+ return null;
+ }
+
+ @Override
+ public CharSequence getTileLabel() {
+ return mContext.getString(R.string.quick_settings_caffeine_label);
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsEvent.ICE;
+ }
+
+ private void startCountDown(long duration) {
+ stopCountDown();
+ mSecondsRemaining = (int)duration;
+ if (duration == -1) {
+ // infinity timing, no need to start timer
+ return;
+ }
+ mCountdownTimer = new CountDownTimer(duration * 1000, 1000) {
+ @Override
+ public void onTick(long millisUntilFinished) {
+ mSecondsRemaining = (int) (millisUntilFinished / 1000);
+ refreshState();
+ }
+
+ @Override
+ public void onFinish() {
+ if (mWakeLock.isHeld())
+ mWakeLock.release();
+ refreshState();
+ }
+
+ }.start();
+ }
+
+ private void stopCountDown() {
+ if (mCountdownTimer != null) {
+ mCountdownTimer.cancel();
+ mCountdownTimer = null;
+ }
+ }
+
+ private String formatValueWithRemainingTime() {
+ if (mSecondsRemaining == -1) {
+ return "\u221E"; // infinity
+ }
+ return String.format("%02d:%02d",
+ mSecondsRemaining / 60 % 60, mSecondsRemaining % 60);
+ }
+
+ @Override
+ protected void handleUpdateState(BooleanState state, Object arg) {
+ state.value = mWakeLock.isHeld();
+ state.icon = mIcon;
+ state.label = mContext.getString(R.string.quick_settings_caffeine_label);
+ if (state.value) {
+ state.secondaryLabel = formatValueWithRemainingTime();
+ state.contentDescription = mContext.getString(
+ R.string.accessibility_quick_settings_caffeine_on);
+ state.state = Tile.STATE_ACTIVE;
+ } else {
+ state.secondaryLabel = null;
+ state.contentDescription = mContext.getString(
+ R.string.accessibility_quick_settings_caffeine_off);
+ state.state = Tile.STATE_INACTIVE;
+ }
+ }
+
+ private final class Receiver extends BroadcastReceiver {
+ public void init() {
+ // Register for Intent broadcasts for...
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_SCREEN_OFF);
+ mContext.registerReceiver(this, filter, null, mHandler);
+ }
+
+ public void destroy() {
+ mContext.unregisterReceiver(this);
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (Intent.ACTION_SCREEN_OFF.equals(action)) {
+ // disable caffeine if user force off (power button)
+ stopCountDown();
+ if (mWakeLock.isHeld())
+ mWakeLock.release();
+ refreshState();
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HeadsUpTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HeadsUpTile.java
new file mode 100644
index 000000000000..8305d6b5f739
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HeadsUpTile.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2015 The CyanogenMod Project
+ * Copyright (C) 2017 The LineageOS 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.qs.tiles;
+
+import android.content.Intent;
+import android.os.Handler;
+import android.os.Looper;
+import android.provider.Settings;
+import android.provider.Settings.Global;
+import android.service.quicksettings.Tile;
+import android.view.View;
+
+import androidx.annotation.Nullable;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.systemui.R;
+import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.plugins.FalsingManager;
+import com.android.systemui.plugins.qs.QSTile.BooleanState;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.qs.QSHost;
+import com.android.systemui.qs.SettingObserver;
+import com.android.systemui.qs.logging.QSLogger;
+import com.android.systemui.qs.tileimpl.QSTileImpl;
+import com.android.systemui.settings.UserTracker;
+import com.android.systemui.util.settings.GlobalSettings;
+
+import javax.inject.Inject;
+
+/** Quick settings tile: Heads up **/
+public class HeadsUpTile extends QSTileImpl<BooleanState> {
+
+ private final Icon mIcon = ResourceIcon.get(R.drawable.ic_qs_heads_up);
+
+ private static final Intent NOTIFICATION_SETTINGS =
+ new Intent("android.settings.NOTIFICATION_SETTINGS");
+
+ private final SettingObserver mSetting;
+
+ @Inject
+ public HeadsUpTile(
+ QSHost host,
+ @Background Looper backgroundLooper,
+ @Main Handler mainHandler,
+ FalsingManager falsingManager,
+ MetricsLogger metricsLogger,
+ StatusBarStateController statusBarStateController,
+ ActivityStarter activityStarter,
+ QSLogger qsLogger,
+ GlobalSettings globalSettings,
+ UserTracker userTracker
+ ) {
+ super(host, backgroundLooper, mainHandler, falsingManager, metricsLogger,
+ statusBarStateController, activityStarter, qsLogger);
+
+ mSetting = new SettingObserver(globalSettings, mHandler,
+ Global.HEADS_UP_NOTIFICATIONS_ENABLED, userTracker.getUserId()) {
+ @Override
+ protected void handleValueChanged(int value, boolean observedChange) {
+ handleRefreshState(value);
+ }
+ };
+ }
+
+ @Override
+ public BooleanState newTileState() {
+ return new BooleanState();
+ }
+
+ @Override
+ protected void handleClick(@Nullable View view) {
+ setEnabled(!mState.value);
+ refreshState();
+ }
+
+ @Override
+ public Intent getLongClickIntent() {
+ return NOTIFICATION_SETTINGS;
+ }
+
+ private void setEnabled(boolean enabled) {
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED,
+ enabled ? 1 : 0);
+ }
+
+ @Override
+ protected void handleUpdateState(BooleanState state, Object arg) {
+ final int value = arg instanceof Integer ? (Integer) arg : mSetting.getValue();
+ final boolean headsUp = value != 0;
+ state.value = headsUp;
+ state.label = mContext.getString(R.string.quick_settings_heads_up_label);
+ state.icon = mIcon;
+ if (headsUp) {
+ state.contentDescription = mContext.getString(
+ R.string.accessibility_quick_settings_heads_up_on);
+ state.state = Tile.STATE_ACTIVE;
+ } else {
+ state.contentDescription = mContext.getString(
+ R.string.accessibility_quick_settings_heads_up_off);
+ state.state = Tile.STATE_INACTIVE;
+ }
+ }
+
+ @Override
+ public CharSequence getTileLabel() {
+ return mContext.getString(R.string.quick_settings_heads_up_label);
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsEvent.ICE;
+ }
+
+ @Override
+ public void handleSetListening(boolean listening) {
+ // Do nothing
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java
index a61f0ce0c864..ac07acd5dd2a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java
@@ -85,6 +85,7 @@ public class NfcTile extends QSTileImpl<BooleanState> {
@Override
public void handleSetListening(boolean listening) {
super.handleSetListening(listening);
+ if (mListening == listening) return;
mListening = listening;
if (mListening) {
mBroadcastDispatcher.registerReceiver(mNfcReceiver,
@@ -151,7 +152,7 @@ public class NfcTile extends QSTileImpl<BooleanState> {
private NfcAdapter getAdapter() {
if (mAdapter == null) {
try {
- mAdapter = NfcAdapter.getDefaultAdapter(mContext);
+ mAdapter = NfcAdapter.getNfcAdapter(mContext.getApplicationContext());
} catch (UnsupportedOperationException e) {
mAdapter = null;
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
index 5716a1d7260c..bd6b62e73868 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
@@ -252,7 +252,7 @@ public class ScreenshotController {
// From WizardManagerHelper.java
private static final String SETTINGS_SECURE_USER_SETUP_COMPLETE = "user_setup_complete";
- private static final int SCREENSHOT_CORNER_DEFAULT_TIMEOUT_MILLIS = 6000;
+ private static final int SCREENSHOT_CORNER_DEFAULT_TIMEOUT_MILLIS = 3000;
private final WindowContext mContext;
private final FeatureFlags mFlags;
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
index e8ceb521b6b0..18b6444912ea 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
@@ -120,8 +120,8 @@ public class ScreenshotView extends FrameLayout implements
private static final long SCREENSHOT_TO_CORNER_X_DURATION_MS = 234;
private static final long SCREENSHOT_TO_CORNER_Y_DURATION_MS = 500;
private static final long SCREENSHOT_TO_CORNER_SCALE_DURATION_MS = 234;
- private static final long SCREENSHOT_ACTIONS_EXPANSION_DURATION_MS = 400;
- private static final long SCREENSHOT_ACTIONS_ALPHA_DURATION_MS = 100;
+ private static final long SCREENSHOT_ACTIONS_EXPANSION_DURATION_MS = 300;
+ private static final long SCREENSHOT_ACTIONS_ALPHA_DURATION_MS = 75;
private static final float SCREENSHOT_ACTIONS_START_SCALE_X = .7f;
private static final int SWIPE_PADDING_DP = 12; // extra padding around views to allow swipe
diff --git a/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt b/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt
index e406be1ea0a3..83c395b5a06f 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt
@@ -18,10 +18,12 @@ package com.android.systemui.shade
import android.annotation.IdRes
import android.app.StatusBarManager
+import android.content.Intent
import android.content.res.Configuration
import android.os.Bundle
import android.os.Trace
import android.os.Trace.TRACE_TAG_APP
+import android.provider.AlarmClock
import android.util.Pair
import android.view.View
import android.view.WindowInsets
@@ -40,6 +42,7 @@ import com.android.systemui.demomode.DemoModeController
import com.android.systemui.dump.DumpManager
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
+import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.qs.ChipVisibilityListener
import com.android.systemui.qs.HeaderPrivacyIconsController
import com.android.systemui.qs.carrier.QSCarrierGroup
@@ -91,7 +94,8 @@ class LargeScreenShadeHeaderController @Inject constructor(
private val featureFlags: FeatureFlags,
private val qsCarrierGroupControllerBuilder: QSCarrierGroupController.Builder,
private val combinedShadeHeadersConstraintManager: CombinedShadeHeadersConstraintManager,
- private val demoModeController: DemoModeController
+ private val demoModeController: DemoModeController,
+ private val activityStarter: ActivityStarter
) : ViewController<View>(header), Dumpable {
companion object {
@@ -282,16 +286,21 @@ class LargeScreenShadeHeaderController @Inject constructor(
.setQSCarrierGroup(qsCarrierGroup)
.build()
- if (!combinedHeaders) {
- // In the new header, we display alarm icon but we ignore it when not using the new
- // headers.
- iconContainer.addIgnoredSlot(
- context.getString(com.android.internal.R.string.status_bar_alarm_clock)
- )
- }
if (combinedHeaders) {
privacyIconsController.onParentVisible()
}
+
+ clock.setOnClickListener {
+ activityStarter.postStartActivityDismissingKeyguard(
+ Intent(AlarmClock.ACTION_SHOW_ALARMS), 0
+ )
+ }
+
+ batteryIcon.setOnClickListener {
+ activityStarter.postStartActivityDismissingKeyguard(
+ Intent(Intent.ACTION_POWER_USAGE_SUMMARY), 0
+ )
+ }
}
override fun onViewAttached() {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 0a4f786dadfe..28f526c5940f 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -80,6 +80,7 @@ import android.transition.TransitionValues;
import android.util.IndentingPrintWriter;
import android.util.Log;
import android.util.MathUtils;
+import android.view.GestureDetector;
import android.view.InputDevice;
import android.view.LayoutInflater;
import android.view.MotionEvent;
@@ -224,6 +225,7 @@ import com.android.systemui.statusbar.policy.KeyguardUserSwitcherController;
import com.android.systemui.statusbar.policy.KeyguardUserSwitcherView;
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
import com.android.systemui.statusbar.window.StatusBarWindowStateController;
+import com.android.systemui.tuner.TunerService;
import com.android.systemui.unfold.SysUIUnfoldComponent;
import com.android.systemui.util.Compile;
import com.android.systemui.util.LargeScreenUtils;
@@ -287,6 +289,10 @@ public final class NotificationPanelViewController implements Dumpable {
private static final String COUNTER_PANEL_OPEN = "panel_open";
private static final String COUNTER_PANEL_OPEN_QS = "panel_open_qs";
private static final String COUNTER_PANEL_OPEN_PEEK = "panel_open_peek";
+
+ private static final String DOUBLE_TAP_SLEEP_GESTURE =
+ "system:" + Settings.System.DOUBLE_TAP_SLEEP_GESTURE;
+
private static final Rect M_DUMMY_DIRTY_RECT = new Rect(0, 0, 1, 1);
private static final Rect EMPTY_RECT = new Rect();
/**
@@ -362,6 +368,7 @@ public final class NotificationPanelViewController implements Dumpable {
private final FragmentListener mQsFragmentListener = new QsFragmentListener();
private final AccessibilityDelegate mAccessibilityDelegate = new ShadeAccessibilityDelegate();
private final NotificationGutsManager mGutsManager;
+ private final TunerService mTunerService;
private long mDownTime;
private boolean mTouchSlopExceededBeforeDown;
@@ -552,6 +559,8 @@ public final class NotificationPanelViewController implements Dumpable {
private final NotificationShadeDepthController mDepthController;
private final NavigationBarController mNavigationBarController;
private final int mDisplayId;
+ private boolean mDoubleTapToSleepEnabled;
+ private GestureDetector mDoubleTapGesture;
private final KeyguardIndicationController mKeyguardIndicationController;
private int mHeadsUpInset;
@@ -800,7 +809,8 @@ public final class NotificationPanelViewController implements Dumpable {
OccludedToLockscreenTransitionViewModel occludedToLockscreenTransitionViewModel,
@Main CoroutineDispatcher mainDispatcher,
KeyguardTransitionInteractor keyguardTransitionInteractor,
- DumpManager dumpManager) {
+ DumpManager dumpManager,
+ TunerService tunerService) {
keyguardStateController.addCallback(new KeyguardStateController.Callback() {
@Override
public void onKeyguardFadingAwayChanged() {
@@ -891,6 +901,7 @@ public final class NotificationPanelViewController implements Dumpable {
LargeScreenUtils.shouldUseSplitNotificationShade(mResources);
mView.setWillNotDraw(!DEBUG_DRAWABLE);
mLargeScreenShadeHeaderController = largeScreenShadeHeaderController;
+ mTunerService = tunerService;
mLayoutInflater = layoutInflater;
mFeatureFlags = featureFlags;
mFalsingCollector = falsingCollector;
@@ -933,6 +944,16 @@ public final class NotificationPanelViewController implements Dumpable {
});
mBottomAreaShadeAlphaAnimator.setDuration(160);
mBottomAreaShadeAlphaAnimator.setInterpolator(Interpolators.ALPHA_OUT);
+ mDoubleTapGesture = new GestureDetector(mView.getContext(),
+ new GestureDetector.SimpleOnGestureListener() {
+ @Override
+ public boolean onDoubleTap(MotionEvent e) {
+ if (mPowerManager != null) {
+ mPowerManager.goToSleep(e.getEventTime());
+ }
+ return true;
+ }
+ });
mConversationNotificationManager = conversationNotificationManager;
mAuthController = authController;
mLockIconViewController = lockIconViewController;
@@ -5754,7 +5775,8 @@ public final class NotificationPanelViewController implements Dumpable {
positionClockAndNotifications(true /* forceUpdate */);
}
- private final class ShadeAttachStateChangeListener implements View.OnAttachStateChangeListener {
+ private final class ShadeAttachStateChangeListener implements View.OnAttachStateChangeListener,
+ TunerService.Tunable {
@Override
public void onViewAttachedToWindow(View v) {
mFragmentService.getFragmentHostManager(mView)
@@ -5762,6 +5784,7 @@ public final class NotificationPanelViewController implements Dumpable {
mStatusBarStateController.addCallback(mStatusBarStateListener);
mStatusBarStateListener.onStateChanged(mStatusBarStateController.getState());
mConfigurationController.addCallback(mConfigurationListener);
+ mTunerService.addTunable(this, DOUBLE_TAP_SLEEP_GESTURE);
// Theme might have changed between inflating this view and attaching it to the
// window, so
// force a call to onThemeChanged
@@ -5779,6 +5802,14 @@ public final class NotificationPanelViewController implements Dumpable {
mStatusBarStateController.removeCallback(mStatusBarStateListener);
mConfigurationController.removeCallback(mConfigurationListener);
mFalsingManager.removeTapListener(mFalsingTapListener);
+ mTunerService.removeTunable(this);
+ }
+
+ @Override
+ public void onTuningChanged(String key, String newValue) {
+ if (DOUBLE_TAP_SLEEP_GESTURE.equals(key)) {
+ mDoubleTapToSleepEnabled = TunerService.parseIntegerSwitch(newValue, true);
+ }
}
}
@@ -6121,6 +6152,10 @@ public final class NotificationPanelViewController implements Dumpable {
return false;
}
+ if (mDoubleTapToSleepEnabled && !mPulsing && !mDozing && mBarState == StatusBarState.KEYGUARD) {
+ mDoubleTapGesture.onTouchEvent(event);
+ }
+
// Make sure the next touch won't the blocked after the current ends.
if (event.getAction() == MotionEvent.ACTION_UP
|| event.getAction() == MotionEvent.ACTION_CANCEL) {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/PulsingGestureListener.kt b/packages/SystemUI/src/com/android/systemui/shade/PulsingGestureListener.kt
index db700650e46c..41aeff9533a0 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/PulsingGestureListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/PulsingGestureListener.kt
@@ -59,10 +59,13 @@ class PulsingGestureListener @Inject constructor(
) : GestureDetector.SimpleOnGestureListener(), Dumpable {
private var doubleTapEnabled = false
private var singleTapEnabled = false
+ private var doubleTapEnabledNative = false
init {
- val tunable = Tunable { key: String?, _: String? ->
+ val tunable = Tunable { key: String?, value: String? ->
when (key) {
+ Settings.Secure.DOUBLE_TAP_TO_WAKE ->
+ doubleTapEnabledNative = TunerService.parseIntegerSwitch(value, false)
Settings.Secure.DOZE_DOUBLE_TAP_GESTURE ->
doubleTapEnabled = ambientDisplayConfiguration.doubleTapGestureEnabled(
UserHandle.USER_CURRENT)
@@ -72,6 +75,7 @@ class PulsingGestureListener @Inject constructor(
}
}
tunerService.addTunable(tunable,
+ Settings.Secure.DOUBLE_TAP_TO_WAKE,
Settings.Secure.DOZE_DOUBLE_TAP_GESTURE,
Settings.Secure.DOZE_TAP_SCREEN_GESTURE)
@@ -109,7 +113,7 @@ class PulsingGestureListener @Inject constructor(
// checks MUST be on the ACTION_UP event.
if (e.actionMasked == MotionEvent.ACTION_UP &&
statusBarStateController.isDozing &&
- (doubleTapEnabled || singleTapEnabled) &&
+ (doubleTapEnabled || singleTapEnabled || doubleTapEnabledNative) &&
!falsingManager.isProximityNear &&
!falsingManager.isFalseDoubleTap
) {
@@ -127,6 +131,7 @@ class PulsingGestureListener @Inject constructor(
override fun dump(pw: PrintWriter, args: Array<out String>) {
pw.println("singleTapEnabled=$singleTapEnabled")
pw.println("doubleTapEnabled=$doubleTapEnabled")
+ pw.println("doubleTapEnabledNative=$doubleTapEnabledNative")
pw.println("isDocked=${dockManager.isDocked}")
pw.println("isProxCovered=${falsingManager.isProximityNear}")
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 6a658b6ee047..3301d6907a25 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -304,10 +304,12 @@ public class KeyguardIndicationController {
R.id.keyguard_indication_text_bottom);
mInitialTextColorState = mTopIndicationView != null
? mTopIndicationView.getTextColors() : ColorStateList.valueOf(Color.WHITE);
- mRotateTextViewController = new KeyguardIndicationRotateTextViewController(
- mLockScreenIndicationView,
- mExecutor,
- mStatusBarStateController);
+ if (mRotateTextViewController == null || !mRotateTextViewController.isAttachedToWindow()) {
+ mRotateTextViewController = new KeyguardIndicationRotateTextViewController(
+ mLockScreenIndicationView,
+ mExecutor,
+ mStatusBarStateController);
+ }
updateDeviceEntryIndication(false /* animate */);
updateOrganizedOwnedDevice();
if (mBroadcastReceiver == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
index 2dad8e053ee1..3b3a19942736 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
@@ -362,7 +362,10 @@ public class CentralSurfacesCommandQueueCallbacks implements CommandQueue.Callba
mPowerManager.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_CAMERA_LAUNCH,
"com.android.systemui:CAMERA_GESTURE");
}
- vibrateForCameraGesture();
+
+ if (source != StatusBarManager.CAMERA_LAUNCH_SOURCE_SCREEN_GESTURE) {
+ vibrateForCameraGesture();
+ }
if (source == StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP) {
Log.v(CentralSurfaces.TAG, "Camera launch");
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index e29305d54a10..8273a11a94f4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -1470,6 +1470,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
filter.addAction(Intent.ACTION_SCREEN_OFF);
+ filter.addAction(Intent.ACTION_SCREEN_CAMERA_GESTURE);
mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter, null, UserHandle.ALL);
}
@@ -2562,6 +2563,21 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
finishBarAnimations();
resetUserExpandedStates();
}
+ else if (Intent.ACTION_SCREEN_CAMERA_GESTURE.equals(action)) {
+ boolean userSetupComplete = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.USER_SETUP_COMPLETE, 0) != 0;
+ if (!userSetupComplete) {
+ if (DEBUG) Log.d(TAG, String.format(
+ "userSetupComplete = %s, ignoring camera launch gesture.",
+ userSetupComplete));
+ return;
+ }
+
+ // This gets executed before we will show Keyguard, so post it in order that the
+ // state is correct.
+ mMainExecutor.execute(() -> mCommandQueueCallbacks.onCameraLaunchGestureDetected(
+ StatusBarManager.CAMERA_LAUNCH_SOURCE_SCREEN_GESTURE));
+ }
Trace.endSection();
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index 2ec7df9e6f16..a2c8b24248cf 100755
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -344,6 +344,9 @@ public class PhoneStatusBarPolicy
mRecordingController.addCallback(this);
mCommandQueue.addCallback(this);
+
+ // Get initial user setup state
+ onUserSetupChanged();
}
private String getManagedProfileAccessibilityString() {
diff --git a/packages/SystemUI/src/com/android/systemui/toast/SystemUIToast.java b/packages/SystemUI/src/com/android/systemui/toast/SystemUIToast.java
index 05e566690f57..29f16c7b924a 100644
--- a/packages/SystemUI/src/com/android/systemui/toast/SystemUIToast.java
+++ b/packages/SystemUI/src/com/android/systemui/toast/SystemUIToast.java
@@ -272,10 +272,10 @@ public class SystemUIToast implements ToastPlugin.Toast {
private static boolean showApplicationIcon(ApplicationInfo appInfo,
PackageManager packageManager) {
- if (hasFlag(appInfo.flags, FLAG_UPDATED_SYSTEM_APP)) {
+ if (hasFlag(appInfo.flags, FLAG_UPDATED_SYSTEM_APP | FLAG_SYSTEM)) {
return packageManager.getLaunchIntentForPackage(appInfo.packageName) != null;
}
- return !hasFlag(appInfo.flags, FLAG_SYSTEM);
+ return true;
}
private static boolean hasFlag(int flags, int flag) {
diff --git a/packages/SystemUI/src/com/android/systemui/tristate/TriStateUiController.java b/packages/SystemUI/src/com/android/systemui/tristate/TriStateUiController.java
new file mode 100644
index 000000000000..5fed8858c34d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/tristate/TriStateUiController.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2019 Paranoid Android
+ *
+ * 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.tristate;
+
+import com.android.systemui.plugins.Plugin;
+import com.android.systemui.plugins.VolumeDialog.Callback;
+import com.android.systemui.plugins.annotations.DependsOn;
+import com.android.systemui.plugins.annotations.ProvidesInterface;
+
+@DependsOn(target = Callback.class)
+@ProvidesInterface(action = "com.android.systemui.action.PLUGIN_TRI_STATE_UI", version = 1)
+public interface TriStateUiController extends Plugin {
+
+ public interface UserActivityListener {
+ void onTriStateUserActivity();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/tristate/TriStateUiControllerImpl.java b/packages/SystemUI/src/com/android/systemui/tristate/TriStateUiControllerImpl.java
new file mode 100644
index 000000000000..5779cbceba41
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/tristate/TriStateUiControllerImpl.java
@@ -0,0 +1,503 @@
+/*
+ * Copyright 2019 Paranoid Android
+ *
+ * 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.tristate;
+
+import static android.view.Surface.ROTATION_90;
+import static android.view.Surface.ROTATION_180;
+import static android.view.Surface.ROTATION_270;
+
+import android.app.Dialog;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.ColorStateList;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.drawable.ColorDrawable;
+import android.hardware.display.DisplayManagerGlobal;
+import android.media.AudioManager;
+import android.os.Build;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.provider.Settings;
+import android.util.Log;
+import android.view.Display;
+import android.view.OrientationEventListener;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager.LayoutParams;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.internal.policy.SystemBarUtils;
+import com.android.systemui.Dependency;
+import com.android.systemui.R;
+import com.android.systemui.tristate.TriStateUiController;
+import com.android.systemui.tristate.TriStateUiController.UserActivityListener;
+import com.android.systemui.plugins.VolumeDialogController;
+import com.android.systemui.plugins.VolumeDialogController.Callbacks;
+import com.android.systemui.plugins.VolumeDialogController.State;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
+
+public class TriStateUiControllerImpl implements ConfigurationListener, TriStateUiController {
+
+ private static String TAG = "TriStateUiControllerImpl";
+
+ private static final int MSG_DIALOG_SHOW = 1;
+ private static final int MSG_DIALOG_DISMISS = 2;
+ private static final int MSG_RESET_SCHEDULE = 3;
+ private static final int MSG_STATE_CHANGE = 4;
+
+ private static final int MODE_NORMAL = AudioManager.RINGER_MODE_NORMAL;
+ private static final int MODE_SILENT = AudioManager.RINGER_MODE_SILENT;
+ private static final int MODE_VIBRATE = AudioManager.RINGER_MODE_VIBRATE;
+
+ private static final int TRI_STATE_UI_POSITION_LEFT = 0;
+ private static final int TRI_STATE_UI_POSITION_RIGHT = 1;
+
+ private static final int DIALOG_TIMEOUT = 2000;
+
+ private Context mContext;
+ private final VolumeDialogController mVolumeDialogController;
+ private final Callbacks mVolumeDialogCallback = new Callbacks() {
+ @Override
+ public void onShowRequested(int reason, boolean keyguardLocked, int lockTaskModeState) { }
+
+ @Override
+ public void onDismissRequested(int reason) { }
+
+ @Override
+ public void onScreenOff() { }
+
+ @Override
+ public void onStateChanged(State state) { }
+
+ @Override
+ public void onLayoutDirectionChanged(int layoutDirection) { }
+
+ @Override
+ public void onShowVibrateHint() { }
+
+ @Override
+ public void onShowSilentHint() { }
+
+ @Override
+ public void onShowSafetyWarning(int flags) { }
+
+ @Override
+ public void onAccessibilityModeChanged(Boolean showA11yStream) { }
+
+ @Override
+ public void onCaptionComponentStateChanged(
+ Boolean isComponentEnabled, Boolean fromTooltip) {}
+
+ @Override
+ public void onConfigurationChanged() {
+ updateTheme();
+ updateTriStateLayout();
+ }
+ };
+
+ private int mDensity;
+ private Dialog mDialog;
+ private int mDialogPosition;
+ private ViewGroup mDialogView;
+ private final H mHandler;
+ private UserActivityListener mListener;
+ OrientationEventListener mOrientationListener;
+ private int mOrientationType = 0;
+ private boolean mShowing = false;
+ private int mBackgroundColor = 0;
+ private int mThemeMode = 0;
+ private int mIconColor = 0;
+ private int mTextColor = 0;
+ private ImageView mTriStateIcon;
+ private TextView mTriStateText;
+ private int mTriStateMode = -1;
+ private Window mWindow;
+ private LayoutParams mWindowLayoutParams;
+ private int mWindowType;
+
+ private final BroadcastReceiver mRingerStateReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ updateRingerModeChanged();
+ }
+ };
+
+ private final class H extends Handler {
+ private TriStateUiControllerImpl mUiController;
+
+ public H(TriStateUiControllerImpl uiController) {
+ super(Looper.getMainLooper());
+ mUiController = uiController;
+ }
+
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_DIALOG_SHOW:
+ mUiController.handleShow();
+ return;
+ case MSG_DIALOG_DISMISS:
+ mUiController.handleDismiss();
+ return;
+ case MSG_RESET_SCHEDULE:
+ mUiController.handleResetTimeout();
+ return;
+ case MSG_STATE_CHANGE:
+ mUiController.handleStateChanged();
+ return;
+ default:
+ return;
+ }
+ }
+ }
+
+ public TriStateUiControllerImpl(Context context) {
+ mContext = context;
+ mHandler = new H(this);
+ mOrientationListener = new OrientationEventListener(mContext, 3) {
+ @Override
+ public void onOrientationChanged(int orientation) {
+ checkOrientationType();
+ }
+ };
+ mVolumeDialogController =
+ (VolumeDialogController) Dependency.get(VolumeDialogController.class);
+ IntentFilter ringerChanged = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION);
+ mContext.registerReceiver(mRingerStateReceiver, ringerChanged);
+ }
+
+ private void checkOrientationType() {
+ Display display = DisplayManagerGlobal.getInstance().getRealDisplay(0);
+ if (display != null) {
+ int rotation = display.getRotation();
+ if (rotation != mOrientationType) {
+ mOrientationType = rotation;
+ updateTriStateLayout();
+ }
+ }
+ }
+
+ public void init(int windowType, UserActivityListener listener) {
+ mWindowType = windowType;
+ mDensity = mContext.getResources().getConfiguration().densityDpi;
+ mListener = listener;
+ ((ConfigurationController) Dependency.get(
+ ConfigurationController.class)).addCallback(this);
+ mVolumeDialogController.addCallback(mVolumeDialogCallback, mHandler);
+ initDialog();
+ }
+
+ public void destroy() {
+ ((ConfigurationController) Dependency.get(
+ ConfigurationController.class)).removeCallback(this);
+ mVolumeDialogController.removeCallback(mVolumeDialogCallback);
+ mContext.unregisterReceiver(mRingerStateReceiver);
+ }
+
+ private void initDialog() {
+ if (mDialog != null) {
+ mDialog.dismiss();
+ mDialog = null;
+ }
+ mDialog = new Dialog(mContext);
+ mShowing = false;
+ mWindow = mDialog.getWindow();
+ mWindow.requestFeature(Window.FEATURE_NO_TITLE);
+ mWindow.setBackgroundDrawable(new ColorDrawable(0));
+ mWindow.clearFlags(LayoutParams.FLAG_DIM_BEHIND);
+ mWindow.addFlags(LayoutParams.FLAG_NOT_FOCUSABLE
+ | LayoutParams.FLAG_LAYOUT_IN_SCREEN
+ | LayoutParams.FLAG_NOT_TOUCH_MODAL
+ | LayoutParams.FLAG_SHOW_WHEN_LOCKED
+ | LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
+ | LayoutParams.FLAG_HARDWARE_ACCELERATED);
+ mDialog.setCanceledOnTouchOutside(false);
+ mWindowLayoutParams = mWindow.getAttributes();
+ mWindowLayoutParams.type = mWindowType;
+ mWindowLayoutParams.format = -3;
+ mWindowLayoutParams.setTitle(TriStateUiControllerImpl.class.getSimpleName());
+ mWindowLayoutParams.gravity = 53;
+ mWindowLayoutParams.y = mDialogPosition;
+ mWindow.setAttributes(mWindowLayoutParams);
+ mWindow.setSoftInputMode(LayoutParams.SOFT_INPUT_ADJUST_NOTHING);
+ mDialog.setContentView(R.layout.tri_state_dialog);
+ mDialogView = (ViewGroup) mDialog.findViewById(R.id.tri_state_layout);
+ mTriStateIcon = (ImageView) mDialog.findViewById(R.id.tri_state_icon);
+ mTriStateText = (TextView) mDialog.findViewById(R.id.tri_state_text);
+ updateTheme();
+ }
+
+ public void show() {
+ mHandler.obtainMessage(MSG_DIALOG_SHOW, 0, 0).sendToTarget();
+ }
+
+ private void registerOrientationListener(boolean enable) {
+ if (mOrientationListener.canDetectOrientation() && enable) {
+ Log.v(TAG, "Can detect orientation");
+ mOrientationListener.enable();
+ return;
+ }
+ Log.v(TAG, "Cannot detect orientation");
+ mOrientationListener.disable();
+ }
+
+ private void updateTriStateLayout() {
+ if (mContext != null) {
+ int iconId = 0;
+ int textId = 0;
+ int bg = 0;
+ Resources res = mContext.getResources();
+ if (res != null) {
+ int positionY;
+ int positionY2 = mWindowLayoutParams.y;
+ int positionX = mWindowLayoutParams.x;
+ int gravity = mWindowLayoutParams.gravity;
+ switch (mTriStateMode) {
+ case MODE_SILENT:
+ iconId = R.drawable.ic_volume_ringer_mute;
+ textId = R.string.volume_ringer_status_silent;
+ break;
+ case MODE_VIBRATE:
+ iconId = R.drawable.ic_volume_ringer_vibrate;
+ textId = R.string.volume_ringer_status_vibrate;
+ break;
+ case MODE_NORMAL:
+ iconId = R.drawable.ic_volume_ringer;
+ textId = R.string.volume_ringer_status_normal;
+ break;
+ }
+ int triStatePos = res.getInteger(
+ com.android.internal.R.integer.config_alertSliderLocation);
+ boolean isTsKeyRight = true;
+ if (triStatePos == TRI_STATE_UI_POSITION_LEFT) {
+ isTsKeyRight = false;
+ } else if (triStatePos == TRI_STATE_UI_POSITION_RIGHT) {
+ isTsKeyRight = true;
+ }
+ switch (mOrientationType) {
+ case ROTATION_90:
+ if (isTsKeyRight) {
+ gravity = 51;
+ } else {
+ gravity = 83;
+ }
+ positionY2 = res.getDimensionPixelSize(
+ R.dimen.tri_state_up_dialog_position_deep_land);
+ if (isTsKeyRight) {
+ positionY2 += SystemBarUtils.getStatusBarHeight(mContext);
+ }
+ if (mTriStateMode == MODE_SILENT) {
+ positionX = res.getDimensionPixelSize(
+ R.dimen.tri_state_up_dialog_position_l);
+ } else if (mTriStateMode == MODE_VIBRATE) {
+ positionX = res.getDimensionPixelSize(
+ R.dimen.tri_state_middle_dialog_position_l);
+ } else if (mTriStateMode == MODE_NORMAL) {
+ positionX = res.getDimensionPixelSize(
+ R.dimen.tri_state_down_dialog_position_l);
+ }
+ bg = R.drawable.dialog_tri_state_middle_bg;
+ break;
+ case ROTATION_180:
+ if (isTsKeyRight) {
+ gravity = 83;
+ } else {
+ gravity = 85;
+ }
+ positionX = res.getDimensionPixelSize(
+ R.dimen.tri_state_up_dialog_position_deep);
+ positionY2 = SystemBarUtils.getStatusBarHeight(mContext);
+ bg = R.drawable.dialog_tri_state_middle_bg;
+ if (mTriStateMode != MODE_SILENT) {
+ if (mTriStateMode != MODE_VIBRATE) {
+ if (mTriStateMode == MODE_NORMAL) {
+ positionY2 += res.getDimensionPixelSize(
+ R.dimen.tri_state_down_dialog_position);
+ break;
+ }
+ }
+ positionY2 += res.getDimensionPixelSize(
+ R.dimen.tri_state_middle_dialog_position);
+ break;
+ }
+ positionY2 += res.getDimensionPixelSize(R.dimen.tri_state_up_dialog_position);
+ break;
+ case ROTATION_270:
+ if (isTsKeyRight) {
+ gravity = 85;
+ } else {
+ gravity = 53;
+ }
+ positionY2 = res.getDimensionPixelSize(
+ R.dimen.tri_state_up_dialog_position_deep_land);
+ if (!isTsKeyRight) {
+ positionY2 += SystemBarUtils.getStatusBarHeight(mContext);
+ }
+ if (mTriStateMode == MODE_SILENT) {
+ positionX = res.getDimensionPixelSize(
+ R.dimen.tri_state_up_dialog_position_l);
+ } else if (mTriStateMode == MODE_VIBRATE) {
+ positionX = res.getDimensionPixelSize(
+ R.dimen.tri_state_middle_dialog_position_l);
+ } else if (mTriStateMode == MODE_NORMAL) {
+ positionX = res.getDimensionPixelSize(
+ R.dimen.tri_state_down_dialog_position_l);
+ }
+ bg = R.drawable.dialog_tri_state_middle_bg;
+ break;
+ default:
+ if (isTsKeyRight) {
+ gravity = 53;
+ } else {
+ gravity = 51;
+ }
+ positionX = res.getDimensionPixelSize(
+ R.dimen.tri_state_up_dialog_position_deep);
+ if (mTriStateMode != MODE_SILENT) {
+ if (mTriStateMode != MODE_VIBRATE) {
+ if (mTriStateMode == MODE_NORMAL) {
+ positionY2 = res.getDimensionPixelSize(
+ R.dimen.tri_state_down_dialog_position)
+ + SystemBarUtils.getStatusBarHeight(mContext);
+ bg = R.drawable.dialog_tri_state_down_bg;
+ break;
+ }
+ }
+ positionY2 = res.getDimensionPixelSize(
+ R.dimen.tri_state_middle_dialog_position)
+ + SystemBarUtils.getStatusBarHeight(mContext);
+ bg = R.drawable.dialog_tri_state_middle_bg;
+ break;
+ }
+ positionY2 = res.getDimensionPixelSize(
+ R.dimen.tri_state_up_dialog_position)
+ + SystemBarUtils.getStatusBarHeight(mContext);
+ bg = R.drawable.dialog_tri_state_up_bg;
+ break;
+ }
+ if (mTriStateMode != -1) {
+ if (mTriStateIcon != null && iconId != 0) {
+ mTriStateIcon.setImageResource(iconId);
+ }
+ if (mTriStateText != null && textId != 0) {
+ String inputText = res.getString(textId);
+ if (inputText != null && mTriStateText.length() == inputText.length()) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(inputText);
+ sb.append(" ");
+ inputText = sb.toString();
+ }
+ mTriStateText.setText(inputText);
+ }
+ if (mDialogView != null && bg != 0) {
+ mDialogView.setBackgroundDrawable(res.getDrawable(bg));
+ }
+ mDialogPosition = positionY2;
+ }
+ positionY = res.getDimensionPixelSize(R.dimen.tri_state_dialog_padding);
+ mWindowLayoutParams.gravity = gravity;
+ mWindowLayoutParams.y = positionY2 - positionY;
+ mWindowLayoutParams.x = positionX - positionY;
+ mWindow.setAttributes(mWindowLayoutParams);
+ handleResetTimeout();
+ }
+ }
+ }
+
+ private void updateRingerModeChanged() {
+ mHandler.obtainMessage(MSG_STATE_CHANGE, 0, 0).sendToTarget();
+ if (mTriStateMode != -1) {
+ show();
+ }
+ }
+
+ private void handleShow() {
+ mHandler.removeMessages(MSG_DIALOG_SHOW);
+ mHandler.removeMessages(MSG_DIALOG_DISMISS);
+ handleResetTimeout();
+ if (!mShowing) {
+ updateTheme();
+ registerOrientationListener(true);
+ checkOrientationType();
+ mShowing = true;
+ mDialog.show();
+ if (mListener != null) {
+ mListener.onTriStateUserActivity();
+ }
+ }
+ }
+
+ private void handleDismiss() {
+ mHandler.removeMessages(MSG_DIALOG_SHOW);
+ mHandler.removeMessages(MSG_DIALOG_DISMISS);
+ if (mShowing) {
+ registerOrientationListener(false);
+ mShowing = false;
+ mDialog.dismiss();
+ }
+ }
+
+ private void handleStateChanged() {
+ AudioManager am = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+ int ringerMode = am.getRingerModeInternal();
+ if (ringerMode != mTriStateMode) {
+ mTriStateMode = ringerMode;
+ updateTriStateLayout();
+ if (mListener != null) {
+ mListener.onTriStateUserActivity();
+ }
+ }
+ }
+
+ public void handleResetTimeout() {
+ mHandler.removeMessages(MSG_DIALOG_DISMISS);
+ mHandler.sendMessageDelayed(mHandler.obtainMessage(
+ MSG_DIALOG_DISMISS, MSG_RESET_SCHEDULE, 0), (long) DIALOG_TIMEOUT);
+ if (mListener != null) {
+ mListener.onTriStateUserActivity();
+ }
+ }
+
+ @Override
+ public void onDensityOrFontScaleChanged() {
+ handleDismiss();
+ initDialog();
+ updateTriStateLayout();
+ }
+
+ private void updateTheme() {
+ // Todo: Add some logic to update the theme only when a new theme is applied
+ mIconColor = getAttrColor(android.R.attr.colorAccent);
+ mTextColor = getAttrColor(android.R.attr.textColorPrimary);
+ mBackgroundColor = getAttrColor(android.R.attr.colorPrimary);
+ mDialogView.setBackgroundTintList(ColorStateList.valueOf(mBackgroundColor));
+ mTriStateIcon.setColorFilter(mIconColor);
+ mTriStateText.setTextColor(mTextColor);
+ }
+
+ public int getAttrColor(int attr) {
+ TypedArray ta = mContext.obtainStyledAttributes(new int[]{attr});
+ int colorAccent = ta.getColor(0, 0);
+ ta.recycle();
+ return colorAccent;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
index e8a22ec4fbe7..a56bcacfb3bb 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
@@ -394,9 +394,8 @@ public class StorageNotification implements CoreStartable {
final VolumeRecord rec = mStorageManager.findRecordByUuid(vol.getFsUuid());
final DiskInfo disk = vol.getDisk();
- // Don't annoy when user dismissed in past. (But make sure the disk is adoptable; we
- // used to allow snoozing non-adoptable disks too.)
- if (rec.isSnoozed() && disk.isAdoptable()) {
+ // Don't annoy when user dismissed in past.
+ if (rec.isSnoozed() && (disk.isAdoptable() || disk.isSd())) {
return null;
}
if (disk.isAdoptable() && !rec.isInited() && rec.getType() != VolumeInfo.TYPE_PUBLIC
@@ -439,8 +438,12 @@ public class StorageNotification implements CoreStartable {
buildUnmountPendingIntent(vol)))
.setContentIntent(browseIntent)
.setCategory(Notification.CATEGORY_SYSTEM);
- // Non-adoptable disks can't be snoozed.
- if (disk.isAdoptable()) {
+ // USB disks notification can be persistent
+ if (disk.isUsb()) {
+ builder.setOngoing(true);
+ }
+
+ if (disk.isAdoptable() || disk.isSd()) {
builder.setDeleteIntent(buildSnoozeIntent(vol.getFsUuid()));
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
index f71d98827e4b..7d086d27fa54 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
@@ -36,6 +36,8 @@ import com.android.systemui.plugins.VolumeDialog;
import com.android.systemui.plugins.VolumeDialogController;
import com.android.systemui.qs.tiles.DndTile;
import com.android.systemui.statusbar.policy.ExtensionController;
+import com.android.systemui.tristate.TriStateUiController;
+import com.android.systemui.tristate.TriStateUiControllerImpl;
import com.android.systemui.tuner.TunerService;
import java.io.PrintWriter;
@@ -49,7 +51,7 @@ import javax.inject.Inject;
*/
@SysUISingleton
public class VolumeDialogComponent implements VolumeComponent, TunerService.Tunable,
- VolumeDialogControllerImpl.UserActivityListener{
+ VolumeDialogControllerImpl.UserActivityListener, TriStateUiController.UserActivityListener {
public static final String VOLUME_DOWN_SILENT = "sysui_volume_down_silent";
public static final String VOLUME_UP_SILENT = "sysui_volume_up_silent";
@@ -66,6 +68,7 @@ public class VolumeDialogComponent implements VolumeComponent, TunerService.Tuna
protected final Context mContext;
private final VolumeDialogControllerImpl mController;
+ private TriStateUiControllerImpl mTriStateController;
private final InterestingConfigChanges mConfigChanges = new InterestingConfigChanges(
ActivityInfo.CONFIG_FONT_SCALE | ActivityInfo.CONFIG_LOCALE
| ActivityInfo.CONFIG_ASSETS_PATHS | ActivityInfo.CONFIG_UI_MODE);
@@ -95,6 +98,8 @@ public class VolumeDialogComponent implements VolumeComponent, TunerService.Tuna
mActivityStarter = activityStarter;
mController = volumeDialogController;
mController.setUserActivityListener(this);
+ boolean hasAlertSlider = mContext.getResources().
+ getBoolean(com.android.internal.R.bool.config_hasAlertSlider);
// Allow plugins to reference the VolumeDialogController.
pluginDependencyProvider.allowPluginDependency(VolumeDialogController.class);
extensionController.newExtension(VolumeDialog.class)
@@ -106,6 +111,13 @@ public class VolumeDialogComponent implements VolumeComponent, TunerService.Tuna
}
mDialog = dialog;
mDialog.init(LayoutParams.TYPE_VOLUME_OVERLAY, mVolumeDialogCallback);
+ if (hasAlertSlider) {
+ if (mTriStateController != null) {
+ mTriStateController.destroy();
+ }
+ mTriStateController = new TriStateUiControllerImpl(mContext);
+ mTriStateController.init(LayoutParams.TYPE_VOLUME_OVERLAY, this);
+ }
}).build();
applyConfiguration();
tunerService.addTunable(this, VOLUME_DOWN_SILENT, VOLUME_UP_SILENT,
@@ -193,6 +205,11 @@ public class VolumeDialogComponent implements VolumeComponent, TunerService.Tuna
mActivityStarter.startActivity(intent, true /* onlyProvisioned */, true /* dismissShade */);
}
+ @Override
+ public void onTriStateUserActivity() {
+ onUserActivity();
+ }
+
private final VolumeDialogImpl.Callback mVolumeDialogCallback = new VolumeDialogImpl.Callback() {
@Override
public void onZenSettingsClicked() {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index db3fd41cc95b..8d0135634ecf 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -275,6 +275,7 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
private Consumer<Boolean> mCrossWindowBlurEnabledListener;
private BackgroundBlurDrawable mDialogRowsViewBackground;
private final InteractionJankMonitor mInteractionJankMonitor;
+ private boolean mLeftVolumeRocker;
public VolumeDialogImpl(
Context context,
@@ -312,6 +313,8 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
mUseBackgroundBlur =
mContext.getResources().getBoolean(R.bool.config_volumeDialogUseBackgroundBlur);
mInteractionJankMonitor = interactionJankMonitor;
+ mLeftVolumeRocker =
+ mContext.getResources().getBoolean(R.bool.config_audioPanelOnLeftSide);
dumpManager.registerDumpable("VolumeDialogImpl", this);
@@ -428,7 +431,11 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
lp.format = PixelFormat.TRANSLUCENT;
lp.setTitle(VolumeDialogImpl.class.getSimpleName());
lp.windowAnimations = -1;
- lp.gravity = mContext.getResources().getInteger(R.integer.volume_dialog_gravity);
+ if (!isAudioPanelOnLeftSide() || isLandscape()) {
+ lp.gravity = Gravity.RIGHT | Gravity.CENTER_VERTICAL;
+ } else {
+ lp.gravity = Gravity.LEFT | Gravity.CENTER_VERTICAL;
+ }
mWindow.setAttributes(lp);
mWindow.setLayout(WRAP_CONTENT, WRAP_CONTENT);
@@ -439,7 +446,8 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
mDialog.setOnShowListener(dialog -> {
mDialogView.getViewTreeObserver().addOnComputeInternalInsetsListener(this);
if (!shouldSlideInVolumeTray()) {
- mDialogView.setTranslationX(mDialogView.getWidth() / 2.0f);
+ mDialogView.setTranslationX(
+ (mDialogView.getWidth() / 2.0f) * (isAudioPanelOnLeftSide() ? -1 : 1));
}
mDialogView.setAlpha(0);
mDialogView.animate()
@@ -668,7 +676,11 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
if (D.BUG) Slog.d(TAG, "Adding row for stream " + stream);
VolumeRow row = new VolumeRow();
initRow(row, stream, iconRes, iconMuteRes, important, defaultStream);
- mDialogRowsView.addView(row.view);
+ if (!isAudioPanelOnLeftSide() || isLandscape()) {
+ mDialogRowsView.addView(row.view, 0);
+ } else {
+ mDialogRowsView.addView(row.view);
+ }
mRows.add(row);
}
@@ -678,7 +690,11 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
final VolumeRow row = mRows.get(i);
initRow(row, row.stream, row.iconRes, row.iconMuteRes, row.important,
row.defaultStream);
- mDialogRowsView.addView(row.view);
+ if (!isAudioPanelOnLeftSide() || isLandscape()) {
+ mDialogRowsView.addView(row.view, 0);
+ } else {
+ mDialogRowsView.addView(row.view);
+ }
updateVolumeRowH(row);
}
}
@@ -1401,7 +1417,10 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
hideRingerDrawer();
}, 50));
- if (!shouldSlideInVolumeTray()) animator.translationX(mDialogView.getWidth() / 2.0f);
+ if (!shouldSlideInVolumeTray()) {
+ animator.translationX(
+ (mDialogView.getWidth() / 2.0f) * (isAudioPanelOnLeftSide() ? -1 : 1));
+ }
animator.setListener(getJankListener(getDialogView(), TYPE_DISMISS,
mDialogHideAnimationDurationMs)).start();
checkODICaptionsTooltip(true);
@@ -2281,6 +2300,10 @@ public class VolumeDialogImpl implements VolumeDialog, Dumpable,
}
}
+ private boolean isAudioPanelOnLeftSide() {
+ return mLeftVolumeRocker;
+ }
+
private static class VolumeRow {
private View view;
private TextView header;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt
index f580f5e00f67..7c0e627563ef 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt
@@ -40,6 +40,7 @@ import com.android.systemui.demomode.DemoModeController
import com.android.systemui.dump.DumpManager
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
+import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.qs.ChipVisibilityListener
import com.android.systemui.qs.HeaderPrivacyIconsController
import com.android.systemui.qs.carrier.QSCarrierGroup
@@ -143,6 +144,7 @@ class LargeScreenShadeHeaderControllerCombinedTest : SysuiTestCase() {
@Mock
private lateinit var largeScreenConstraints: ConstraintSet
@Mock private lateinit var demoModeController: DemoModeController
+ @Mock private lateinit var activityStarter: ActivityStarter
@JvmField @Rule
val mockitoRule = MockitoJUnit.rule()
@@ -204,7 +206,8 @@ class LargeScreenShadeHeaderControllerCombinedTest : SysuiTestCase() {
featureFlags,
qsCarrierGroupControllerBuilder,
combinedShadeHeadersConstraintManager,
- demoModeController
+ demoModeController,
+ activityStarter
)
whenever(view.isAttachedToWindow).thenReturn(true)
controller.init()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt
index b568122d3fed..a973a70dd0eb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt
@@ -19,6 +19,7 @@ import com.android.systemui.demomode.DemoModeController
import com.android.systemui.dump.DumpManager
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
+import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.qs.HeaderPrivacyIconsController
import com.android.systemui.qs.carrier.QSCarrierGroup
import com.android.systemui.qs.carrier.QSCarrierGroupController
@@ -75,6 +76,7 @@ class LargeScreenShadeHeaderControllerTest : SysuiTestCase() {
@Mock private lateinit var mockedContext: Context
@Mock private lateinit var demoModeController: DemoModeController
+ @Mock private lateinit var activityStarter: ActivityStarter
@JvmField @Rule val mockitoRule = MockitoJUnit.rule()
var viewVisibility = View.GONE
@@ -129,7 +131,8 @@ class LargeScreenShadeHeaderControllerTest : SysuiTestCase() {
featureFlags,
qsCarrierGroupControllerBuilder,
combinedShadeHeadersConstraintManager,
- demoModeController
+ demoModeController,
+ activityStarter
)
whenever(view.isAttachedToWindow).thenReturn(true)
mLargeScreenShadeHeaderController.init()
diff --git a/packages/overlays/Android.mk b/packages/overlays/Android.mk
index 69641e69a9f2..4b0ae0abc66c 100644
--- a/packages/overlays/Android.mk
+++ b/packages/overlays/Android.mk
@@ -25,7 +25,6 @@ LOCAL_REQUIRED_MODULES := \
DisplayCutoutEmulationHoleOverlay \
DisplayCutoutEmulationTallOverlay \
DisplayCutoutEmulationWaterfallOverlay \
- FontNotoSerifSourceOverlay \
NavigationBarMode3ButtonOverlay \
NavigationBarModeGesturalOverlay \
NavigationBarModeGesturalOverlayNarrowBack \
diff --git a/proto/src/metrics_constants/metrics_constants.proto b/proto/src/metrics_constants/metrics_constants.proto
index 3801c2473c11..49f37db67e41 100644
--- a/proto/src/metrics_constants/metrics_constants.proto
+++ b/proto/src/metrics_constants/metrics_constants.proto
@@ -7437,5 +7437,8 @@ message MetricsEvent {
// ---- End Q Constants, all Q constants go above this line ----
// Add new aosp constants above this line.
// END OF AOSP CONSTANTS
+
+ // ICE Metrics
+ ICE = 2772;
}
}
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index e282679d8695..771281b7365c 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -165,6 +165,9 @@ public final class BatteryService extends SystemService {
private boolean mBatteryLevelLow;
+ private boolean mOemFastCharger;
+ private boolean mLastOemFastCharger;
+
private long mDischargeStartTime;
private int mDischargeStartLevel;
@@ -491,6 +494,8 @@ public final class BatteryService extends SystemService {
shutdownIfNoPowerLocked();
shutdownIfOverTempLocked();
+ mOemFastCharger = isOemFastCharger();
+
if (force
|| (mHealthInfo.batteryStatus != mLastBatteryStatus
|| mHealthInfo.batteryHealth != mLastBatteryHealth
@@ -502,7 +507,8 @@ public final class BatteryService extends SystemService {
|| mHealthInfo.maxChargingCurrentMicroamps != mLastMaxChargingCurrent
|| mHealthInfo.maxChargingVoltageMicrovolts != mLastMaxChargingVoltage
|| mHealthInfo.batteryChargeCounterUah != mLastChargeCounter
- || mInvalidCharger != mLastInvalidCharger)) {
+ || mInvalidCharger != mLastInvalidCharger
+ || mOemFastCharger != mLastOemFastCharger)) {
if (mPlugType != mLastPlugType) {
if (mLastPlugType == BATTERY_PLUGGED_NONE) {
@@ -676,6 +682,7 @@ public final class BatteryService extends SystemService {
mLastChargeCounter = mHealthInfo.batteryChargeCounterUah;
mLastBatteryLevelCritical = mBatteryLevelCritical;
mLastInvalidCharger = mInvalidCharger;
+ mLastOemFastCharger = mOemFastCharger;
}
}
@@ -707,9 +714,11 @@ public final class BatteryService extends SystemService {
BatteryManager.EXTRA_MAX_CHARGING_VOLTAGE,
mHealthInfo.maxChargingVoltageMicrovolts);
intent.putExtra(BatteryManager.EXTRA_CHARGE_COUNTER, mHealthInfo.batteryChargeCounterUah);
+ intent.putExtra(BatteryManager.EXTRA_OEM_FAST_CHARGER, mOemFastCharger);
if (DEBUG) {
Slog.d(TAG, "Sending ACTION_BATTERY_CHANGED. scale:" + BATTERY_SCALE
- + ", info:" + mHealthInfo.toString());
+ + ", info:" + mHealthInfo.toString()
+ + ", mOemFastCharger:" + mOemFastCharger);
}
mHandler.post(() -> ActivityManager.broadcastStickyIntent(intent, UserHandle.USER_ALL));
@@ -761,6 +770,25 @@ public final class BatteryService extends SystemService {
mLastBatteryLevelChangedSentMs = SystemClock.elapsedRealtime();
}
+ private boolean isOemFastCharger() {
+ final String path = mContext.getResources().getString(
+ com.android.internal.R.string.config_oemFastChargerStatusPath);
+
+ if (path.isEmpty())
+ return false;
+
+ final String value = mContext.getResources().getString(
+ com.android.internal.R.string.config_oemFastChargerStatusValue);
+
+ try {
+ return FileUtils.readTextFile(new File(path), value.length(), null).equals(value);
+ } catch (IOException e) {
+ Slog.e(TAG, "Failed to read oem fast charger status path: " + path);
+ }
+
+ return false;
+ }
+
// TODO: Current code doesn't work since "--unplugged" flag in BSS was purposefully removed.
private void logBatteryStatsLocked() {
IBinder batteryInfoService = ServiceManager.getService(BatteryStats.SERVICE_NAME);
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 1e4d3f7d3de5..26cf38f2fa55 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -1619,6 +1619,8 @@ class StorageManagerService extends IStorageManager.Stub
// public API requirement of being in a stable location.
if (vol.disk.isAdoptable()) {
vol.mountFlags |= VolumeInfo.MOUNT_FLAG_VISIBLE_FOR_WRITE;
+ } else if (vol.disk.isSd()) {
+ vol.mountFlags |= VolumeInfo.MOUNT_FLAG_VISIBLE_FOR_WRITE;
}
vol.mountUserId = mCurrentUserId;
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 44b186e1541f..9470a728389f 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -71,6 +71,7 @@ import android.content.pm.PackagePartitions;
import android.content.pm.UserInfo;
import android.os.BatteryStats;
import android.os.Binder;
+import android.os.Build;
import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
@@ -761,7 +762,7 @@ class UserController implements Handler.Callback {
// purposefully block sending BOOT_COMPLETED until after all
// PRE_BOOT receivers are finished to avoid ANR'ing apps
final UserInfo info = getUserInfo(userId);
- if (!Objects.equals(info.lastLoggedInFingerprint, PackagePartitions.FINGERPRINT)
+ if (!Objects.equals(info.lastLoggedInFingerprint, Build.VERSION.INCREMENTAL)
|| SystemProperties.getBoolean("persist.pm.mock-upgrade", false)) {
// Suppress double notifications for managed profiles that
// were unlocked automatically as part of their parent user being
diff --git a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
index a6a3db11b729..e9b3e8577fd2 100644
--- a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
@@ -1720,9 +1720,17 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
mContext.getSystemService(Context.TELEPHONY_SERVICE);
int type = AGPS_SETID_TYPE_NONE;
String setId = null;
+ final Boolean isEmergency = mNIHandler.getInEmergency();
+
+ // Unless we are in an emergency, do not provide sensitive subscriber information
+ // to SUPL servers.
+ if (!isEmergency) {
+ mGnssNative.setAgpsSetId(type, "");
+ return;
+ }
int subId = SubscriptionManager.getDefaultDataSubscriptionId();
- if (mNIHandler.getInEmergency() && mNetworkConnectivityHandler.getActiveSubId() >= 0) {
+ if (isEmergency && mNetworkConnectivityHandler.getActiveSubId() >= 0) {
subId = mNetworkConnectivityHandler.getActiveSubId();
}
if (SubscriptionManager.isValidSubscriptionId(subId)) {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 4d44c886fa22..a7b0bc5ae0cd 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -2317,7 +2317,6 @@ public class NotificationManagerService extends SystemService {
mAppOps,
new SysUiStatsEvent.BuilderFactory(),
mShowReviewPermissionsNotification);
- mPreferencesHelper.updateFixedImportance(mUm.getUsers());
mRankingHelper = new RankingHelper(getContext(),
mRankingHandler,
mPreferencesHelper,
@@ -2760,6 +2759,9 @@ public class NotificationManagerService extends SystemService {
maybeShowInitialReviewPermissionsNotification();
} else if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
mSnoozeHelper.scheduleRepostsForPersistedNotifications(System.currentTimeMillis());
+ } else if (phase == SystemService.PHASE_DEVICE_SPECIFIC_SERVICES_READY) {
+ mPreferencesHelper.updateFixedImportance(mUm.getUsers());
+ mPreferencesHelper.migrateNotificationPermissions(mUm.getUsers());
}
}
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 5507158f34da..d7e8c832cdf9 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -237,7 +237,6 @@ public class PreferencesHelper implements RankingConfig {
Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
NotificationManagerService.REVIEW_NOTIF_STATE_SHOULD_SHOW);
}
- ArrayList<PermissionHelper.PackagePermission> pkgPerms = new ArrayList<>();
synchronized (mPackagePreferences) {
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
tag = parser.getName();
@@ -255,27 +254,18 @@ public class PreferencesHelper implements RankingConfig {
String name = parser.getAttributeValue(null, ATT_NAME);
if (!TextUtils.isEmpty(name)) {
restorePackage(parser, forRestore, userId, name, upgradeForBubbles,
- migrateToPermission, pkgPerms);
+ migrateToPermission);
}
}
}
}
}
- if (migrateToPermission) {
- for (PackagePermission p : pkgPerms) {
- try {
- mPermissionHelper.setNotificationPermission(p);
- } catch (Exception e) {
- Slog.e(TAG, "could not migrate setting for " + p.packageName, e);
- }
- }
- }
}
@GuardedBy("mPackagePreferences")
private void restorePackage(TypedXmlPullParser parser, boolean forRestore,
@UserIdInt int userId, String name, boolean upgradeForBubbles,
- boolean migrateToPermission, ArrayList<PermissionHelper.PackagePermission> pkgPerms) {
+ boolean migrateToPermission) {
try {
int uid = parser.getAttributeInt(null, ATT_UID, UNKNOWN_UID);
if (forRestore) {
@@ -382,14 +372,6 @@ public class PreferencesHelper implements RankingConfig {
if (migrateToPermission) {
r.importance = appImportance;
r.migrateToPm = true;
- if (r.uid != UNKNOWN_UID) {
- // Don't call into permission system until we have a valid uid
- PackagePermission pkgPerm = new PackagePermission(
- r.pkg, UserHandle.getUserId(r.uid),
- r.importance != IMPORTANCE_NONE,
- hasUserConfiguredSettings(r));
- pkgPerms.add(pkgPerm);
- }
}
} catch (Exception e) {
Slog.w(TAG, "Failed to restore pkg", e);
@@ -2679,6 +2661,31 @@ public class PreferencesHelper implements RankingConfig {
}
}
+ public void migrateNotificationPermissions(List<UserInfo> users) {
+ for (UserInfo user : users) {
+ List<PackageInfo> packages = mPm.getInstalledPackagesAsUser(
+ PackageManager.PackageInfoFlags.of(PackageManager.MATCH_ALL),
+ user.getUserHandle().getIdentifier());
+ for (PackageInfo pi : packages) {
+ synchronized (mPackagePreferences) {
+ PackagePreferences p = getOrCreatePackagePreferencesLocked(
+ pi.packageName, pi.applicationInfo.uid);
+ if (p.migrateToPm && p.uid != UNKNOWN_UID) {
+ try {
+ PackagePermission pkgPerm = new PackagePermission(
+ p.pkg, UserHandle.getUserId(p.uid),
+ p.importance != IMPORTANCE_NONE,
+ hasUserConfiguredSettings(p));
+ mPermissionHelper.setNotificationPermission(pkgPerm);
+ } catch (Exception e) {
+ Slog.e(TAG, "could not migrate setting for " + p.pkg, e);
+ }
+ }
+ }
+ }
+ }
+ }
+
private void updateConfig() {
mRankingHandler.requestSort();
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 8b15b2da3dfd..cc6b1258d480 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -862,6 +862,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService
final PendingPackageBroadcasts mPendingBroadcasts;
+ ArrayList<ComponentName> mDisabledComponentsList;
+
static final int SEND_PENDING_BROADCAST = 1;
static final int INIT_COPY = 5;
static final int POST_INSTALL = 9;
@@ -1494,7 +1496,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
}
PackageManagerService m = new PackageManagerService(injector, onlyCore, factoryTest,
- PackagePartitions.FINGERPRINT, Build.IS_ENG, Build.IS_USERDEBUG,
+ Build.VERSION.INCREMENTAL, Build.IS_ENG, Build.IS_USERDEBUG,
Build.VERSION.SDK_INT, Build.VERSION.INCREMENTAL);
t.traceEnd(); // "create package manager"
@@ -1961,7 +1963,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
!buildFingerprint.equals(ver.fingerprint);
if (mIsUpgrade) {
PackageManagerServiceUtils.logCriticalInfo(Log.INFO, "Upgrading from "
- + ver.fingerprint + " to " + PackagePartitions.FINGERPRINT);
+ + ver.fingerprint + " to " + Build.VERSION.INCREMENTAL);
}
mInitAppsHelper = new InitAppsHelper(this, mApexManager, mInstallPackageHelper,
@@ -2075,8 +2077,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService
// allow... it would be nice to have some better way to handle
// this situation.
if (mIsUpgrade) {
- Slog.i(TAG, "Build fingerprint changed from " + ver.fingerprint + " to "
- + PackagePartitions.FINGERPRINT
+ Slog.i(TAG, "Build incremental version changed from " + ver.fingerprint + " to "
+ + Build.VERSION.INCREMENTAL
+ "; regranting permissions for internal storage");
}
mPermissionManager.onStorageVolumeMounted(
@@ -2092,13 +2094,24 @@ public class PackageManagerService implements PackageSender, TestUtilityService
}
}
+ // Disable components marked for disabling at build-time
+ mDisabledComponentsList = new ArrayList<ComponentName>();
+ enableComponents(mContext.getResources().getStringArray(
+ com.android.internal.R.array.config_deviceDisabledComponents), false);
+ enableComponents(mContext.getResources().getStringArray(
+ com.android.internal.R.array.config_globallyDisabledComponents), false);
+
+ // Enable components marked for forced-enable at build-time
+ enableComponents(mContext.getResources().getStringArray(
+ com.android.internal.R.array.config_forceEnabledComponents), true);
+
// If this is first boot after an OTA, and a normal boot, then
// we need to clear code cache directories.
// Note that we do *not* clear the application profiles. These remain valid
// across OTAs and are used to drive profile verification (post OTA) and
// profile compilation (without waiting to collect a fresh set of profiles).
if (mIsUpgrade && !mOnlyCore) {
- Slog.i(TAG, "Build fingerprint changed; clearing code caches");
+ Slog.i(TAG, "Build incremental version changed; clearing code caches");
for (int i = 0; i < packageSettings.size(); i++) {
final PackageSetting ps = packageSettings.valueAt(i);
if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.getVolumeUuid())) {
@@ -2109,7 +2122,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
| Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES);
}
}
- ver.fingerprint = PackagePartitions.FINGERPRINT;
+ ver.fingerprint = Build.VERSION.INCREMENTAL;
}
// Defer the app data fixup until we are done with app data clearing above.
@@ -2268,6 +2281,30 @@ public class PackageManagerService implements PackageSender, TestUtilityService
Slog.i(TAG, "Fix for b/169414761 is applied");
}
+ private void enableComponents(String[] components, boolean enable) {
+ // Disable or enable components marked at build-time
+ for (String name : components) {
+ ComponentName cn = ComponentName.unflattenFromString(name);
+ if (!enable) {
+ mDisabledComponentsList.add(cn);
+ }
+ Slog.v(TAG, "Changing enabled state of " + name + " to " + enable);
+ String className = cn.getClassName();
+ String packageName = cn.getPackageName();
+ AndroidPackage pkg = mPackages.get(packageName);
+ if (pkg == null || !AndroidPackageUtils.hasComponentClassName(pkg, className)) {
+ Slog.w(TAG, "Unable to change enabled state of " + name + " to " + enable);
+ continue;
+ }
+ PackageSetting pkgSetting = mSettings.getPackageLPr(packageName);
+ if (enable) {
+ pkgSetting.enableComponentLPw(className, UserHandle.USER_OWNER);
+ } else {
+ pkgSetting.disableComponentLPw(className, UserHandle.USER_OWNER);
+ }
+ }
+ }
+
@GuardedBy("mLock")
void updateInstantAppInstallerLocked(String modifiedPackage) {
// we're only interested in updating the installer application when 1) it's not
@@ -5637,6 +5674,12 @@ public class PackageManagerService implements PackageSender, TestUtilityService
public void setComponentEnabledSetting(ComponentName componentName,
int newState, int flags, int userId) {
if (!mUserManager.exists(userId)) return;
+ // Don't allow to enable components marked for disabling at build-time
+ if (mDisabledComponentsList.contains(componentName)) {
+ Slog.d(TAG, "Ignoring attempt to set enabled state of disabled component "
+ + componentName.flattenToString());
+ return;
+ }
setEnabledSettings(List.of(new PackageManager.ComponentEnabledSetting(componentName, newState, flags)),
userId, null /* callingPackage */);
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index cfd029346340..a9b624653b92 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -445,7 +445,7 @@ public final class Settings implements Watchable, Snappable {
public void forceCurrent() {
sdkVersion = Build.VERSION.SDK_INT;
databaseVersion = CURRENT_DATABASE_VERSION;
- fingerprint = PackagePartitions.FINGERPRINT;
+ fingerprint = Build.VERSION.INCREMENTAL;
}
}
@@ -5527,7 +5527,7 @@ public final class Settings implements Watchable, Snappable {
}
private String getExtendedFingerprint(long version) {
- return PackagePartitions.FINGERPRINT + "?pc_version=" + version;
+ return Build.VERSION.INCREMENTAL + "?pc_version=" + version;
}
private static long uniformRandom(double low, double high) {
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index f303fedde567..66901edb1c1d 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -5162,7 +5162,7 @@ public class ShortcutService extends IShortcutService.Stub {
// Injection point.
String injectBuildFingerprint() {
- return Build.FINGERPRINT;
+ return Build.VERSION.INCREMENTAL;
}
final void wtf(String message) {
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index c2dd32667bc2..7090881138c7 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -4046,7 +4046,7 @@ public class UserManagerService extends IUserManager.Stub {
userInfo.creationTime = getCreationTime();
userInfo.partial = true;
userInfo.preCreated = preCreate;
- userInfo.lastLoggedInFingerprint = PackagePartitions.FINGERPRINT;
+ userInfo.lastLoggedInFingerprint = Build.VERSION.INCREMENTAL;
if (userTypeDetails.hasBadge() && parentId != UserHandle.USER_NULL) {
userInfo.profileBadge = getFreeProfileBadgeLU(parentId, userType);
}
@@ -5332,7 +5332,7 @@ public class UserManagerService extends IUserManager.Stub {
t.traceBegin("onBeforeStartUser-" + userId);
final int userSerial = userInfo.serialNumber;
// Migrate only if build fingerprints mismatch
- boolean migrateAppsData = !PackagePartitions.FINGERPRINT.equals(
+ boolean migrateAppsData = !Build.VERSION.INCREMENTAL.equals(
userInfo.lastLoggedInFingerprint);
t.traceBegin("prepareUserData");
mUserDataPreparer.prepareUserData(userId, userSerial, StorageManager.FLAG_STORAGE_DE);
@@ -5363,7 +5363,7 @@ public class UserManagerService extends IUserManager.Stub {
}
final int userSerial = userInfo.serialNumber;
// Migrate only if build fingerprints mismatch
- boolean migrateAppsData = !PackagePartitions.FINGERPRINT.equals(
+ boolean migrateAppsData = !Build.VERSION.INCREMENTAL.equals(
userInfo.lastLoggedInFingerprint);
final TimingsTraceAndSlog t = new TimingsTraceAndSlog();
@@ -5408,7 +5408,7 @@ public class UserManagerService extends IUserManager.Stub {
if (now > EPOCH_PLUS_30_YEARS) {
userData.info.lastLoggedInTime = now;
}
- userData.info.lastLoggedInFingerprint = PackagePartitions.FINGERPRINT;
+ userData.info.lastLoggedInFingerprint = Build.VERSION.INCREMENTAL;
scheduleWriteUser(userData);
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 20fb97839926..887dad13f463 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -190,6 +190,7 @@ import com.android.internal.app.AssistUtils;
import com.android.internal.inputmethod.SoftInputShowHideReason;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto;
+import com.android.internal.os.DeviceKeyHandler;
import com.android.internal.os.RoSystemProperties;
import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.policy.IShortcutService;
@@ -218,11 +219,15 @@ import com.android.server.wm.WindowManagerInternal;
import com.android.server.wm.WindowManagerInternal.AppTransitionListener;
import com.android.server.wm.WindowManagerService;
+import dalvik.system.PathClassLoader;
+
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -601,6 +606,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
private int mCurrentUserId;
+ private AssistUtils mAssistUtils;
+
// Maps global key codes to the components that will handle them.
private GlobalKeyManager mGlobalKeyManager;
@@ -622,6 +629,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
private boolean mLockNowPending = false;
+ private final List<DeviceKeyHandler> mDeviceKeyHandlers = new ArrayList<>();
+
private static final int MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK = 3;
private static final int MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK = 4;
private static final int MSG_KEYGUARD_DRAWN_COMPLETE = 5;
@@ -1307,6 +1316,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
+ private boolean hasAssistant() {
+ return mAssistUtils.getAssistComponentForUser(mCurrentUserId) != null;
+ }
+
private int getResolvedLongPressOnPowerBehavior() {
if (FactoryTest.isLongPressOnPowerOffEnabled()) {
return LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM;
@@ -1314,7 +1327,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// If the config indicates the assistant behavior but the device isn't yet provisioned, show
// global actions instead.
- if (mLongPressOnPowerBehavior == LONG_PRESS_POWER_ASSISTANT && !isDeviceProvisioned()) {
+ if (mLongPressOnPowerBehavior == LONG_PRESS_POWER_ASSISTANT &&
+ (!isDeviceProvisioned() || !hasAssistant())) {
return LONG_PRESS_POWER_GLOBAL_ACTIONS;
}
@@ -2126,6 +2140,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mSafeModeEnabledVibePattern = getLongIntArray(mContext.getResources(),
com.android.internal.R.array.config_safeModeEnabledVibePattern);
+ mAssistUtils = new AssistUtils(context);
+
mGlobalKeyManager = new GlobalKeyManager(mContext);
// Controls rotation and the like.
@@ -2170,6 +2186,28 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mWindowManagerFuncs.onKeyguardShowingAndNotOccludedChanged();
}
});
+ final String[] deviceKeyHandlerLibs = res.getStringArray(
+ com.android.internal.R.array.config_deviceKeyHandlerLibs);
+ final String[] deviceKeyHandlerClasses = res.getStringArray(
+ com.android.internal.R.array.config_deviceKeyHandlerClasses);
+
+ for (int i = 0;
+ i < deviceKeyHandlerLibs.length && i < deviceKeyHandlerClasses.length; i++) {
+ try {
+ PathClassLoader loader = new PathClassLoader(
+ deviceKeyHandlerLibs[i], getClass().getClassLoader());
+ Class<?> klass = loader.loadClass(deviceKeyHandlerClasses[i]);
+ Constructor<?> constructor = klass.getConstructor(Context.class);
+ mDeviceKeyHandlers.add((DeviceKeyHandler) constructor.newInstance(mContext));
+ } catch (Exception e) {
+ Slog.w(TAG, "Could not instantiate device key handler "
+ + deviceKeyHandlerLibs[i] + " from class "
+ + deviceKeyHandlerClasses[i], e);
+ }
+ }
+ if (DEBUG_INPUT) {
+ Slog.d(TAG, "" + mDeviceKeyHandlers.size() + " device key handlers loaded");
+ }
initKeyCombinationRules();
initSingleKeyGestureRules();
mSideFpsEventHandler = new SideFpsEventHandler(mContext, mHandler, mPowerManager);
@@ -3095,6 +3133,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
return key_consumed;
}
+ // Specific device key handling
+ if (dispatchKeyToKeyHandlers(event)) {
+ return -1;
+ }
+
// Reserve all the META modifier combos for system behavior
if ((metaState & KeyEvent.META_META_ON) != 0) {
return key_consumed;
@@ -3147,6 +3190,23 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
+ private boolean dispatchKeyToKeyHandlers(KeyEvent event) {
+ for (DeviceKeyHandler handler : mDeviceKeyHandlers) {
+ try {
+ if (DEBUG_INPUT) {
+ Log.d(TAG, "Dispatching key event " + event + " to handler " + handler);
+ }
+ event = handler.handleKeyEvent(event);
+ if (event == null) {
+ return true;
+ }
+ } catch (Exception e) {
+ Slog.w(TAG, "Could not dispatch event to device key handler", e);
+ }
+ }
+ return false;
+ }
+
// TODO(b/117479243): handle it in InputPolicy
/** {@inheritDoc} */
@Override
@@ -3862,6 +3922,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
&& (!isNavBarVirtKey || mNavBarVirtualKeyHapticFeedbackEnabled)
&& event.getRepeatCount() == 0;
+ // Specific device key handling
+ if (dispatchKeyToKeyHandlers(event)) {
+ return 0;
+ }
+
// Handle special keys.
switch (keyCode) {
case KeyEvent.KEYCODE_BACK: {
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index dad9584c6722..f817bc4ac1b4 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -115,6 +115,8 @@ public class Notifier {
-1);
private static final VibrationAttributes HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES =
VibrationAttributes.createForUsage(VibrationAttributes.USAGE_HARDWARE_FEEDBACK);
+ private static final VibrationEffect CHARGING_VIBRATION_DOUBLE_CLICK_EFFECT =
+ VibrationEffect.createPredefined(VibrationEffect.EFFECT_DOUBLE_CLICK);
private final Object mLock = new Object();
@@ -844,8 +846,8 @@ public class Notifier {
final boolean vibrate = Settings.Secure.getIntForUser(mContext.getContentResolver(),
Settings.Secure.CHARGING_VIBRATION_ENABLED, 1, userId) != 0;
if (vibrate) {
- mVibrator.vibrate(CHARGING_VIBRATION_EFFECT,
- HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES);
+ mVibrator.vibrate(mVibrator.hasAmplitudeControl() ? CHARGING_VIBRATION_EFFECT :
+ CHARGING_VIBRATION_DOUBLE_CLICK_EFFECT, HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES);
}
// play sound
diff --git a/services/core/java/com/android/server/textservices/TextServicesManagerService.java b/services/core/java/com/android/server/textservices/TextServicesManagerService.java
index cd2b8943ce11..f2106696de29 100644
--- a/services/core/java/com/android/server/textservices/TextServicesManagerService.java
+++ b/services/core/java/com/android/server/textservices/TextServicesManagerService.java
@@ -43,6 +43,8 @@ import android.service.textservice.SpellCheckerService;
import android.text.TextUtils;
import android.util.Slog;
import android.util.SparseArray;
+import android.view.inputmethod.InputMethodManager;
+import android.view.inputmethod.InputMethodSubtype;
import android.view.textservice.SpellCheckerInfo;
import android.view.textservice.SpellCheckerSubtype;
import android.view.textservice.SuggestionsInfo;
@@ -544,19 +546,37 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
// subtypeHashCode == 0 means spell checker language settings is "auto"
- if (systemLocale == null) {
+ Locale candidateLocale = null;
+ final InputMethodManager imm = mContext.getSystemService(InputMethodManager.class);
+ if (imm != null) {
+ final InputMethodSubtype currentInputMethodSubtype =
+ imm.getCurrentInputMethodSubtype();
+ if (currentInputMethodSubtype != null) {
+ final String localeString = currentInputMethodSubtype.getLocale();
+ if (!TextUtils.isEmpty(localeString)) {
+ // 1. Use keyboard locale if available in the spell checker
+ candidateLocale = SubtypeLocaleUtils.constructLocaleFromString(localeString);
+ }
+ }
+ }
+ if (candidateLocale == null) {
+ // 2. Use System locale if available in the spell checker
+ candidateLocale = systemLocale;
+ }
+
+ if (candidateLocale == null) {
return null;
}
SpellCheckerSubtype firstLanguageMatchingSubtype = null;
for (int i = 0; i < sci.getSubtypeCount(); ++i) {
final SpellCheckerSubtype scs = sci.getSubtypeAt(i);
final Locale scsLocale = scs.getLocaleObject();
- if (Objects.equals(scsLocale, systemLocale)) {
+ if (Objects.equals(scsLocale, candidateLocale)) {
// Exact match wins.
return scs;
}
if (firstLanguageMatchingSubtype == null && scsLocale != null
- && TextUtils.equals(systemLocale.getLanguage(), scsLocale.getLanguage())) {
+ && TextUtils.equals(candidateLocale.getLanguage(), scsLocale.getLanguage())) {
// Remember as a fall back candidate
firstLanguageMatchingSubtype = scs;
}
diff --git a/services/core/java/com/android/server/webkit/SystemImpl.java b/services/core/java/com/android/server/webkit/SystemImpl.java
index 68f554cb2758..5604fc6c0f39 100644
--- a/services/core/java/com/android/server/webkit/SystemImpl.java
+++ b/services/core/java/com/android/server/webkit/SystemImpl.java
@@ -219,7 +219,7 @@ public class SystemImpl implements SystemInterface {
@Override
public boolean systemIsDebuggable() {
- return Build.IS_DEBUGGABLE;
+ return Build.IS_DEBUGGABLE && Build.IS_ENG;
}
@Override
diff --git a/services/core/java/com/android/server/wm/AlertWindowNotification.java b/services/core/java/com/android/server/wm/AlertWindowNotification.java
index c589feae56ca..51c93a6293b4 100644
--- a/services/core/java/com/android/server/wm/AlertWindowNotification.java
+++ b/services/core/java/com/android/server/wm/AlertWindowNotification.java
@@ -24,6 +24,7 @@ import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.provider.Settings.ACTION_MANAGE_APP_OVERLAY_PERMISSION;
+import android.annotation.UserIdInt;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
@@ -37,6 +38,7 @@ import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
+import android.os.UserHandle;
import com.android.internal.R;
import com.android.internal.util.ImageUtils;
@@ -53,11 +55,14 @@ class AlertWindowNotification {
private String mNotificationTag;
private final NotificationManager mNotificationManager;
private final String mPackageName;
+ private final @UserIdInt int mUserId;
private boolean mPosted;
- AlertWindowNotification(WindowManagerService service, String packageName) {
+ AlertWindowNotification(WindowManagerService service, String packageName,
+ @UserIdInt int userId) {
mService = service;
mPackageName = packageName;
+ mUserId = userId;
mNotificationManager =
(NotificationManager) mService.mContext.getSystemService(NOTIFICATION_SERVICE);
mNotificationTag = CHANNEL_PREFIX + mPackageName;
@@ -100,7 +105,7 @@ class AlertWindowNotification {
final Context context = mService.mContext;
final PackageManager pm = context.getPackageManager();
- final ApplicationInfo aInfo = getApplicationInfo(pm, mPackageName);
+ final ApplicationInfo aInfo = getApplicationInfoAsUser(pm, mPackageName, mUserId);
final String appName = (aInfo != null)
? pm.getApplicationLabel(aInfo).toString() : mPackageName;
@@ -138,6 +143,7 @@ class AlertWindowNotification {
final Intent intent = new Intent(ACTION_MANAGE_APP_OVERLAY_PERMISSION,
Uri.fromParts("package", packageName, null));
intent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
+ intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.of(mUserId));
// Calls into activity manager...
return PendingIntent.getActivity(context, mRequestCode, intent,
FLAG_CANCEL_CURRENT | FLAG_IMMUTABLE);
@@ -168,9 +174,10 @@ class AlertWindowNotification {
}
- private ApplicationInfo getApplicationInfo(PackageManager pm, String packageName) {
+ private ApplicationInfo getApplicationInfoAsUser(PackageManager pm, String packageName,
+ @UserIdInt int userId) {
try {
- return pm.getApplicationInfo(packageName, 0);
+ return pm.getApplicationInfoAsUser(packageName, 0, userId);
} catch (PackageManager.NameNotFoundException e) {
return null;
}
diff --git a/services/core/java/com/android/server/wm/RemoteDisplayChangeController.java b/services/core/java/com/android/server/wm/RemoteDisplayChangeController.java
index 43baebc7255a..e646f14a3e13 100644
--- a/services/core/java/com/android/server/wm/RemoteDisplayChangeController.java
+++ b/services/core/java/com/android/server/wm/RemoteDisplayChangeController.java
@@ -114,9 +114,15 @@ public class RemoteDisplayChangeController {
// timed-out, so run all continue callbacks and clear the list
synchronized (mService.mGlobalLock) {
for (int i = 0; i < mCallbacks.size(); ++i) {
- mCallbacks.get(i).onContinueRemoteDisplayChange(null /* transaction */);
+ final ContinueRemoteDisplayChangeCallback callback = mCallbacks.get(i);
+ if (i == mCallbacks.size() - 1) {
+ // Clear all callbacks before calling the last one, so that if the callback
+ // itself calls {@link #isWaitingForRemoteDisplayChange()}, it will get
+ // {@code false}. After all, there is nothing pending after this one.
+ mCallbacks.clear();
+ }
+ callback.onContinueRemoteDisplayChange(null /* transaction */);
}
- mCallbacks.clear();
}
}
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index fb68fe666c0b..67088e957eb8 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -761,7 +761,8 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
if (mAlertWindowSurfaces.isEmpty()) {
cancelAlertWindowNotification();
} else if (mAlertWindowNotification == null){
- mAlertWindowNotification = new AlertWindowNotification(mService, mPackageName);
+ mAlertWindowNotification = new AlertWindowNotification(mService, mPackageName,
+ UserHandle.getUserId(mUid));
if (mShowingAlertWindowNotificationAllowed) {
mAlertWindowNotification.post();
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index 598a22bbde39..c9b264a1875b 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -676,10 +676,6 @@ public class PreferencesHelperTest extends UiServiceTestCase {
compareChannels(ido, mHelper.getNotificationChannel(PKG_O, UID_O, ido.getId(), false));
compareChannels(idp, mHelper.getNotificationChannel(PKG_P, UID_P, idp.getId(), false));
- verify(mPermissionHelper).setNotificationPermission(nMr1Expected);
- verify(mPermissionHelper).setNotificationPermission(oExpected);
- verify(mPermissionHelper).setNotificationPermission(pExpected);
-
// verify that we also write a state for review_permissions_notification to eventually
// show a notification
assertEquals(NotificationManagerService.REVIEW_NOTIF_STATE_SHOULD_SHOW,
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 3edee50216b6..67b67c5bda70 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -9193,7 +9193,7 @@ public class CarrierConfigManager {
sDefaults.putBoolean(KEY_SHOW_4G_FOR_3G_DATA_ICON_BOOL, false);
sDefaults.putString(KEY_OPERATOR_NAME_FILTER_PATTERN_STRING, "");
sDefaults.putString(KEY_SHOW_CARRIER_DATA_ICON_PATTERN_STRING, "");
- sDefaults.putBoolean(KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL, true);
+ sDefaults.putBoolean(KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL, false);
sDefaults.putInt(KEY_LTE_PLUS_THRESHOLD_BANDWIDTH_KHZ_INT, 20000);
sDefaults.putInt(KEY_NR_ADVANCED_THRESHOLD_BANDWIDTH_KHZ_INT, 0);
sDefaults.putBoolean(KEY_INCLUDE_LTE_FOR_NR_ADVANCED_THRESHOLD_BANDWIDTH_BOOL, false);