Merge tag 'android-11.0.0_r36' into r
Android 11.0.0 Release 36 (RQ2A.210505.002)
Change-Id: Ib5cdaf186577e6fec0f0cf0d454d5ec29885bd96
diff --git a/Android.bp b/Android.bp
index bf6c99d..7a0fdce 100644
--- a/Android.bp
+++ b/Android.bp
@@ -383,10 +383,10 @@
"android.hardware.vibrator-V1.2-java",
"android.hardware.vibrator-V1.3-java",
"devicepolicyprotosnano",
-
"com.android.sysprop.apex",
"com.android.sysprop.init",
"PlatformProperties",
+ "vendor.lineage.touch-V1.0-java",
],
sdk_version: "core_platform",
installable: false,
diff --git a/apex/jobscheduler/framework/java/android/os/IDeviceIdleController.aidl b/apex/jobscheduler/framework/java/android/os/IDeviceIdleController.aidl
index 643d47c..d6a3cf0 100644
--- a/apex/jobscheduler/framework/java/android/os/IDeviceIdleController.aidl
+++ b/apex/jobscheduler/framework/java/android/os/IDeviceIdleController.aidl
@@ -49,4 +49,6 @@
void exitIdle(String reason);
int setPreIdleTimeoutMode(int Mode);
void resetPreIdleTimeoutMode();
+ int getIdleStateDetailed();
+ int getLightIdleStateDetailed();
}
diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
index ac58f3d..d414377 100644
--- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
+++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
@@ -1677,6 +1677,18 @@
return isPowerSaveWhitelistAppInternal(name);
}
+ @Override public int getIdleStateDetailed() {
+ getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
+ null);
+ return mState;
+ }
+
+ @Override public int getLightIdleStateDetailed() {
+ getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
+ null);
+ return mLightState;
+ }
+
@Override
public long whitelistAppTemporarily(String packageName, int userId, String reason)
throws RemoteException {
diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
index 36ccaf9..e440d07 100644
--- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
@@ -1757,7 +1757,7 @@
@Override
public void initializeDefaultsForSystemApps(int userId) {
if (!mSystemServicesReady) {
- // Do it later, since SettingsProvider wasn't queried yet for app_standby_enabled
+ // Do it later, since SettingsProvider wasn't queried yet for adaptive_battery_management_enabled
mPendingInitializeDefaults = true;
return;
}
@@ -1995,8 +1995,6 @@
final boolean buildFlag = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_enableAutoPowerModes);
final boolean runtimeFlag = Global.getInt(mContext.getContentResolver(),
- Global.APP_STANDBY_ENABLED, 1) == 1
- && Global.getInt(mContext.getContentResolver(),
Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED, 1) == 1;
return buildFlag && runtimeFlag;
}
@@ -2301,7 +2299,6 @@
void registerObserver() {
final ContentResolver cr = mContext.getContentResolver();
cr.registerContentObserver(Global.getUriFor(Global.APP_IDLE_CONSTANTS), false, this);
- cr.registerContentObserver(Global.getUriFor(Global.APP_STANDBY_ENABLED), false, this);
cr.registerContentObserver(Global.getUriFor(Global.ENABLE_RESTRICTED_BUCKET),
false, this);
cr.registerContentObserver(Global.getUriFor(Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED),
@@ -2317,9 +2314,6 @@
void updateSettings() {
if (DEBUG) {
Slog.d(TAG,
- "appidle=" + Global.getString(mContext.getContentResolver(),
- Global.APP_STANDBY_ENABLED));
- Slog.d(TAG,
"adaptivebat=" + Global.getString(mContext.getContentResolver(),
Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED));
Slog.d(TAG, "appidleconstants=" + Global.getString(
diff --git a/config/hiddenapi-greylist-max-o.txt b/config/hiddenapi-greylist-max-o.txt
index 023bf38..2bcfd65 100644
--- a/config/hiddenapi-greylist-max-o.txt
+++ b/config/hiddenapi-greylist-max-o.txt
@@ -56734,6 +56734,7 @@
Landroid/provider/Settings$Secure;->VOLUME_HUSH_GESTURE:Ljava/lang/String;
Landroid/provider/Settings$Secure;->VOLUME_HUSH_GESTURE_VALIDATOR:Landroid/provider/SettingsValidators$Validator;
Landroid/provider/Settings$Secure;->VOLUME_HUSH_MUTE:I
+Landroid/provider/Settings$Secure;->VOLUME_HUSH_MUTE_NO_MEDIA:I
Landroid/provider/Settings$Secure;->VOLUME_HUSH_OFF:I
Landroid/provider/Settings$Secure;->VOLUME_HUSH_VIBRATE:I
Landroid/provider/Settings$Secure;->VR_DISPLAY_MODE:Ljava/lang/String;
@@ -94148,6 +94149,7 @@
Lcom/android/internal/R$string;->view_flight_desc:I
Lcom/android/internal/R$string;->volume_alarm:I
Lcom/android/internal/R$string;->volume_dialog_ringer_guidance_silent:I
+Lcom/android/internal/R$string;->volume_dialog_ringer_guidance_silent_no_media:I
Lcom/android/internal/R$string;->volume_dialog_ringer_guidance_vibrate:I
Lcom/android/internal/R$string;->volume_icon_description_bluetooth:I
Lcom/android/internal/R$string;->volume_icon_description_incall:I
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index b47d44d..328a13a 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -6821,9 +6821,9 @@
}
if (holder == null) {
if (UserManager.get(c).isUserUnlocked(userId)) {
- Slog.e(TAG, "Failed to find provider info for " + auth);
+ if (DEBUG_MESSAGES) Slog.e(TAG, "Failed to find provider info for " + auth);
} else {
- Slog.w(TAG, "Failed to find provider info for " + auth + " (user not unlocked)");
+ if (DEBUG_MESSAGES) Slog.w(TAG, "Failed to find provider info for " + auth + " (user not unlocked)");
}
return null;
}
diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java
index 07194226..77aa382 100644
--- a/core/java/android/app/DownloadManager.java
+++ b/core/java/android/app/DownloadManager.java
@@ -302,6 +302,13 @@
public final static int PAUSED_UNKNOWN = 4;
/**
+ * Value of {@link #COLUMN_REASON} when the download is paused manually.
+ *
+ * @hide
+ */
+ public final static int PAUSED_MANUAL = 5;
+
+ /**
* Broadcast intent action sent by the download manager when a download completes.
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
@@ -994,6 +1001,7 @@
parts.add(statusClause("=", Downloads.Impl.STATUS_WAITING_TO_RETRY));
parts.add(statusClause("=", Downloads.Impl.STATUS_WAITING_FOR_NETWORK));
parts.add(statusClause("=", Downloads.Impl.STATUS_QUEUED_FOR_WIFI));
+ parts.add(statusClause("=", Downloads.Impl.STATUS_PAUSED_MANUAL));
}
if ((mStatusFlags & STATUS_SUCCESSFUL) != 0) {
parts.add(statusClause("=", Downloads.Impl.STATUS_SUCCESS));
@@ -1284,6 +1292,34 @@
}
/**
+ * Pause the given running download manually.
+ *
+ * @param id the ID of the download to be paused
+ * @return the number of downloads actually updated
+ * @hide
+ */
+ public int pauseDownload(long id) {
+ ContentValues values = new ContentValues();
+ values.put(Downloads.Impl.COLUMN_STATUS, Downloads.Impl.STATUS_PAUSED_MANUAL);
+
+ return mResolver.update(ContentUris.withAppendedId(mBaseUri, id), values, null, null);
+ }
+
+ /**
+ * Resume the given paused download manually.
+ *
+ * @param id the ID of the download to be resumed
+ * @return the number of downloads actually updated
+ * @hide
+ */
+ public int resumeDownload(long id) {
+ ContentValues values = new ContentValues();
+ values.put(Downloads.Impl.COLUMN_STATUS, Downloads.Impl.STATUS_RUNNING);
+
+ return mResolver.update(ContentUris.withAppendedId(mBaseUri, id), values, null, null);
+ }
+
+ /**
* Returns maximum size, in bytes, of downloads that may go over a mobile connection; or null if
* there's no limit
*
@@ -1773,6 +1809,9 @@
case Downloads.Impl.STATUS_QUEUED_FOR_WIFI:
return PAUSED_QUEUED_FOR_WIFI;
+ case Downloads.Impl.STATUS_PAUSED_MANUAL:
+ return PAUSED_MANUAL;
+
default:
return PAUSED_UNKNOWN;
}
@@ -1828,6 +1867,7 @@
case Downloads.Impl.STATUS_WAITING_TO_RETRY:
case Downloads.Impl.STATUS_WAITING_FOR_NETWORK:
case Downloads.Impl.STATUS_QUEUED_FOR_WIFI:
+ case Downloads.Impl.STATUS_PAUSED_MANUAL:
return STATUS_PAUSED;
case Downloads.Impl.STATUS_SUCCESS:
diff --git a/core/java/android/app/IAlarmManager.aidl b/core/java/android/app/IAlarmManager.aidl
index 6f624ee..a6792a7 100644
--- a/core/java/android/app/IAlarmManager.aidl
+++ b/core/java/android/app/IAlarmManager.aidl
@@ -41,4 +41,6 @@
@UnsupportedAppUsage
AlarmManager.AlarmClockInfo getNextAlarmClock(int userId);
long currentNetworkTimeMillis();
+ // update the uids being synchronized by network socket request manager
+ void updateBlockedUids(int uid, boolean isBlocked);
}
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java
index 1329fa4..8ad1d6f 100644
--- a/core/java/android/app/StatusBarManager.java
+++ b/core/java/android/app/StatusBarManager.java
@@ -198,6 +198,7 @@
public static final int CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP = 1;
/** @hide */
public static final int CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER = 2;
+ public static final int CAMERA_LAUNCH_SOURCE_SCREEN_GESTURE = 3;
@UnsupportedAppUsage
private Context mContext;
diff --git a/core/java/android/app/admin/SystemUpdateInfo.java b/core/java/android/app/admin/SystemUpdateInfo.java
index 4019290..5d480b5 100644
--- a/core/java/android/app/admin/SystemUpdateInfo.java
+++ b/core/java/android/app/admin/SystemUpdateInfo.java
@@ -129,7 +129,7 @@
out.startTag(null, tag);
out.attribute(null, ATTR_RECEIVED_TIME, String.valueOf(mReceivedTime));
out.attribute(null, ATTR_SECURITY_PATCH_STATE, String.valueOf(mSecurityPatchState));
- out.attribute(null, ATTR_ORIGINAL_BUILD , Build.FINGERPRINT);
+ out.attribute(null, ATTR_ORIGINAL_BUILD , Build.DATE);
out.endTag(null, tag);
}
@@ -138,7 +138,7 @@
public static SystemUpdateInfo readFromXml(XmlPullParser 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.DATE.equals(buildFingerprint)) {
return null;
}
final long receivedTime =
diff --git a/core/java/android/app/backup/BackupAgent.java b/core/java/android/app/backup/BackupAgent.java
index 20aa064..a280cf7 100644
--- a/core/java/android/app/backup/BackupAgent.java
+++ b/core/java/android/app/backup/BackupAgent.java
@@ -748,8 +748,11 @@
// Pull out the domain and set it aside to use when making the tarball.
String domainPath = FullBackup.getBackupScheme(this).tokenToDirectoryPath(domain);
if (domainPath == null) {
- // Should never happen.
- return;
+ if (startingPath == null) {
+ return;
+ } else {
+ domainPath = startingPath;
+ }
}
File rootFile = new File(startingPath);
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 29a98fa..61f13b8 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -110,7 +110,7 @@
*/
public final class BluetoothAdapter {
private static final String TAG = "BluetoothAdapter";
- private static final boolean DBG = true;
+ private static final boolean DBG = false;
private static final boolean VDBG = false;
/**
@@ -3099,6 +3099,22 @@
}
}
+ /**
+ * @hide
+ */
+ public void unregisterAdapter() {
+ try {
+ //mServiceLock.writeLock().lock();
+ if (mManagerService != null){
+ mManagerService.unregisterAdapter(mManagerCallback);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ } finally {
+ //mServiceLock.writeLock().unlock();
+ }
+ }
+
private Set<BluetoothDevice> toDeviceSet(BluetoothDevice[] devices) {
Set<BluetoothDevice> deviceSet = new HashSet<BluetoothDevice>(Arrays.asList(devices));
return Collections.unmodifiableSet(deviceSet);
diff --git a/core/java/android/bluetooth/BluetoothCodecConfig.java b/core/java/android/bluetooth/BluetoothCodecConfig.java
index 735980b..d685cbd 100644
--- a/core/java/android/bluetooth/BluetoothCodecConfig.java
+++ b/core/java/android/bluetooth/BluetoothCodecConfig.java
@@ -64,10 +64,25 @@
public static final int SOURCE_CODEC_TYPE_APTX_HD = 3;
@UnsupportedAppUsage
- public static final int SOURCE_CODEC_TYPE_LDAC = 4;
+ public static final int SOURCE_CODEC_TYPE_APTX_ADAPTIVE = 4;
@UnsupportedAppUsage
- public static final int SOURCE_CODEC_TYPE_MAX = 5;
+ public static final int SOURCE_CODEC_TYPE_LDAC = 5;
+
+ @UnsupportedAppUsage
+ public static final int SOURCE_CODEC_TYPE_APTX_TWSP = 6;
+
+ @UnsupportedAppUsage
+ public static final int SOURCE_CODEC_TYPE_MAX = 7;
+
+ /* CELT is not an A2DP Codec and only used to fetch encoder
+ ** format for BA usecase, moving out of a2dp codec value list
+ */
+ @UnsupportedAppUsage
+ public static final int SOURCE_CODEC_TYPE_CELT = 8;
+
+ @UnsupportedAppUsage
+ public static final int SOURCE_CODEC_TYPE_LC3 = 9;
@UnsupportedAppUsage
public static final int SOURCE_CODEC_TYPE_INVALID = 1000 * 1000;
@@ -125,6 +140,17 @@
@UnsupportedAppUsage
public static final int SAMPLE_RATE_192000 = 0x1 << 5;
+ @UnsupportedAppUsage
+ public static final int SAMPLE_RATE_16000 = 0x1 << 6;
+
+ @UnsupportedAppUsage
+ public static final int SAMPLE_RATE_24000 = 0x1 << 7;
+
+ @UnsupportedAppUsage
+ public static final int SAMPLE_RATE_32000 = 0x1 << 8;
+
+ @UnsupportedAppUsage
+ public static final int SAMPLE_RATE_8000 = 0x1 << 9;
/** @hide */
@IntDef(prefix = "BITS_PER_SAMPLE_", value = {
@@ -153,7 +179,8 @@
@IntDef(prefix = "CHANNEL_MODE_", value = {
CHANNEL_MODE_NONE,
CHANNEL_MODE_MONO,
- CHANNEL_MODE_STEREO
+ CHANNEL_MODE_STEREO,
+ CHANNEL_MODE_DUAL_CHANNEL
})
@Retention(RetentionPolicy.SOURCE)
public @interface ChannelMode {}
@@ -167,6 +194,12 @@
@UnsupportedAppUsage
public static final int CHANNEL_MODE_STEREO = 0x1 << 1;
+ @UnsupportedAppUsage
+ public static final int CHANNEL_MODE_DUAL_CHANNEL = 0x1 << 2;
+
+ @UnsupportedAppUsage
+ public static final int CHANNEL_MODE_JOINT_STEREO = 0x1 << 3;
+
private final @SourceCodecType int mCodecType;
private @CodecPriority int mCodecPriority;
private final @SampleRate int mSampleRate;
@@ -313,6 +346,9 @@
if ((mChannelMode & CHANNEL_MODE_STEREO) != 0) {
channelModeStr = appendCapabilityToString(channelModeStr, "STEREO");
}
+ if ((mChannelMode & CHANNEL_MODE_DUAL_CHANNEL) != 0) {
+ channelModeStr = appendCapabilityToString(channelModeStr, "DUAL_CHANNEL");
+ }
return "{codecName:" + getCodecName()
+ ",mCodecType:" + mCodecType
@@ -402,6 +438,10 @@
return "aptX HD";
case SOURCE_CODEC_TYPE_LDAC:
return "LDAC";
+ case SOURCE_CODEC_TYPE_APTX_ADAPTIVE:
+ return "aptX Adaptive";
+ case SOURCE_CODEC_TYPE_APTX_TWSP:
+ return "aptX TWS+";
case SOURCE_CODEC_TYPE_INVALID:
return "INVALID CODEC";
default:
@@ -493,7 +533,8 @@
* supported channel modes:
* {@link android.bluetooth.BluetoothCodecConfig#CHANNEL_MODE_NONE} or
* {@link android.bluetooth.BluetoothCodecConfig#CHANNEL_MODE_MONO} or
- * {@link android.bluetooth.BluetoothCodecConfig#CHANNEL_MODE_STEREO}
+ * {@link android.bluetooth.BluetoothCodecConfig#CHANNEL_MODE_STEREO} or
+ * {@link android.bluetooth.BluetoothCodecConfig#CHANNEL_MODE_DUAL_CHANNEL}
*
* @return the codec channel mode
* @hide
@@ -650,6 +691,10 @@
if (mCodecSpecific1 != other.mCodecSpecific1) {
return false;
}
+ case SOURCE_CODEC_TYPE_APTX_ADAPTIVE:
+ if (other.mCodecSpecific4 > 0) {
+ return false;
+ }
// fall through
default:
return true;
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 594e5ff..50d47a5 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -1,4 +1,39 @@
/*
+ * Copyright (C) 2017, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted (subject to the limitations in the
+ * disclaimer below) provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
+ * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
+ * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -197,6 +232,18 @@
public static final String ACTION_BOND_STATE_CHANGED =
"android.bluetooth.device.action.BOND_STATE_CHANGED";
+ /**
+ * Broadcast Action: Broadcast details of IOT device when an IOT
+ * related issue is observed.
+ * <p>Always contains the extra fields {@link #EXTRA_NAME}.
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
+ * @hide
+ **/
+
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_REMOTE_ISSUE_OCCURRED =
+ "org.codeaurora.intent.bluetooth.action.REMOTE_ISSUE_OCCURRED";
+
/**
* Broadcast Action: Indicates the battery level of a remote device has
* been retrieved for the first time, or changed since the last retrieval
@@ -236,6 +283,17 @@
public static final int BATTERY_LEVEL_BLUETOOTH_OFF = -100;
/**
+ * Broadcast Action: Indicates the remote devices are TWS plus earbuds pair.
+ * <p>Always contains the extra fields {@link #EXTRA_TWS_PLUS_DEVICE1},
+ * {@link #EXTRA_TWS_PLUS_DEVICE2}.
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_TWS_PLUS_DEVICE_PAIR =
+ "android.bluetooth.device.action.TWS_PLUS_DEVICE_PAIR";
+
+ /**
* Used as a Parcelable {@link BluetoothDevice} extra field in every intent
* broadcast by this class. It contains the {@link BluetoothDevice} that
* the intent applies to.
@@ -249,6 +307,76 @@
public static final String EXTRA_NAME = "android.bluetooth.device.extra.NAME";
/**
+ * Used as a Parcelable {@link BluetoothQualityReport} extra field in
+ * {@link #ACTION_REMOTE_ISSUE_OCCURRED} intent. It contains the {@link BluetoothQualityReport}.
+ * @hide
+ */
+ public static final String EXTRA_BQR = "android.bluetooth.qti.extra.EXTRA_BQR";
+
+ /**
+ * Used as a String extra field in {@link #ACTION_REMOTE_ISSUE_OCCURRED}
+ * intents. It contains the type of IOT issue that occurred.
+ * @hide
+ */
+ public static final String EXTRA_ISSUE_TYPE = "android.bluetooth.qti.extra.ERROR_TYPE";
+
+ /**
+ * Used as a String extra field in {@link #ACTION_REMOTE_ISSUE_OCCURRED} intents.
+ * It contains the details of details of the issue.
+ * @hide
+ */
+ public static final String EXTRA_ERROR_CODE = "android.bluetooth.qti.extra.ERROR_CODE";
+
+ /**
+ * Used as a String extra field in {@link #ACTION_REMOTE_ISSUE_OCCURRED} intents.
+ * It contains the SoC event mask when issue occurred.
+ * @hide
+ */
+ public static final String EXTRA_ERROR_EVENT_MASK = "android.bluetooth.qti.extra.ERROR_EVENT_MASK";
+
+ /**
+ * Used as a String extra field in {@link #ACTION_REMOTE_ISSUE_OCCURRED} intents.
+ * It contains the LMP Version of IOT device.
+ * @hide
+ */
+ public static final String EXTRA_LMP_VERSION = "android.bluetooth.qti.extra.EXTRA_LMP_VERSION";
+
+ /**
+ * Used as a String extra field in {@link #ACTION_REMOTE_ISSUE_OCCURRED} intents.
+ * It contains the LMP Sub Version of IOT device.
+ * @hide
+ */
+ public static final String EXTRA_LMP_SUBVER = "android.bluetooth.qti.extra.EXTRA_LMP_SUBVER";
+
+ /**
+ * Used as a String extra field in {@link #ACTION_REMOTE_ISSUE_OCCURRED} intents.
+ * It contains the Manufacturer ID of IOT device.
+ * @hide
+ */
+ public static final String EXTRA_MANUFACTURER = "android.bluetooth.qti.extra.EXTRA_MANUFACTURER";
+
+ /**
+ * Used as a String extra field in {@link #ACTION_REMOTE_ISSUE_OCCURRED} intents.
+ * It contains the Power level.
+ * @hide
+ */
+ public static final String EXTRA_POWER_LEVEL = "android.bluetooth.qti.extra.EXTRA_POWER_LEVEL";
+
+ /**
+ * Used as a String extra field in {@link #ACTION_REMOTE_ISSUE_OCCURRED} intents.
+ * It contains the Link Quality of the connection.
+ * @hide
+ */
+ public static final String EXTRA_LINK_QUALITY = "android.bluetooth.qti.extra.EXTRA_LINK_QUALITY";
+
+ /**
+ * Used as a String extra field in {@link #ACTION_REMOTE_ISSUE_OCCURRED} intents.
+ * It contains the coutnt of glitches occured since last broadcast.
+ * @hide
+ */
+ public static final String EXTRA_GLITCH_COUNT = "android.bluetooth.qti.extra.EXTRA_GLITCH_COUNT";
+
+ /**
* Used as an optional short extra field in {@link #ACTION_FOUND} intents.
* Contains the RSSI value of the remote device as reported by the
* Bluetooth hardware.
@@ -280,6 +408,23 @@
*/
public static final String EXTRA_PREVIOUS_BOND_STATE =
"android.bluetooth.device.extra.PREVIOUS_BOND_STATE";
+
+ /**
+ * Used as a String extra field in {@link #ACTION_TWS+_DEVICE_PAIR}
+ * intents. It contains the first TWS+ earbud address of pair.
+ * @hide
+ */
+ public static final String EXTRA_TWS_PLUS_DEVICE1 =
+ "android.bluetooth.device.extra.EXTRA_TWS_PLUS_DEVICE1";
+
+ /**
+ * Used as a String extra field in {@link #ACTION_TWS+_DEVICE_PAIR}
+ * intents. It contains the second TWS+ earbud address of pair.
+ * @hide
+ */
+ public static final String EXTRA_TWS_PLUS_DEVICE2 =
+ "android.bluetooth.device.extra.EXTRA_TWS_PLUS_DEVICE2";
+
/**
* Indicates the remote device is not bonded (paired).
* <p>There is no shared link key with the remote device, so communication
@@ -1031,7 +1176,11 @@
try {
String name = service.getRemoteName(this);
if (name != null) {
- return name.replaceAll("[\\t\\n\\r]+", " ");
+ // remove whitespace characters from the name
+ return name
+ .replace('\t', ' ')
+ .replace('\n', ' ')
+ .replace('\r', ' ');
}
return null;
} catch (RemoteException e) {
@@ -1229,6 +1378,22 @@
return false;
}
+ /** @hide */
+ @UnsupportedAppUsage
+ public void setBondingInitiatedLocally(boolean localInitiated) {
+ final IBluetooth service = sService;
+ if (service == null) {
+ Log.w(TAG, "BT not enabled, setBondingInitiatedLocally failed");
+ return;
+ }
+ try {
+ service.setBondingInitiatedLocally(this, localInitiated);
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ }
+ return;
+ }
+
/**
* Set the Out Of Band data for a remote device to be used later
* in the pairing mechanism. Users can obtain this data through other
@@ -1512,6 +1677,41 @@
}
/**
+ * Returns whether if the device is TWS+ device.
+ *
+ * @return True if the devcie is TWS+ device.
+ * @hide
+ */
+ public boolean isTwsPlusDevice() {
+ if (sService == null) {
+ Log.e(TAG, "BT not enabled. Cannot query remote device sdp records");
+ return false;
+ }
+ try {
+ return sService.isTwsPlusDevice(this);
+ } catch (RemoteException e) {Log.e(TAG, "", e);}
+ return false;
+ }
+
+ /**
+ * Get the TWS+ peer address of the remote device.
+ *
+ * @return the TWS+ peer address of the remote device if available, otherwise
+ * null.
+ * @hide
+ */
+ public String getTwsPlusPeerAddress() {
+ if (sService == null) {
+ Log.e(TAG, "BT not enabled. Cannot get Remote Device name");
+ return null;
+ }
+ try {
+ return sService.getTwsPlusPeerAddress(this);
+ } catch (RemoteException e) {Log.e(TAG, "", e);}
+ return null;
+ }
+
+ /**
* Set the pin during pairing when the pairing method is {@link #PAIRING_VARIANT_PIN}
* <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
*
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index e6d6e7a..c2db0e0 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -284,6 +284,41 @@
public static final int STATE_AUDIO_CONNECTED = 12;
/**
+ * Intent used to broadcast the Battery status of TWS+ devices
+ *
+ * <p>This intent will have 2 extras:
+ * <ul>
+ * <li> {@link #EXTRA_HF_TWSP_BATTERY_STATE} - Current Battey state of TWS+
+ * device. 0 for Discharging, 1 for Charging
+ * <\li>
+ * <li> {@link #EXTRA_HF_TWSP_BATTERY_LEVEL} - Current Battey charging level
+ * in percentage of TWS+ device.
+ * <\li>
+ *
+ * @hide
+ */
+ public static final String ACTION_HF_TWSP_BATTERY_STATE_CHANGED =
+ "android.bluetooth.headset.action.HF_TWSP_BATTERY_STATE_CHANGED";
+
+ /**
+ * A int extra field in {@link #EXTRA_HF_TWSP_BATTERY_STATE}
+ * intents that contains the battery state of TWS+ device
+ *
+ * @hide
+ */
+ public static final String EXTRA_HF_TWSP_BATTERY_STATE =
+ "android.bluetooth.headset.extra.HF_TWSP_BATTERY_STATE";
+
+ /**
+ * A int extra field in {@link #EXTRA_HF_TWSP_BATTERY_LEVEL}
+ * intents that contains the value of battery level in percentage for TWS+ device
+ * @hide
+ */
+ public static final String EXTRA_HF_TWSP_BATTERY_LEVEL =
+ "android.bluetooth.headset.extra.HF_TWSP_BATTERY_LEVEL";
+
+
+ /**
* Intent used to broadcast the headset's indicator status
*
* <p>This intent will have 3 extras:
@@ -417,6 +452,10 @@
doUnbind();
}
+ protected void finalize() throws Throwable {
+ close();
+ }
+
/**
* Initiate connection to a profile of the remote bluetooth device.
*
diff --git a/core/java/android/bluetooth/BluetoothQualityReport.java b/core/java/android/bluetooth/BluetoothQualityReport.java
new file mode 100644
index 0000000..bc52b9b
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothQualityReport.java
@@ -0,0 +1,1389 @@
+/*
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package android.bluetooth;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.Arrays;
+
+/**
+ * This class provides the public APIs to access the data of BQR event reported
+ * from firmware side. Currently it supports five event types: Quality monitor event,
+ * Approaching LSTO event, A2DP choppy event, SCO choppy event and Connect fail event.
+ * To know which kind of event is wrapped in this {@link BluetoothQualityReport} object,
+ * you need to call {@link #getQualityReportId}.
+ * <ul>
+ * <li> For Quality monitor event, you can call {@link #getBqrCommon} to get a
+ * {@link BluetoothQualityReport.BqrCommon} object, and call {@link #getBqrVsCommon} to get a
+ * {@link BluetoothQualityReport.BqrVsCommon} object.
+ * <li> For Approaching LSTO event, you can call {@link #getBqrCommon} to get a
+ * {@link BluetoothQualityReport.BqrCommon} object, and call {@link #getBqrVsCommon} to get a
+ * {@link BluetoothQualityReport.BqrVsCommon} object, and call {@link #getBqrVsLsto} to get a
+ * {@link BluetoothQualityReport.BqrVsLsto} object.
+ * <li> For A2DP choppy event, you can call {@link #getBqrCommon} to get a
+ * {@link BluetoothQualityReport.BqrCommon} object, and call {@link #getBqrVsCommon} to get a
+ * {@link BluetoothQualityReport.BqrVsCommon} object, and call {@link #getBqrVsA2dpChoppy} to
+ * get a {@link BluetoothQualityReport.BqrVsA2dpChoppy} object.
+ * <li> For SCO choppy event, you can call {@link #getBqrCommon} to get a
+ * {@link BluetoothQualityReport.BqrCommon} object, and call {@link #getBqrVsCommon} to get a
+ * {@link BluetoothQualityReport.BqrVsCommon} object, and call {@link #getBqrVsScoChoppy} to
+ * get a {@link BluetoothQualityReport.BqrVsScoChoppy} object.
+ * <li> For Connect fail event, you can call {@link #getBqrCommon} to get a
+ * {@link BluetoothQualityReport.BqrCommon} object, and call {@link #getBqrVsCommon} to get a
+ * {@link BluetoothQualityReport.BqrVsCommon} object, and call {@link #getBqrVsConnectFail} to
+ * get a {@link BluetoothQualityReport.BqrVsConnectFail} object.
+ * </ul>
+ *
+ * @hide
+ */
+public final class BluetoothQualityReport implements Parcelable {
+ private static final String TAG = "BluetoothQualityReport";
+
+ public static final int QUALITY_REPORT_ID_MONITOR = 0x01;
+ public static final int QUALITY_REPORT_ID_APPROACH_LSTO = 0x02;
+ public static final int QUALITY_REPORT_ID_A2DP_CHOPPY = 0x03;
+ public static final int QUALITY_REPORT_ID_SCO_CHOPPY = 0x04;
+ /* Vendor Specific Report IDs from 0x20 */
+ public static final int QUALITY_REPORT_ID_CONN_FAIL = 0x20;
+
+ private String mAddr;
+ private int mLmpVer;
+ private int mLmpSubVer;
+ private int mManufacturerId;
+ private String mName;
+ private int mBluetoothClass;
+
+ private BqrCommon mBqrCommon;
+
+ private BqrVsCommon mBqrVsCommon;
+ private BqrVsLsto mBqrVsLsto;
+ private BqrVsA2dpChoppy mBqrVsA2dpChoppy;
+ private BqrVsScoChoppy mBqrVsScoChoppy;
+ private BqrVsConnectFail mBqrVsConnectFail;
+
+ enum PacketType {
+ INVALID, TYPE_ID, TYPE_NULL, TYPE_POLL, TYPE_FHS, TYPE_HV1, TYPE_HV2, TYPE_HV3,
+ TYPE_DV, TYPE_EV3, TYPE_EV4, TYPE_EV5, TYPE_2EV3, TYPE_2EV5, TYPE_3EV3, TYPE_3EV5,
+ TYPE_DM1, TYPE_DH1, TYPE_DM3, TYPE_DH3, TYPE_DM5, TYPE_DH5, TYPE_AUX1, TYPE_2DH1,
+ TYPE_2DH3, TYPE_2DH5, TYPE_3DH1, TYPE_3DH3, TYPE_3DH5;
+
+ private static PacketType[] sAllValues = values();
+
+ static PacketType fromOrdinal(int n) {
+ if (n < sAllValues.length) {
+ return sAllValues[n];
+ }
+ return INVALID;
+ }
+ }
+
+ enum ConnState {
+ CONN_IDLE(0x00), CONN_ACTIVE(0x81), CONN_HOLD(0x02), CONN_SNIFF_IDLE(0x03),
+ CONN_SNIFF_ACTIVE(0x84), CONN_SNIFF_MASTER_TRANSITION(0x85), CONN_PARK(0x06),
+ CONN_PARK_PEND(0x47), CONN_UNPARK_PEND(0x08), CONN_UNPARK_ACTIVE(0x89),
+ CONN_DISCONNECT_PENDING(0x4A), CONN_PAGING(0x0B), CONN_PAGE_SCAN(0x0C),
+ CONN_LOCAL_LOOPBACK(0x0D), CONN_LE_ACTIVE(0x0E), CONN_ANT_ACTIVE(0x0F),
+ CONN_TRIGGER_SCAN(0x10), CONN_RECONNECTING(0x11), CONN_SEMI_CONN(0x12);
+
+ private int mValue;
+ private static ConnState[] sAllStates = values();
+
+ private ConnState(int val) {
+ mValue = val;
+ }
+
+ public static String getName(int val) {
+ for (ConnState state: sAllStates) {
+ if (state.mValue == val) {
+ return state.toString();
+ }
+ }
+ return "INVALID";
+ }
+ }
+
+ enum LinkQuality {
+ ULTRA_HIGH, HIGH, STANDARD, MEDIUM, LOW, INVALID;
+
+ private static LinkQuality[] sAllValues = values();
+
+ static LinkQuality fromOrdinal(int n) {
+ if (n < sAllValues.length - 1) {
+ return sAllValues[n];
+ }
+ return INVALID;
+ }
+ }
+
+ enum AirMode {
+ uLaw, aLaw, CVSD, transparent_msbc, INVALID;
+
+ private static AirMode[] sAllValues = values();
+
+ static AirMode fromOrdinal(int n) {
+ if (n < sAllValues.length - 1) {
+ return sAllValues[n];
+ }
+ return INVALID;
+ }
+ }
+
+ public BluetoothQualityReport(String remoteAddr, int lmpVer, int lmpSubVer,
+ int manufacturerId, String remoteName, int remoteCoD, byte[] rawData) {
+ if (!BluetoothAdapter.checkBluetoothAddress(remoteAddr)) {
+ Log.d(TAG, "remote addr is invalid");
+ mAddr = "00:00:00:00:00:00";
+ } else {
+ mAddr = remoteAddr;
+ }
+
+ mLmpVer = lmpVer;
+ mLmpSubVer = lmpSubVer;
+ mManufacturerId = manufacturerId;
+ if (remoteName == null) {
+ Log.d(TAG, "remote name is null");
+ mName = "";
+ } else {
+ mName = remoteName;
+ }
+ mBluetoothClass = remoteCoD;
+
+ mBqrCommon = new BqrCommon(rawData, 0);
+
+ mBqrVsCommon = new BqrVsCommon(rawData, BqrCommon.BQR_COMMON_LEN);
+ int id = mBqrCommon.getQualityReportId();
+ if (id == QUALITY_REPORT_ID_MONITOR)
+ return;
+
+ int vsPartOffset = BqrCommon.BQR_COMMON_LEN + mBqrVsCommon.getLength();
+ if (id == QUALITY_REPORT_ID_APPROACH_LSTO) {
+ mBqrVsLsto = new BqrVsLsto(rawData, vsPartOffset);
+ } else if (id == QUALITY_REPORT_ID_A2DP_CHOPPY) {
+ mBqrVsA2dpChoppy = new BqrVsA2dpChoppy(rawData, vsPartOffset);
+ } else if (id == QUALITY_REPORT_ID_SCO_CHOPPY) {
+ mBqrVsScoChoppy = new BqrVsScoChoppy(rawData, vsPartOffset);
+ } else if (id == QUALITY_REPORT_ID_CONN_FAIL) {
+ mBqrVsConnectFail = new BqrVsConnectFail(rawData, vsPartOffset);
+ } else {
+ throw new IllegalArgumentException(TAG + ": unkown quality report id:" + id);
+ }
+ }
+
+ private BluetoothQualityReport(Parcel in) {
+ mBqrCommon = new BqrCommon(in);
+ mAddr = in.readString();
+ mLmpVer = in.readInt();
+ mLmpSubVer = in.readInt();
+ mManufacturerId = in.readInt();
+ mName = in.readString();
+ mBluetoothClass = in.readInt();
+
+ mBqrVsCommon = new BqrVsCommon(in);
+ int id = mBqrCommon.getQualityReportId();
+ if (id == QUALITY_REPORT_ID_APPROACH_LSTO) {
+ mBqrVsLsto = new BqrVsLsto(in);
+ } else if (id == QUALITY_REPORT_ID_A2DP_CHOPPY) {
+ mBqrVsA2dpChoppy = new BqrVsA2dpChoppy(in);
+ } else if (id == QUALITY_REPORT_ID_SCO_CHOPPY) {
+ mBqrVsScoChoppy = new BqrVsScoChoppy(in);
+ } else if (id == QUALITY_REPORT_ID_CONN_FAIL) {
+ mBqrVsConnectFail = new BqrVsConnectFail(in);
+ }
+ }
+
+ /**
+ * Get the quality report id.
+ * @return the id, is one of {@link #QUALITY_REPORT_ID_MONITOR},
+ * {@link #QUALITY_REPORT_ID_APPROACH_LSTO}, {@link #QUALITY_REPORT_ID_A2DP_CHOPPY},
+ * {@link #QUALITY_REPORT_ID_SCO_CHOPPY}, {@link #QUALITY_REPORT_ID_CONN_FAIL}.
+ */
+ public int getQualityReportId() {
+ return mBqrCommon.getQualityReportId();
+ }
+
+ /**
+ * Get the string of the quality report id.
+ * @return the string of the id.
+ */
+ public String getQualityReportIdStr() {
+ int id = mBqrCommon.getQualityReportId();
+ switch (id) {
+ case QUALITY_REPORT_ID_MONITOR:
+ return "Quality monitor";
+ case QUALITY_REPORT_ID_APPROACH_LSTO:
+ return "Approaching LSTO";
+ case QUALITY_REPORT_ID_A2DP_CHOPPY:
+ return "A2DP choppy";
+ case QUALITY_REPORT_ID_SCO_CHOPPY:
+ return "SCO choppy";
+ case QUALITY_REPORT_ID_CONN_FAIL:
+ return "Connect fail";
+ default:
+ return "INVALID";
+ }
+ }
+
+ /**
+ * Get bluetooth address of remote device in this report.
+ * @return bluetooth address of remote device.
+ */
+ public String getAddress() {
+ return mAddr;
+ }
+
+ /**
+ * Get LMP version of remote device in this report.
+ * @return LMP version of remote device.
+ */
+ public int getLmpVersion() {
+ return mLmpVer;
+ }
+
+ /**
+ * Get LMP subVersion of remote device in this report.
+ * @return LMP subVersion of remote device.
+ */
+ public int getLmpSubVersion() {
+ return mLmpSubVer;
+ }
+
+ /**
+ * Get manufacturer id of remote device in this report.
+ * @return manufacturer id of remote device.
+ */
+ public int getManufacturerId() {
+ return mManufacturerId;
+ }
+
+ /**
+ * Get the name of remote device in this report.
+ * @return the name of remote device.
+ */
+ public String getName() {
+ return mName;
+ }
+
+ /**
+ * Get the class of remote device in this report.
+ * @return the class of remote device.
+ */
+ public int getBluetoothClass() {
+ return mBluetoothClass;
+ }
+
+ /**
+ * Get the {@link BluetoothQualityReport.BqrCommon} object.
+ * @return the {@link BluetoothQualityReport.BqrCommon} object.
+ */
+ public BqrCommon getBqrCommon() {
+ return mBqrCommon;
+ }
+
+ /**
+ * Get the {@link BluetoothQualityReport.BqrVsCommon} object.
+ * @return the {@link BluetoothQualityReport.BqrVsCommon} object.
+ */
+ public BqrVsCommon getBqrVsCommon() {
+ return mBqrVsCommon;
+ }
+
+ /**
+ * Get the {@link BluetoothQualityReport.BqrVsLsto} object.
+ * @return the {@link BluetoothQualityReport.BqrVsLsto} object
+ * or null if report id is not {@link #QUALITY_REPORT_ID_APPROACH_LSTO}.
+ */
+ public BqrVsLsto getBqrVsLsto() {
+ return mBqrVsLsto;
+ }
+
+ /**
+ * Get the {@link BluetoothQualityReport.BqrVsA2dpChoppy} object.
+ * @return the {@link BluetoothQualityReport.BqrVsA2dpChoppy} object
+ * or null if report id is not {@link #QUALITY_REPORT_ID_A2DP_CHOPPY}.
+ */
+ public BqrVsA2dpChoppy getBqrVsA2dpChoppy() {
+ return mBqrVsA2dpChoppy;
+ }
+
+ /**
+ * Get the {@link BluetoothQualityReport.BqrVsScoChoppy} object.
+ * @return the {@link BluetoothQualityReport.BqrVsScoChoppy} object
+ * or null if report id is not {@link #QUALITY_REPORT_ID_SCO_CHOPPY}.
+ */
+ public BqrVsScoChoppy getBqrVsScoChoppy() {
+ return mBqrVsScoChoppy;
+ }
+
+ /**
+ * Get the {@link BluetoothQualityReport.BqrVsConnectFail} object.
+ * @return the {@link BluetoothQualityReport.BqrVsConnectFail} object
+ * or null if report id is not {@link #QUALITY_REPORT_ID_CONN_FAIL}.
+ */
+ public BqrVsConnectFail getBqrVsConnectFail() {
+ return mBqrVsConnectFail;
+ }
+
+ public static final @android.annotation.NonNull Parcelable.Creator<BluetoothQualityReport> CREATOR =
+ new Parcelable.Creator<BluetoothQualityReport>() {
+ public BluetoothQualityReport createFromParcel(Parcel in) {
+ return new BluetoothQualityReport(in);
+ }
+
+ public BluetoothQualityReport[] newArray(int size) {
+ return new BluetoothQualityReport[size];
+ }
+ };
+
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ mBqrCommon.writeToParcel(out, flags);
+ out.writeString(mAddr);
+ out.writeInt(mLmpVer);
+ out.writeInt(mLmpSubVer);
+ out.writeInt(mManufacturerId);
+ out.writeString(mName);
+ out.writeInt(mBluetoothClass);
+ mBqrVsCommon.writeToParcel(out, flags);
+ int id = mBqrCommon.getQualityReportId();
+ if (id == QUALITY_REPORT_ID_APPROACH_LSTO) {
+ mBqrVsLsto.writeToParcel(out, flags);
+ } else if (id == QUALITY_REPORT_ID_A2DP_CHOPPY) {
+ mBqrVsA2dpChoppy.writeToParcel(out, flags);
+ } else if (id == QUALITY_REPORT_ID_SCO_CHOPPY) {
+ mBqrVsScoChoppy.writeToParcel(out, flags);
+ } else if (id == QUALITY_REPORT_ID_CONN_FAIL) {
+ mBqrVsConnectFail.writeToParcel(out, flags);
+ }
+ }
+
+ @Override
+ public String toString() {
+ String str;
+ str = "BQR: {\n"
+ + " mAddr: " + mAddr
+ + ", mLmpVer: " + String.format("0x%02X", mLmpVer)
+ + ", mLmpSubVer: " + String.format("0x%04X", mLmpSubVer)
+ + ", mManufacturerId: " + String.format("0x%04X", mManufacturerId)
+ + ", mName: " + mName
+ + ", mBluetoothClass: " + String.format("0x%X", mBluetoothClass)
+ + ",\n"
+ + mBqrCommon + "\n"
+ + mBqrVsCommon + "\n";
+
+ int id = mBqrCommon.getQualityReportId();
+ if (id == QUALITY_REPORT_ID_APPROACH_LSTO) {
+ str += mBqrVsLsto + "\n}";
+ } else if (id == QUALITY_REPORT_ID_A2DP_CHOPPY) {
+ str += mBqrVsA2dpChoppy + "\n}";
+ } else if (id == QUALITY_REPORT_ID_SCO_CHOPPY) {
+ str += mBqrVsScoChoppy + "\n}";
+ } else if (id == QUALITY_REPORT_ID_CONN_FAIL) {
+ str += mBqrVsConnectFail + "\n}";
+ } else if (id == QUALITY_REPORT_ID_MONITOR) {
+ str += "}";
+ }
+
+ return str;
+ }
+
+ /**
+ * This class provides the public APIs to access the common part of BQR event.
+ */
+ public class BqrCommon implements Parcelable {
+ private static final String TAG = BluetoothQualityReport.TAG + ".BqrCommon";
+ static final int BQR_COMMON_LEN = 48;
+
+ private int mQualityReportId;
+ private int mPacketType;
+ private int mConnectionHandle;
+ private int mConnectionRole;
+ private int mTxPowerLevel;
+ private int mRssi;
+ private int mSnr;
+ private int mUnusedAfhChannelCount;
+ private int mAfhSelectUnidealChannelCount;
+ private int mLsto;
+ private long mPiconetClock;
+ private long mRetransmissionCount;
+ private long mNoRxCount;
+ private long mNakCount;
+ private long mLastTxAckTimestamp;
+ private long mFlowOffCount;
+ private long mLastFlowOnTimestamp;
+ private long mOverflowCount;
+ private long mUnderflowCount;
+
+ private BqrCommon(byte[] rawData, int offset) {
+ if (rawData == null || rawData.length < offset + BQR_COMMON_LEN) {
+ throw new IllegalArgumentException(TAG + ": BQR raw data length is abnormal.");
+ }
+
+ ByteBuffer bqrBuf = ByteBuffer.wrap(rawData, offset, rawData.length - offset)
+ .asReadOnlyBuffer();
+ bqrBuf.order(ByteOrder.LITTLE_ENDIAN);
+
+ mQualityReportId = bqrBuf.get() & 0xFF;
+ mPacketType = bqrBuf.get() & 0xFF;
+ mConnectionHandle = bqrBuf.getShort() & 0xFFFF;
+ mConnectionRole = bqrBuf.get() & 0xFF;
+ mTxPowerLevel = bqrBuf.get() & 0xFF;
+ mRssi = bqrBuf.get();
+ mSnr = bqrBuf.get();
+ mUnusedAfhChannelCount = bqrBuf.get() & 0xFF;
+ mAfhSelectUnidealChannelCount = bqrBuf.get() & 0xFF;
+ mLsto = bqrBuf.getShort() & 0xFFFF;
+ mPiconetClock = bqrBuf.getInt() & 0xFFFFFFFFL;
+ mRetransmissionCount = bqrBuf.getInt() & 0xFFFFFFFFL;
+ mNoRxCount = bqrBuf.getInt() & 0xFFFFFFFFL;
+ mNakCount = bqrBuf.getInt() & 0xFFFFFFFFL;
+ mLastTxAckTimestamp = bqrBuf.getInt() & 0xFFFFFFFFL;
+ mFlowOffCount = bqrBuf.getInt() & 0xFFFFFFFFL;
+ mLastFlowOnTimestamp = bqrBuf.getInt() & 0xFFFFFFFFL;
+ mOverflowCount = bqrBuf.getInt() & 0xFFFFFFFFL;
+ mUnderflowCount = bqrBuf.getInt() & 0xFFFFFFFFL;
+ }
+
+ private BqrCommon(Parcel in) {
+ mQualityReportId = in.readInt();
+ mPacketType = in.readInt();
+ mConnectionHandle = in.readInt();
+ mConnectionRole = in.readInt();
+ mTxPowerLevel = in.readInt();
+ mRssi = in.readInt();
+ mSnr = in.readInt();
+ mUnusedAfhChannelCount = in.readInt();
+ mAfhSelectUnidealChannelCount = in.readInt();
+ mLsto = in.readInt();
+ mPiconetClock = in.readLong();
+ mRetransmissionCount = in.readLong();
+ mNoRxCount = in.readLong();
+ mNakCount = in.readLong();
+ mLastTxAckTimestamp = in.readLong();
+ mFlowOffCount = in.readLong();
+ mLastFlowOnTimestamp = in.readLong();
+ mOverflowCount = in.readLong();
+ mUnderflowCount = in.readLong();
+ }
+
+ int getQualityReportId() {
+ return mQualityReportId;
+ }
+
+ /**
+ * Get the packet type of the connection.
+ * @return the packet type.
+ */
+ public int getPacketType() {
+ return mPacketType;
+ }
+
+ /**
+ * Get the string of packet type
+ * @return the string of packet type.
+ */
+ public String getPacketTypeStr() {
+ PacketType type = PacketType.fromOrdinal(mPacketType);
+ return type.toString();
+ }
+
+ /**
+ * Get the connecton handle of the connection
+ * @return the connecton handle.
+ */
+ public int getConnectionHandle() {
+ return mConnectionHandle;
+ }
+
+ /**
+ * Get the connecton Role of the connection, "Master" or "Slave".
+ * @return the connecton Role.
+ */
+ public String getConnectionRole() {
+ if (mConnectionRole == 0) {
+ return "Master";
+ } else if (mConnectionRole == 1) {
+ return "Slave";
+ } else {
+ return "INVALID:" + mConnectionRole;
+ }
+ }
+
+ /**
+ * Get the current transmit power level for the connection.
+ * @return the TX power level.
+ */
+ public int getTxPowerLevel() {
+ return mTxPowerLevel;
+ }
+
+ /**
+ * Get the Received Signal Strength Indication (RSSI) value for the connection.
+ * @return the RSSI.
+ */
+ public int getRssi() {
+ return mRssi;
+ }
+
+ /**
+ * get the Signal-to-Noise Ratio (SNR) value for the connection.
+ * @return the SNR.
+ */
+ public int getSnr() {
+ return mSnr;
+ }
+
+ /**
+ * Get the number of unused channels in AFH_channel_map.
+ * @return the number of unused channels.
+ */
+ public int getUnusedAfhChannelCount() {
+ return mUnusedAfhChannelCount;
+ }
+
+ /**
+ * Get the number of the channels which are interfered and quality is
+ * bad but are still selected for AFH.
+ * @return the number of the selected unideal channels.
+ */
+ public int getAfhSelectUnidealChannelCount() {
+ return mAfhSelectUnidealChannelCount;
+ }
+
+ /**
+ * Get the current link supervision timeout setting.
+ * time_ms: N * 0.625 ms (1 slot).
+ * @return link supervision timeout value.
+ */
+ public int getLsto() {
+ return mLsto;
+ }
+
+ /**
+ * Get the piconet clock for the specified Connection_Handle.
+ * time_ms: N * 0.3125 ms (1 Bluetooth Clock).
+ * @return the piconet clock.
+ */
+ public long getPiconetClock() {
+ return mPiconetClock;
+ }
+
+ /**
+ * Get the count of retransmission.
+ * @return the count of retransmission.
+ */
+ public long getRetransmissionCount() {
+ return mRetransmissionCount;
+ }
+
+ /**
+ * Get the count of no RX.
+ * @return the count of no RX.
+ */
+ public long getNoRxCount() {
+ return mNoRxCount;
+ }
+
+ /**
+ * Get the count of NAK(Negative Acknowledge).
+ * @return the count of NAK.
+ */
+ public long getNakCount() {
+ return mNakCount;
+ }
+
+ /**
+ * Get the timestamp of last TX ACK.
+ * time_ms: N * 0.3125 ms (1 Bluetooth Clock).
+ * @return the timestamp of last TX ACK.
+ */
+ public long getLastTxAckTimestamp() {
+ return mLastTxAckTimestamp;
+ }
+
+ /**
+ * Get the count of flow-off.
+ * @return the count of flow-off.
+ */
+ public long getFlowOffCount() {
+ return mFlowOffCount;
+ }
+
+ /**
+ * Get the timestamp of last flow-on.
+ * @return the timestamp of last flow-on.
+ */
+ public long getLastFlowOnTimestamp() {
+ return mLastFlowOnTimestamp;
+ }
+
+ /**
+ * Get the buffer overflow count (how many bytes of TX data are dropped) since the
+ * last event.
+ * @return the buffer overflow count.
+ */
+ public long getOverflowCount() {
+ return mOverflowCount;
+ }
+
+ /**
+ * Get the buffer underflow count (in byte).
+ * @return the buffer underflow count.
+ */
+ public long getUnderflowCount() {
+ return mUnderflowCount;
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mQualityReportId);
+ dest.writeInt(mPacketType);
+ dest.writeInt(mConnectionHandle);
+ dest.writeInt(mConnectionRole);
+ dest.writeInt(mTxPowerLevel);
+ dest.writeInt(mRssi);
+ dest.writeInt(mSnr);
+ dest.writeInt(mUnusedAfhChannelCount);
+ dest.writeInt(mAfhSelectUnidealChannelCount);
+ dest.writeInt(mLsto);
+ dest.writeLong(mPiconetClock);
+ dest.writeLong(mRetransmissionCount);
+ dest.writeLong(mNoRxCount);
+ dest.writeLong(mNakCount);
+ dest.writeLong(mLastTxAckTimestamp);
+ dest.writeLong(mFlowOffCount);
+ dest.writeLong(mLastFlowOnTimestamp);
+ dest.writeLong(mOverflowCount);
+ dest.writeLong(mUnderflowCount);
+ }
+
+ @Override
+ public String toString() {
+ String str;
+ str = " BqrCommon: {\n"
+ + " mQualityReportId: " + BluetoothQualityReport.this.getQualityReportIdStr()
+ + "(" + String.format("0x%02X", mQualityReportId) + ")"
+ + ", mPacketType: " + getPacketTypeStr()
+ + "(" + String.format("0x%02X", mPacketType) + ")"
+ + ", mConnectionHandle: " + String.format("0x%04X", mConnectionHandle)
+ + ", mConnectionRole: " + getConnectionRole() + "(" + mConnectionRole + ")"
+ + ", mTxPowerLevel: " + mTxPowerLevel
+ + ", mRssi: " + mRssi
+ + ", mSnr: " + mSnr
+ + ", mUnusedAfhChannelCount: " + mUnusedAfhChannelCount
+ + ",\n"
+ + " mAfhSelectUnidealChannelCount: " + mAfhSelectUnidealChannelCount
+ + ", mLsto: " + mLsto
+ + ", mPiconetClock: " + String.format("0x%08X", mPiconetClock)
+ + ", mRetransmissionCount: " + mRetransmissionCount
+ + ", mNoRxCount: " + mNoRxCount
+ + ", mNakCount: " + mNakCount
+ + ", mLastTxAckTimestamp: " + String.format("0x%08X", mLastTxAckTimestamp)
+ + ", mFlowOffCount: " + mFlowOffCount
+ + ",\n"
+ + " mLastFlowOnTimestamp: " + String.format("0x%08X", mLastFlowOnTimestamp)
+ + ", mOverflowCount: " + mOverflowCount
+ + ", mUnderflowCount: " + mUnderflowCount
+ + "\n }";
+
+ return str;
+ }
+
+ }
+
+ /**
+ * This class provides the public APIs to access the vendor specific common part of
+ * BQR event.
+ */
+ public class BqrVsCommon implements Parcelable {
+ private static final String TAG = BluetoothQualityReport.TAG + ".BqrVsCommon";
+ private static final int BQR_VS_COMMON_LEN = 6 + 1;
+
+ private String mAddr;
+ private int mCalFailedItemCount;
+
+ private BqrVsCommon(byte[] rawData, int offset) {
+ if (rawData == null || rawData.length < offset + BQR_VS_COMMON_LEN) {
+ throw new IllegalArgumentException(TAG + ": BQR raw data length is abnormal.");
+ }
+
+ ByteBuffer bqrBuf = ByteBuffer.wrap(rawData, offset, rawData.length - offset)
+ .asReadOnlyBuffer();
+ bqrBuf.order(ByteOrder.LITTLE_ENDIAN);
+
+ mAddr = String.format("%02X:%02X:%02X:%02X:%02X:%02X", bqrBuf.get(offset+5),
+ bqrBuf.get(offset+4), bqrBuf.get(offset+3), bqrBuf.get(offset+2),
+ bqrBuf.get(offset+1), bqrBuf.get(offset+0));
+ bqrBuf.position(offset+6);
+ mCalFailedItemCount = bqrBuf.get() & 0xFF;
+ }
+
+ private BqrVsCommon(Parcel in) {
+ mAddr = in.readString();
+ mCalFailedItemCount = in.readInt();
+ }
+
+ /**
+ * Get the count of calibration failed items.
+ * @return the count of calibration failure.
+ */
+ public int getCalFailedItemCount() {
+ return mCalFailedItemCount;
+ }
+
+ int getLength() {
+ return BQR_VS_COMMON_LEN;
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mAddr);
+ dest.writeInt(mCalFailedItemCount);
+ }
+
+ @Override
+ public String toString() {
+ String str;
+ str = " BqrVsCommon: {\n"
+ + " mAddr: " + mAddr
+ + ", mCalFailedItemCount: " + mCalFailedItemCount
+ + "\n }";
+
+ return str;
+ }
+ }
+
+ /**
+ * This class provides the public APIs to access the vendor specific part of
+ * Approaching LSTO event.
+ */
+ public class BqrVsLsto implements Parcelable {
+ private static final String TAG = BluetoothQualityReport.TAG + ".BqrVsLsto";
+
+ private int mConnState;
+ private long mBasebandStats;
+ private long mSlotsUsed;
+ private int mCxmDenials;
+ private int mTxSkipped;
+ private int mRfLoss;
+ private long mNativeClock;
+ private long mLastTxAckTimestamp;
+
+ private BqrVsLsto(byte[] rawData, int offset) {
+ if (rawData == null || rawData.length <= offset) {
+ throw new IllegalArgumentException(TAG + ": BQR raw data length is abnormal.");
+ }
+
+ ByteBuffer bqrBuf = ByteBuffer.wrap(rawData, offset, rawData.length - offset)
+ .asReadOnlyBuffer();
+ bqrBuf.order(ByteOrder.LITTLE_ENDIAN);
+
+ mConnState = bqrBuf.get() & 0xFF;
+ mBasebandStats = bqrBuf.getInt() & 0xFFFFFFFFL;
+ mSlotsUsed = bqrBuf.getInt() & 0xFFFFFFFFL;
+ mCxmDenials = bqrBuf.getShort() & 0xFFFF;
+ mTxSkipped = bqrBuf.getShort() & 0xFFFF;
+ mRfLoss = bqrBuf.getShort() & 0xFFFF;
+ mNativeClock = bqrBuf.getInt() & 0xFFFFFFFFL;
+ mLastTxAckTimestamp = bqrBuf.getInt() & 0xFFFFFFFFL;
+ }
+
+ private BqrVsLsto(Parcel in) {
+ mConnState = in.readInt();
+ mBasebandStats = in.readLong();
+ mSlotsUsed = in.readLong();
+ mCxmDenials = in.readInt();
+ mTxSkipped = in.readInt();
+ mRfLoss = in.readInt();
+ mNativeClock = in.readLong();
+ mLastTxAckTimestamp = in.readLong();
+ }
+
+ /**
+ * Get the conn state of sco.
+ * @return the conn state.
+ */
+ public int getConnState() {
+ return mConnState;
+ }
+
+ /**
+ * Get the string of conn state of sco.
+ * @return the string of conn state.
+ */
+ public String getConnStateStr() {
+ return ConnState.getName(mConnState);
+ }
+
+ /**
+ * Get the baseband statistics.
+ * @return the baseband statistics.
+ */
+ public long getBasebandStats() {
+ return mBasebandStats;
+ }
+
+ /**
+ * Get the count of slots allocated for current connection.
+ * @return the count of slots allocated for current connection.
+ */
+ public long getSlotsUsed() {
+ return mSlotsUsed;
+ }
+
+ /**
+ * Get the count of Coex denials.
+ * @return the count of CXM denials.
+ */
+ public int getCxmDenials() {
+ return mCxmDenials;
+ }
+
+ /**
+ * Get the count of TX skipped when no poll from remote device.
+ * @return the count of TX skipped.
+ */
+ public int getTxSkipped() {
+ return mTxSkipped;
+ }
+
+ /**
+ * Get the count of RF loss.
+ * @return the count of RF loss.
+ */
+ public int getRfLoss() {
+ return mRfLoss;
+ }
+
+ /**
+ * Get the timestamp when issue happened.
+ * time_ms: N * 0.3125 ms (1 Bluetooth Clock).
+ * @return the timestamp when issue happened.
+ */
+ public long getNativeClock() {
+ return mNativeClock;
+ }
+
+ /**
+ * Get the timestamp of last TX ACK.
+ * time_ms: N * 0.3125 ms (1 Bluetooth Clock).
+ * @return the timestamp of last TX ACK.
+ */
+ public long getLastTxAckTimestamp() {
+ return mLastTxAckTimestamp;
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mConnState);
+ dest.writeLong(mBasebandStats);
+ dest.writeLong(mSlotsUsed);
+ dest.writeInt(mCxmDenials);
+ dest.writeInt(mTxSkipped);
+ dest.writeInt(mRfLoss);
+ dest.writeLong(mNativeClock);
+ dest.writeLong(mLastTxAckTimestamp);
+ }
+
+ @Override
+ public String toString() {
+ String str;
+ str = " BqrVsLsto: {\n"
+ + " mConnState: " + getConnStateStr()
+ + "(" + String.format("0x%02X", mConnState) + ")"
+ + ", mBasebandStats: " + String.format("0x%08X", mBasebandStats)
+ + ", mSlotsUsed: " + mSlotsUsed
+ + ", mCxmDenials: " + mCxmDenials
+ + ", mTxSkipped: " + mTxSkipped
+ + ", mRfLoss: " + mRfLoss
+ + ", mNativeClock: " + String.format("0x%08X", mNativeClock)
+ + ", mLastTxAckTimestamp: " + String.format("0x%08X", mLastTxAckTimestamp)
+ + "\n }";
+
+ return str;
+ }
+ }
+
+ /**
+ * This class provides the public APIs to access the vendor specific part of
+ * A2dp choppy event.
+ */
+ public class BqrVsA2dpChoppy implements Parcelable {
+ private static final String TAG = BluetoothQualityReport.TAG + ".BqrVsA2dpChoppy";
+
+ private long mArrivalTime;
+ private long mScheduleTime;
+ private int mGlitchCount;
+ private int mTxCxmDenials;
+ private int mRxCxmDenials;
+ private int mAclTxQueueLength;
+ private int mLinkQuality;
+
+ private BqrVsA2dpChoppy(byte[] rawData, int offset) {
+ if (rawData == null || rawData.length <= offset) {
+ throw new IllegalArgumentException(TAG + ": BQR raw data length is abnormal.");
+ }
+
+ ByteBuffer bqrBuf = ByteBuffer.wrap(rawData, offset, rawData.length - offset)
+ .asReadOnlyBuffer();
+ bqrBuf.order(ByteOrder.LITTLE_ENDIAN);
+
+ mArrivalTime = bqrBuf.getInt() & 0xFFFFFFFFL;
+ mScheduleTime = bqrBuf.getInt() & 0xFFFFFFFFL;
+ mGlitchCount = bqrBuf.getShort() & 0xFFFF;
+ mTxCxmDenials = bqrBuf.getShort() & 0xFFFF;
+ mRxCxmDenials = bqrBuf.getShort() & 0xFFFF;
+ mAclTxQueueLength = bqrBuf.get() & 0xFF;
+ mLinkQuality = bqrBuf.get() & 0xFF;
+ }
+
+ private BqrVsA2dpChoppy(Parcel in) {
+ mArrivalTime = in.readLong();
+ mScheduleTime = in.readLong();
+ mGlitchCount = in.readInt();
+ mTxCxmDenials = in.readInt();
+ mRxCxmDenials = in.readInt();
+ mAclTxQueueLength = in.readInt();
+ mLinkQuality = in.readInt();
+ }
+
+ /**
+ * Get the timestamp of a2dp packet arrived.
+ * time_ms: N * 0.3125 ms (1 Bluetooth Clock).
+ * @return the timestamp of a2dp packet arrived.
+ */
+ public long getArrivalTime() {
+ return mArrivalTime;
+ }
+
+ /**
+ * Get the timestamp of a2dp packet scheduled.
+ * time_ms: N * 0.3125 ms (1 Bluetooth Clock).
+ * @return the timestamp of a2dp packet scheduled.
+ */
+ public long getScheduleTime() {
+ return mScheduleTime;
+ }
+
+ /**
+ * Get the a2dp glitch count since the last event.
+ * @return the a2dp glitch count.
+ */
+ public int getGlitchCount() {
+ return mGlitchCount;
+ }
+
+ /**
+ * Get the count of Coex TX denials.
+ * @return the count of Coex TX denials.
+ */
+ public int getTxCxmDenials() {
+ return mTxCxmDenials;
+ }
+
+ /**
+ * Get the count of Coex RX denials.
+ * @return the count of Coex RX denials.
+ */
+ public int getRxCxmDenials() {
+ return mRxCxmDenials;
+ }
+
+ /**
+ * Get the ACL queue length which are pending TX in FW.
+ * @return the ACL queue length.
+ */
+ public int getAclTxQueueLength() {
+ return mAclTxQueueLength;
+ }
+
+ /**
+ * Get the link quality for the current connection.
+ * @return the link quality.
+ */
+ public int getLinkQuality() {
+ return mLinkQuality;
+ }
+
+ /**
+ * Get the string of link quality for the current connection.
+ * @return the string of link quality.
+ */
+ public String getLinkQualityStr() {
+ LinkQuality q = LinkQuality.fromOrdinal(mLinkQuality);
+ return q.toString();
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeLong(mArrivalTime);
+ dest.writeLong(mScheduleTime);
+ dest.writeInt(mGlitchCount);
+ dest.writeInt(mTxCxmDenials);
+ dest.writeInt(mRxCxmDenials);
+ dest.writeInt(mAclTxQueueLength);
+ dest.writeInt(mLinkQuality);
+ }
+
+ @Override
+ public String toString() {
+ String str;
+ str = " BqrVsA2dpChoppy: {\n"
+ + " mArrivalTime: " + String.format("0x%08X", mArrivalTime)
+ + ", mScheduleTime: " + String.format("0x%08X", mScheduleTime)
+ + ", mGlitchCount: " + mGlitchCount
+ + ", mTxCxmDenials: " + mTxCxmDenials
+ + ", mRxCxmDenials: " + mRxCxmDenials
+ + ", mAclTxQueueLength: " + mAclTxQueueLength
+ + ", mLinkQuality: " + getLinkQualityStr()
+ + "(" + String.format("0x%02X", mLinkQuality) + ")"
+ + "\n }";
+
+ return str;
+ }
+
+ }
+
+ /**
+ * This class provides the public APIs to access the vendor specific part of
+ * SCO choppy event.
+ */
+ public class BqrVsScoChoppy implements Parcelable {
+ private static final String TAG = BluetoothQualityReport.TAG + ".BqrVsScoChoppy";
+
+ private int mGlitchCount;
+ private int mIntervalEsco;
+ private int mWindowEsco;
+ private int mAirFormat;
+ private int mInstanceCount;
+ private int mTxCxmDenials;
+ private int mRxCxmDenials;
+ private int mTxAbortCount;
+ private int mLateDispatch;
+ private int mMicIntrMiss;
+ private int mLpaIntrMiss;
+ private int mSprIntrMiss;
+ private int mPlcFillCount;
+ private int mPlcDiscardCount;
+
+ private BqrVsScoChoppy(byte[] rawData, int offset) {
+ if (rawData == null || rawData.length <= offset) {
+ throw new IllegalArgumentException(TAG + ": BQR raw data length is abnormal.");
+ }
+
+ ByteBuffer bqrBuf = ByteBuffer.wrap(rawData, offset, rawData.length - offset)
+ .asReadOnlyBuffer();
+ bqrBuf.order(ByteOrder.LITTLE_ENDIAN);
+
+ mGlitchCount = bqrBuf.getShort() & 0xFFFF;
+ mIntervalEsco = bqrBuf.get() & 0xFF;
+ mWindowEsco = bqrBuf.get() & 0xFF;
+ mAirFormat = bqrBuf.get() & 0xFF;
+ mInstanceCount = bqrBuf.getShort() & 0xFFFF;
+ mTxCxmDenials = bqrBuf.getShort() & 0xFFFF;
+ mRxCxmDenials = bqrBuf.getShort() & 0xFFFF;
+ mTxAbortCount = bqrBuf.getShort() & 0xFFFF;
+ mLateDispatch = bqrBuf.getShort() & 0xFFFF;
+ mMicIntrMiss = bqrBuf.getShort() & 0xFFFF;
+ mLpaIntrMiss = bqrBuf.getShort() & 0xFFFF;
+ mSprIntrMiss = bqrBuf.getShort() & 0xFFFF;
+ mPlcFillCount = bqrBuf.getShort() & 0xFFFF;
+ mPlcDiscardCount = bqrBuf.getShort() & 0xFFFF;
+ }
+
+ private BqrVsScoChoppy(Parcel in) {
+ mGlitchCount = in.readInt();
+ mIntervalEsco = in.readInt();
+ mWindowEsco = in.readInt();
+ mAirFormat = in.readInt();
+ mInstanceCount = in.readInt();
+ mTxCxmDenials = in.readInt();
+ mRxCxmDenials = in.readInt();
+ mTxAbortCount = in.readInt();
+ mLateDispatch = in.readInt();
+ mMicIntrMiss = in.readInt();
+ mLpaIntrMiss = in.readInt();
+ mSprIntrMiss = in.readInt();
+ mPlcFillCount = in.readInt();
+ mPlcDiscardCount = in.readInt();
+ }
+
+ /**
+ * Get the sco glitch count since the last event.
+ * @return the sco glitch count.
+ */
+ public int getGlitchCount() {
+ return mGlitchCount;
+ }
+
+ /**
+ * Get ESCO interval in slots. It is the value of Transmission_Interval parameter in
+ * Synchronous Connection Complete event.
+ * @return ESCO interval in slots.
+ */
+ public int getIntervalEsco() {
+ return mIntervalEsco;
+ }
+
+ /**
+ * Get ESCO window in slots. It is the value of Retransmission Window parameter in
+ * Synchronous Connection Complete event.
+ * @return ESCO window in slots.
+ */
+ public int getWindowEsco() {
+ return mWindowEsco;
+ }
+
+ /**
+ * Get the air mode. It is the value of Air Mode parameter in
+ * Synchronous Connection Complete event.
+ * @return the air mode.
+ */
+ public int getAirFormat() {
+ return mAirFormat;
+ }
+
+ /**
+ * Get the string of air mode.
+ * @return the string of air mode.
+ */
+ public String getAirFormatStr() {
+ AirMode m = AirMode.fromOrdinal(mAirFormat);
+ return m.toString();
+ }
+
+ /**
+ * Get the xSCO instance count.
+ * @return the xSCO instance count.
+ */
+ public int getInstanceCount() {
+ return mInstanceCount;
+ }
+
+ /**
+ * Get the count of Coex TX denials.
+ * @return the count of Coex TX denials.
+ */
+ public int getTxCxmDenials() {
+ return mTxCxmDenials;
+ }
+
+ /**
+ * Get the count of Coex RX denials.
+ * @return the count of Coex RX denials.
+ */
+ public int getRxCxmDenials() {
+ return mRxCxmDenials;
+ }
+
+ /**
+ * Get the count of sco packets aborted.
+ * @return the count of sco packets aborted.
+ */
+ public int getTxAbortCount() {
+ return mTxAbortCount;
+ }
+
+ /**
+ * Get the count of sco packets dispatched late.
+ * @return the count of sco packets dispatched late.
+ */
+ public int getLateDispatch() {
+ return mLateDispatch;
+ }
+
+ /**
+ * Get the count of missed Mic interrrupts.
+ * @return the count of missed Mic interrrupts.
+ */
+ public int getMicIntrMiss() {
+ return mMicIntrMiss;
+ }
+
+ /**
+ * Get the count of missed LPA interrrupts.
+ * @return the count of missed LPA interrrupts.
+ */
+ public int getLpaIntrMiss() {
+ return mLpaIntrMiss;
+ }
+
+ /**
+ * Get the count of missed Speaker interrrupts.
+ * @return the count of missed Speaker interrrupts.
+ */
+ public int getSprIntrMiss() {
+ return mSprIntrMiss;
+ }
+
+ /**
+ * Get the count of packet loss concealment filled.
+ * @return the count of packet loss concealment filled.
+ */
+ public int getPlcFillCount() {
+ return mPlcFillCount;
+ }
+
+ /**
+ * Get the count of packet loss concealment discarded.
+ * @return the count of packet loss concealment discarded.
+ */
+ public int getPlcDiscardCount() {
+ return mPlcDiscardCount;
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mGlitchCount);
+ dest.writeInt(mIntervalEsco);
+ dest.writeInt(mWindowEsco);
+ dest.writeInt(mAirFormat);
+ dest.writeInt(mInstanceCount);
+ dest.writeInt(mTxCxmDenials);
+ dest.writeInt(mRxCxmDenials);
+ dest.writeInt(mTxAbortCount);
+ dest.writeInt(mLateDispatch);
+ dest.writeInt(mMicIntrMiss);
+ dest.writeInt(mLpaIntrMiss);
+ dest.writeInt(mSprIntrMiss);
+ dest.writeInt(mPlcFillCount);
+ dest.writeInt(mPlcDiscardCount);
+ }
+
+ @Override
+ public String toString() {
+ String str;
+ str = " BqrVsScoChoppy: {\n"
+ + " mGlitchCount: " + mGlitchCount
+ + ", mIntervalEsco: " + mIntervalEsco
+ + ", mWindowEsco: " + mWindowEsco
+ + ", mAirFormat: " + getAirFormatStr()
+ + "(" + String.format("0x%02X", mAirFormat) + ")"
+ + ", mInstanceCount: " + mInstanceCount
+ + ", mTxCxmDenials: " + mTxCxmDenials
+ + ", mRxCxmDenials: " + mRxCxmDenials
+ + ", mTxAbortCount: " + mTxAbortCount
+ + ",\n"
+ + " mLateDispatch: " + mLateDispatch
+ + ", mMicIntrMiss: " + mMicIntrMiss
+ + ", mLpaIntrMiss: " + mLpaIntrMiss
+ + ", mSprIntrMiss: " + mSprIntrMiss
+ + ", mPlcFillCount: " + mPlcFillCount
+ + ", mPlcDiscardCount: " + mPlcDiscardCount
+ + "\n }";
+
+ return str;
+ }
+
+ }
+
+ /**
+ * This class provides the public APIs to access the vendor specific part of
+ * Connect fail event.
+ */
+ public class BqrVsConnectFail implements Parcelable {
+ private static final String TAG = BluetoothQualityReport.TAG + ".BqrVsConnectFail";
+
+ private int mFailReason;
+
+ private BqrVsConnectFail(byte[] rawData, int offset) {
+ if (rawData == null || rawData.length <= offset) {
+ throw new IllegalArgumentException(TAG + ": BQR raw data length is abnormal.");
+ }
+
+ ByteBuffer bqrBuf = ByteBuffer.wrap(rawData, offset, rawData.length - offset)
+ .asReadOnlyBuffer();
+ bqrBuf.order(ByteOrder.LITTLE_ENDIAN);
+
+ mFailReason = bqrBuf.get() & 0xFF;
+ }
+
+ private BqrVsConnectFail(Parcel in) {
+ mFailReason = in.readInt();
+ }
+
+ /**
+ * Get the fail reason.
+ * @return the fail reason.
+ */
+ public int getFailReason() {
+ return mFailReason;
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mFailReason);
+ }
+
+ @Override
+ public String toString() {
+ String str;
+ str = " BqrVsConnectFail: {\n"
+ + " mFailReason: " + String.format("0x%02X", mFailReason)
+ + "\n }";
+
+ return str;
+ }
+ }
+
+}
diff --git a/core/java/android/bluetooth/le/AdvertiseData.java b/core/java/android/bluetooth/le/AdvertiseData.java
index 5fd8258..d7f22bf 100644
--- a/core/java/android/bluetooth/le/AdvertiseData.java
+++ b/core/java/android/bluetooth/le/AdvertiseData.java
@@ -47,17 +47,20 @@
private final Map<ParcelUuid, byte[]> mServiceData;
private final boolean mIncludeTxPowerLevel;
private final boolean mIncludeDeviceName;
+ private final byte[] mTransportDiscoveryData;
private AdvertiseData(List<ParcelUuid> serviceUuids,
SparseArray<byte[]> manufacturerData,
Map<ParcelUuid, byte[]> serviceData,
boolean includeTxPowerLevel,
- boolean includeDeviceName) {
+ boolean includeDeviceName,
+ byte[] transportDiscoveryData) {
mServiceUuids = serviceUuids;
mManufacturerSpecificData = manufacturerData;
mServiceData = serviceData;
mIncludeTxPowerLevel = includeTxPowerLevel;
mIncludeDeviceName = includeDeviceName;
+ mTransportDiscoveryData = transportDiscoveryData;
}
/**
@@ -98,12 +101,20 @@
}
/**
+ * Returns an array of Transport Discovery data.
+ * @hide
+ */
+ public byte[] getTransportDiscoveryData() {
+ return mTransportDiscoveryData;
+ }
+
+ /**
* @hide
*/
@Override
public int hashCode() {
return Objects.hash(mServiceUuids, mManufacturerSpecificData, mServiceData,
- mIncludeDeviceName, mIncludeTxPowerLevel);
+ mIncludeDeviceName, mIncludeTxPowerLevel, mTransportDiscoveryData);
}
/**
@@ -123,7 +134,8 @@
other.mManufacturerSpecificData)
&& BluetoothLeUtils.equals(mServiceData, other.mServiceData)
&& mIncludeDeviceName == other.mIncludeDeviceName
- && mIncludeTxPowerLevel == other.mIncludeTxPowerLevel;
+ && mIncludeTxPowerLevel == other.mIncludeTxPowerLevel
+ && BluetoothLeUtils.equals(mTransportDiscoveryData, other.mTransportDiscoveryData);
}
@Override
@@ -132,7 +144,8 @@
+ BluetoothLeUtils.toString(mManufacturerSpecificData) + ", mServiceData="
+ BluetoothLeUtils.toString(mServiceData)
+ ", mIncludeTxPowerLevel=" + mIncludeTxPowerLevel + ", mIncludeDeviceName="
- + mIncludeDeviceName + "]";
+ + mIncludeDeviceName + ", mTransportDiscoveryData="
+ + BluetoothLeUtils.toString(mTransportDiscoveryData)+ "]";
}
@Override
@@ -157,6 +170,10 @@
}
dest.writeByte((byte) (getIncludeTxPowerLevel() ? 1 : 0));
dest.writeByte((byte) (getIncludeDeviceName() ? 1 : 0));
+ dest.writeInt(mTransportDiscoveryData != null ? mTransportDiscoveryData.length : 0);
+ if (mTransportDiscoveryData != null) {
+ dest.writeByteArray(mTransportDiscoveryData);
+ }
}
public static final @android.annotation.NonNull Parcelable.Creator<AdvertiseData> CREATOR =
@@ -188,6 +205,11 @@
}
builder.setIncludeTxPowerLevel(in.readByte() == 1);
builder.setIncludeDeviceName(in.readByte() == 1);
+ int transportDiscoveryDataSize = in.readInt();
+ if (transportDiscoveryDataSize > 0) {
+ byte[] transportDiscoveryData = in.createByteArray();
+ builder.addTransportDiscoveryData(transportDiscoveryData);
+ }
return builder.build();
}
};
@@ -202,6 +224,7 @@
private Map<ParcelUuid, byte[]> mServiceData = new ArrayMap<ParcelUuid, byte[]>();
private boolean mIncludeTxPowerLevel;
private boolean mIncludeDeviceName;
+ private byte[] mTransportDiscoveryData;
/**
* Add a service UUID to advertise data.
@@ -276,11 +299,23 @@
}
/**
+ * Add Transport Discovery data
+ * @hide
+ */
+ public Builder addTransportDiscoveryData(byte[] transportDiscoveryData) {
+ if ((transportDiscoveryData == null) || (transportDiscoveryData.length == 0)) {
+ throw new IllegalArgumentException("transportDiscoveryData is null");
+ }
+ mTransportDiscoveryData = transportDiscoveryData;
+ return this;
+ }
+
+ /**
* Build the {@link AdvertiseData}.
*/
public AdvertiseData build() {
return new AdvertiseData(mServiceUuids, mManufacturerSpecificData, mServiceData,
- mIncludeTxPowerLevel, mIncludeDeviceName);
+ mIncludeTxPowerLevel, mIncludeDeviceName, mTransportDiscoveryData);
}
}
}
diff --git a/core/java/android/bluetooth/le/BluetoothLeScanner.java b/core/java/android/bluetooth/le/BluetoothLeScanner.java
index 9a17346..09dd20f 100644
--- a/core/java/android/bluetooth/le/BluetoothLeScanner.java
+++ b/core/java/android/bluetooth/le/BluetoothLeScanner.java
@@ -32,6 +32,7 @@
import android.os.WorkSource;
import android.util.Log;
+import java.util.Arrays;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -235,6 +236,13 @@
if (gatt == null) {
return postCallbackErrorOrReturn(callback, ScanCallback.SCAN_FAILED_INTERNAL_ERROR);
}
+
+ if ((settings.getCallbackType() == ScanSettings.CALLBACK_TYPE_SENSOR_ROUTING)
+ && (filters == null || filters.isEmpty())) {
+ ScanFilter filter = (new ScanFilter.Builder()).build();
+ filters = Arrays.asList(filter);
+ }
+
if (!isSettingsConfigAllowedForScan(settings)) {
return postCallbackErrorOrReturn(callback,
ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED);
@@ -247,6 +255,10 @@
return postCallbackErrorOrReturn(callback,
ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED);
}
+ if (!isRoutingAllowedForScan(settings)) {
+ return postCallbackErrorOrReturn(callback,
+ ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED);
+ }
if (callback != null) {
BleScanCallbackWrapper wrapper = new BleScanCallbackWrapper(gatt, filters,
settings, workSource, callback, resultStorages);
@@ -605,4 +617,14 @@
}
return true;
}
+
+ private boolean isRoutingAllowedForScan(ScanSettings settings) {
+ final int callbackType = settings.getCallbackType();
+
+ if (callbackType == ScanSettings.CALLBACK_TYPE_SENSOR_ROUTING
+ && settings.getScanMode() == ScanSettings.SCAN_MODE_OPPORTUNISTIC) {
+ return false;
+ }
+ return true;
+ }
}
diff --git a/core/java/android/bluetooth/le/BluetoothLeUtils.java b/core/java/android/bluetooth/le/BluetoothLeUtils.java
index 6381f55..f8d1c51 100644
--- a/core/java/android/bluetooth/le/BluetoothLeUtils.java
+++ b/core/java/android/bluetooth/le/BluetoothLeUtils.java
@@ -77,6 +77,28 @@
}
/**
+ * Returns a string composed from a byte array.
+ */
+ static <T> String toString(byte[] data) {
+ if (data == null) {
+ return "null";
+ }
+ if (data.length == 0) {
+ return "{}";
+ }
+ StringBuilder buffer = new StringBuilder();
+ buffer.append('{');
+ for(int i=0; i < data.length; i++) {
+ buffer.append(data[i]);
+ if ((i+1) < data.length) {
+ buffer.append(", ");
+ }
+ }
+ buffer.append('}');
+ return buffer.toString();
+ }
+
+ /**
* Check whether two {@link SparseArray} equal.
*/
static boolean equals(SparseArray<byte[]> array, SparseArray<byte[]> otherArray) {
@@ -126,6 +148,25 @@
}
/**
+ * Check whether two byte arrays are equal.
+ */
+ static <T> boolean equals(byte[] data, byte[] otherData) {
+ if (data == otherData) {
+ return true;
+ }
+ if (data == null || otherData == null) {
+ return false;
+ }
+ if (data.length != otherData.length) {
+ return false;
+ }
+ if (!Objects.deepEquals(data, otherData)) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
* Ensure Bluetooth is turned on.
*
* @throws IllegalStateException If {@code adapter} is null or Bluetooth state is not {@link
diff --git a/core/java/android/bluetooth/le/ScanFilter.java b/core/java/android/bluetooth/le/ScanFilter.java
index 7511fd0..108141c 100644
--- a/core/java/android/bluetooth/le/ScanFilter.java
+++ b/core/java/android/bluetooth/le/ScanFilter.java
@@ -47,6 +47,12 @@
*/
public final class ScanFilter implements Parcelable {
+ /**
+ * Provide TDS data scan results for WiFi Alliance Org id
+ * @hide
+ */
+ public static final int WIFI_ALLIANCE_ORG_ID = 2;
+
@Nullable
private final String mDeviceName;
@@ -76,6 +82,11 @@
@Nullable
private final byte[] mManufacturerDataMask;
+ private final int mOrgId;
+ private final int mTDSFlags;
+ private final int mTDSFlagsMask;
+ private final byte[] mWifiNANHash;
+
/** @hide */
public static final ScanFilter EMPTY = new ScanFilter.Builder().build();
@@ -84,7 +95,8 @@
ParcelUuid uuidMask, ParcelUuid solicitationUuid,
ParcelUuid solicitationUuidMask, ParcelUuid serviceDataUuid,
byte[] serviceData, byte[] serviceDataMask,
- int manufacturerId, byte[] manufacturerData, byte[] manufacturerDataMask) {
+ int manufacturerId, byte[] manufacturerData, byte[] manufacturerDataMask,
+ int orgId, int TDSFlags, int TDSFlagsMask, byte[] wifiNANHash) {
mDeviceName = name;
mServiceUuid = uuid;
mServiceUuidMask = uuidMask;
@@ -97,6 +109,10 @@
mManufacturerId = manufacturerId;
mManufacturerData = manufacturerData;
mManufacturerDataMask = manufacturerDataMask;
+ mOrgId = orgId;
+ mTDSFlags = TDSFlags;
+ mTDSFlagsMask = TDSFlagsMask;
+ mWifiNANHash = wifiNANHash;
}
@Override
@@ -157,6 +173,17 @@
dest.writeByteArray(mManufacturerDataMask);
}
}
+ dest.writeInt(mOrgId);
+ dest.writeInt(mOrgId < 0 ? 0 : 1);
+ if(mOrgId >= 0) {
+ dest.writeInt(mTDSFlags);
+ dest.writeInt(mTDSFlagsMask);
+ dest.writeInt(mWifiNANHash == null ? 0 : 1);
+ if (mWifiNANHash != null) {
+ dest.writeInt(mWifiNANHash.length);
+ dest.writeByteArray(mWifiNANHash);
+ }
+ }
}
/**
@@ -234,6 +261,22 @@
}
}
+ int orgId = in.readInt();
+ if(in.readInt() == 1) {
+ int tdsFlags = in.readInt();
+ int tdsFlagsMask = in.readInt();
+ if (in.readInt() == 1) {
+ int wifiNANHashLength = in.readInt();
+ byte[] wifiNanHash = new byte[wifiNANHashLength];
+ in.readByteArray(wifiNanHash);
+ builder.setTransportDiscoveryData(orgId, tdsFlags, tdsFlagsMask,
+ wifiNanHash);
+ }
+ else {
+ builder.setTransportDiscoveryData(orgId, tdsFlags, tdsFlagsMask, null);
+ }
+ }
+
return builder.build();
}
};
@@ -313,6 +356,37 @@
}
/**
+ * @hide
+ * Returns the organization id. -1 if the organization id is not set.
+ */
+ public int getOrgId() {
+ return mOrgId;
+ }
+
+ /**
+ * @hide
+ * Returns the TDS flags. -1 if TDS flags is not set.
+ */
+ public int getTDSFlags() {
+ return mTDSFlags;
+ }
+
+ /**
+ * @hide
+ * Returns the TDS flags mask. -1 if TDS flags mask is not set.
+ */
+ public int getTDSFlagsMask() {
+ return mTDSFlagsMask;
+ }
+
+ /**
+ * @hide
+ */
+ public byte[] getWifiNANHash() {
+ return mWifiNANHash;
+ }
+
+ /**
* Check if the scan filter matches a {@code scanResult}. A scan result is considered as a match
* if it matches all the field filters.
*/
@@ -369,6 +443,18 @@
return false;
}
}
+
+ //Transport Discovery data match
+ if(mOrgId >= 0) {
+ byte[] tdsData = scanRecord.getTDSData();
+ if ((tdsData != null) && (tdsData.length > 0)) {
+ if ((mOrgId != tdsData[0]) ||
+ ((mTDSFlags & mTDSFlagsMask) != (tdsData[1] & mTDSFlagsMask))) {
+ return false;
+ }
+ }
+ }
+
// All filters match.
return true;
}
@@ -463,7 +549,10 @@
+ Arrays.toString(mServiceData) + ", mServiceDataMask="
+ Arrays.toString(mServiceDataMask) + ", mManufacturerId=" + mManufacturerId
+ ", mManufacturerData=" + Arrays.toString(mManufacturerData)
- + ", mManufacturerDataMask=" + Arrays.toString(mManufacturerDataMask) + "]";
+ + ", mManufacturerDataMask=" + Arrays.toString(mManufacturerDataMask)
+ + ", mOrganizationId=" + mOrgId + ", mTDSFlags=" + mTDSFlags
+ + ", mTDSFlagsMask=" + mTDSFlagsMask
+ + ", mWifiNANHash=" + Arrays.toString(mWifiNANHash) +"]";
}
@Override
@@ -475,7 +564,8 @@
Arrays.hashCode(mServiceData),
Arrays.hashCode(mServiceDataMask),
mServiceUuid, mServiceUuidMask,
- mServiceSolicitationUuid, mServiceSolicitationUuidMask);
+ mServiceSolicitationUuid, mServiceSolicitationUuidMask,
+ mOrgId, mTDSFlags, mTDSFlagsMask, Arrays.hashCode(mWifiNANHash));
}
@Override
@@ -499,7 +589,11 @@
&& Objects.equals(mServiceUuidMask, other.mServiceUuidMask)
&& Objects.equals(mServiceSolicitationUuid, other.mServiceSolicitationUuid)
&& Objects.equals(mServiceSolicitationUuidMask,
- other.mServiceSolicitationUuidMask);
+ other.mServiceSolicitationUuidMask)
+ && mOrgId == other.mOrgId
+ && mTDSFlags == other.mTDSFlags
+ && mTDSFlagsMask == other.mTDSFlagsMask
+ && Objects.deepEquals(mWifiNANHash, other.mWifiNANHash);
}
/**
@@ -533,6 +627,11 @@
private byte[] mManufacturerData;
private byte[] mManufacturerDataMask;
+ private int mOrgId = -1;
+ private int mTDSFlags = -1;
+ private int mTDSFlagsMask = -1;
+ private byte[] mWifiNANHash;
+
/**
* Set filter on device name.
*/
@@ -717,6 +816,27 @@
return this;
}
+
+ /**
+ * @hide
+ * Set filter on transport discovery data.
+ * @throws IllegalArgumentException If the {@code orgId} is invalid or {@code
+ * wifiNANhash} is not null while {@code orgId} is non-Wifi.
+ */
+ public Builder setTransportDiscoveryData(int orgId, int TDSFlags, int TDSFlagsMask,
+ byte[] wifiNANHash) {
+ if (orgId < 0) {
+ throw new IllegalArgumentException("invalid organization id");
+ }
+ if ((orgId != WIFI_ALLIANCE_ORG_ID) && (wifiNANHash != null)) {
+ throw new IllegalArgumentException("Wifi NAN Hash is not null for non-Wifi Org Id");
+ }
+ mOrgId = orgId;
+ mTDSFlags = TDSFlags;
+ mTDSFlagsMask = TDSFlagsMask;
+ mWifiNANHash = wifiNANHash;
+ return this;
+ }
/**
* Build {@link ScanFilter}.
*
@@ -727,7 +847,8 @@
mServiceUuid, mUuidMask, mServiceSolicitationUuid,
mServiceSolicitationUuidMask,
mServiceDataUuid, mServiceData, mServiceDataMask,
- mManufacturerId, mManufacturerData, mManufacturerDataMask);
+ mManufacturerId, mManufacturerData, mManufacturerDataMask,
+ mOrgId, mTDSFlags, mTDSFlagsMask, mWifiNANHash);
}
}
}
diff --git a/core/java/android/bluetooth/le/ScanRecord.java b/core/java/android/bluetooth/le/ScanRecord.java
index c0c1aa1..abcb381 100644
--- a/core/java/android/bluetooth/le/ScanRecord.java
+++ b/core/java/android/bluetooth/le/ScanRecord.java
@@ -56,6 +56,7 @@
private static final int DATA_TYPE_SERVICE_SOLICITATION_UUIDS_32_BIT = 0x1F;
private static final int DATA_TYPE_SERVICE_SOLICITATION_UUIDS_128_BIT = 0x15;
private static final int DATA_TYPE_MANUFACTURER_SPECIFIC_DATA = 0xFF;
+ private static final int DATA_TYPE_TRANSPORT_DISCOVERY_DATA = 0x26;
// Flags of the advertising data.
private final int mAdvertiseFlags;
@@ -78,6 +79,9 @@
// Raw bytes of scan record.
private final byte[] mBytes;
+ // Transport Discovery data.
+ private final byte[] mTDSData;
+
/**
* Returns the advertising flags indicating the discoverable mode and capability of the device.
* Returns -1 if the flag field is not set.
@@ -162,6 +166,14 @@
}
/**
+ * @hide
+ * Returns Transport Discovery data
+ */
+ public byte[] getTDSData() {
+ return mTDSData;
+ }
+
+ /**
* Returns raw bytes of scan record.
*/
public byte[] getBytes() {
@@ -173,7 +185,7 @@
SparseArray<byte[]> manufacturerData,
Map<ParcelUuid, byte[]> serviceData,
int advertiseFlags, int txPowerLevel,
- String localName, byte[] bytes) {
+ String localName, byte[] tdsData, byte[] bytes) {
mServiceSolicitationUuids = serviceSolicitationUuids;
mServiceUuids = serviceUuids;
mManufacturerSpecificData = manufacturerData;
@@ -181,6 +193,7 @@
mDeviceName = localName;
mAdvertiseFlags = advertiseFlags;
mTxPowerLevel = txPowerLevel;
+ mTDSData = tdsData;
mBytes = bytes;
}
@@ -211,6 +224,8 @@
SparseArray<byte[]> manufacturerData = new SparseArray<byte[]>();
Map<ParcelUuid, byte[]> serviceData = new ArrayMap<ParcelUuid, byte[]>();
+ byte[] tdsData = null;
+
try {
while (currentPos < scanRecord.length) {
// length is unsigned int.
@@ -288,6 +303,9 @@
dataLength - 2);
manufacturerData.put(manufacturerId, manufacturerDataBytes);
break;
+ case DATA_TYPE_TRANSPORT_DISCOVERY_DATA:
+ tdsData = extractBytes(scanRecord, currentPos, dataLength);
+ break;
default:
// Just ignore, we don't handle such data type.
break;
@@ -299,12 +317,12 @@
serviceUuids = null;
}
return new ScanRecord(serviceUuids, serviceSolicitationUuids, manufacturerData,
- serviceData, advertiseFlag, txPowerLevel, localName, scanRecord);
+ serviceData, advertiseFlag, txPowerLevel, localName, tdsData, scanRecord);
} catch (Exception e) {
Log.e(TAG, "unable to parse scan record: " + Arrays.toString(scanRecord));
// As the record is invalid, ignore all the parsed results for this packet
// and return an empty record with raw scanRecord bytes in results
- return new ScanRecord(null, null, null, null, -1, Integer.MIN_VALUE, null, scanRecord);
+ return new ScanRecord(null, null, null, null, -1, Integer.MIN_VALUE, null, null, scanRecord);
}
}
@@ -315,7 +333,8 @@
+ ", mManufacturerSpecificData=" + BluetoothLeUtils.toString(
mManufacturerSpecificData)
+ ", mServiceData=" + BluetoothLeUtils.toString(mServiceData)
- + ", mTxPowerLevel=" + mTxPowerLevel + ", mDeviceName=" + mDeviceName + "]";
+ + ", mTxPowerLevel=" + mTxPowerLevel + ", mDeviceName=" + mDeviceName +
+ ", mTDSData=" + BluetoothLeUtils.toString(mTDSData) +"]";
}
// Parse service UUIDs.
diff --git a/core/java/android/bluetooth/le/ScanSettings.java b/core/java/android/bluetooth/le/ScanSettings.java
index 504118e..bd6e9d5 100644
--- a/core/java/android/bluetooth/le/ScanSettings.java
+++ b/core/java/android/bluetooth/le/ScanSettings.java
@@ -69,6 +69,12 @@
*/
public static final int CALLBACK_TYPE_MATCH_LOST = 4;
+ /**
+ * Provide results to sensor router instead of the apps processor
+ * @hide
+ */
+ public static final int CALLBACK_TYPE_SENSOR_ROUTING = 8;
+
/**
* Determines how many advertisements to match per filter, as this is scarce hw resource
@@ -302,7 +308,8 @@
private boolean isValidCallbackType(int callbackType) {
if (callbackType == CALLBACK_TYPE_ALL_MATCHES
|| callbackType == CALLBACK_TYPE_FIRST_MATCH
- || callbackType == CALLBACK_TYPE_MATCH_LOST) {
+ || callbackType == CALLBACK_TYPE_MATCH_LOST
+ || callbackType == CALLBACK_TYPE_SENSOR_ROUTING) {
return true;
}
return callbackType == (CALLBACK_TYPE_FIRST_MATCH | CALLBACK_TYPE_MATCH_LOST);
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index ededd0d..7770e64 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -3295,6 +3295,21 @@
public static final String ACTION_AIRPLANE_MODE_CHANGED = "android.intent.action.AIRPLANE_MODE";
/**
+ * <p>Broadcast Action: The user has changed carrier label:</p>
+ * <ul>
+ * <li><em>state</em> - String value.</li>
+ * </ul>
+ *
+ * <p class="note">This is a protected intent that can only be sent
+ * by the system.
+ *
+ * @hide
+ */
+ //@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_CUSTOM_CARRIER_LABEL_CHANGED
+ = "android.intent.action.CUSTOM_CARRIER_LABEL";
+
+ /**
* Broadcast Action: Some content providers have parts of their namespace
* where they publish new events or items that the user may be especially
* interested in. For these things, they may broadcast this action when the
@@ -4661,6 +4676,15 @@
public static final String ACTION_PACKAGE_NEEDS_INTEGRITY_VERIFICATION =
"android.intent.action.PACKAGE_NEEDS_INTEGRITY_VERIFICATION";
+ /**
+ * 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/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 70e4e6c..967d59b 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -3572,11 +3572,7 @@
ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_ALLOW_CLEAR_USER_DATA_ON_FAILED_RESTORE;
}
- if (sa.getBoolean(
- R.styleable.AndroidManifestApplication_allowAudioPlaybackCapture,
- owner.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.Q)) {
- ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE;
- }
+ ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE;
if (sa.getBoolean(
R.styleable.AndroidManifestApplication_requestLegacyExternalStorage,
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 7c4692c..cc812ef 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -573,7 +573,10 @@
SQLiteSession.TRANSACTION_MODE_IMMEDIATE,
transactionListener,
getThreadDefaultConnectionFlags(false /*readOnly*/), null);
- } finally {
+ } catch (SQLiteDatabaseCorruptException ex) {
+ onCorruption();
+ throw ex;
+ }finally {
releaseReference();
}
}
@@ -586,6 +589,9 @@
acquireReference();
try {
getThreadSession().endTransaction(null);
+ } catch (SQLiteDatabaseCorruptException ex) {
+ onCorruption();
+ throw ex;
} finally {
releaseReference();
}
@@ -703,6 +709,9 @@
acquireReference();
try {
return getThreadSession().yieldTransaction(sleepAfterYieldDelay, throwIfUnsafe, null);
+ } catch (SQLiteDatabaseCorruptException ex) {
+ onCorruption();
+ throw ex;
} finally {
releaseReference();
}
@@ -2438,33 +2447,17 @@
public boolean isDatabaseIntegrityOk() {
acquireReference();
try {
- List<Pair<String, String>> attachedDbs = null;
+ SQLiteStatement prog = null;
try {
- attachedDbs = getAttachedDbs();
- if (attachedDbs == null) {
- throw new IllegalStateException("databaselist for: " + getPath() + " couldn't " +
- "be retrieved. probably because the database is closed");
+ prog = compileStatement("PRAGMA integrity_check(1);");
+ String rslt = prog.simpleQueryForString();
+ if (!rslt.equalsIgnoreCase("ok")) {
+ // integrity_checker failed on main or attached databases
+ Log.e(TAG, "PRAGMA integrity_check returned: " + rslt);
+ return false;
}
- } catch (SQLiteException e) {
- // can't get attachedDb list. do integrity check on the main database
- attachedDbs = new ArrayList<Pair<String, String>>();
- attachedDbs.add(new Pair<String, String>("main", getPath()));
- }
-
- for (int i = 0; i < attachedDbs.size(); i++) {
- Pair<String, String> p = attachedDbs.get(i);
- SQLiteStatement prog = null;
- try {
- prog = compileStatement("PRAGMA " + p.first + ".integrity_check(1);");
- String rslt = prog.simpleQueryForString();
- if (!rslt.equalsIgnoreCase("ok")) {
- // integrity_checker failed on main or attached databases
- Log.e(TAG, "PRAGMA integrity_check on " + p.second + " returned: " + rslt);
- return false;
- }
- } finally {
- if (prog != null) prog.close();
- }
+ } finally {
+ if (prog != null) prog.close();
}
} finally {
releaseReference();
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 25279b3..e135ce4 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -45,6 +45,7 @@
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.SystemProperties;
import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.RSIllegalArgumentException;
@@ -62,6 +63,7 @@
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
@@ -171,6 +173,10 @@
private static final int CAMERA_MSG_RAW_IMAGE_NOTIFY = 0x200;
private static final int CAMERA_MSG_PREVIEW_METADATA = 0x400;
private static final int CAMERA_MSG_FOCUS_MOVE = 0x800;
+ /* ### QC ADD-ONS: START */
+ private static final int CAMERA_MSG_STATS_DATA = 0x1000;
+ private static final int CAMERA_MSG_META_DATA = 0x2000;
+ /* ### QC ADD-ONS: END */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
private long mNativeContext; // accessed by native methods
@@ -202,6 +208,17 @@
private boolean mShutterSoundEnabledFromApp = true;
private static final int NO_ERROR = 0;
+ private static final int EACCESS = -13;
+ private static final int ENODEV = -19;
+ private static final int EBUSY = -16;
+ private static final int EINVAL = -22;
+ private static final int ENOSYS = -38;
+ private static final int EUSERS = -87;
+ private static final int EOPNOTSUPP = -95;
+ /* ### QC ADD-ONS: START */
+ private CameraDataCallback mCameraDataCallback;
+ private CameraMetaDataCallback mCameraMetaDataCallback;
+ /* ### QC ADD-ONS: END */
/**
* Broadcast Action: A new picture is taken by the camera, and the entry of
@@ -283,7 +300,37 @@
* @return total number of accessible camera devices, or 0 if there are no
* cameras or an error was encountered enumerating them.
*/
- public native static int getNumberOfCameras();
+ public static int getNumberOfCameras() {
+ boolean exposeAuxCamera = true;
+ String packageName = ActivityThread.currentOpPackageName();
+ /* Force to expose only two cameras
+ * if the package name does not falls in this bucket
+ */
+ String packageList = SystemProperties.get("vendor.camera.aux.packagelist", "");
+ String packageBlacklist = SystemProperties.get("vendor.camera.aux.packageblacklist", "");
+ if (!packageList.isEmpty()) {
+ exposeAuxCamera = false;
+ if (Arrays.asList(packageList.split(",")).contains(packageName)) {
+ exposeAuxCamera = true;
+ }
+ } else if (!packageBlacklist.isEmpty()) {
+ exposeAuxCamera = true;
+ if (Arrays.asList(packageBlacklist.split(",")).contains(packageName)) {
+ exposeAuxCamera = false;
+ }
+ }
+ int numberOfCameras = _getNumberOfCameras();
+ if (exposeAuxCamera == false && (numberOfCameras > 2)) {
+ numberOfCameras = 2;
+ }
+ return numberOfCameras;
+ }
+
+ /**
+ * Returns the number of physical cameras available on this device.
+ */
+ /** @hide */
+ public native static int _getNumberOfCameras();
/**
* Returns the information about a particular camera.
@@ -294,6 +341,9 @@
* low-level failure).
*/
public static void getCameraInfo(int cameraId, CameraInfo cameraInfo) {
+ if(cameraId >= getNumberOfCameras()){
+ throw new RuntimeException("Unknown camera ID");
+ }
_getCameraInfo(cameraId, cameraInfo);
IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
IAudioService audioService = IAudioService.Stub.asInterface(b);
@@ -327,6 +377,17 @@
*/
public static final int CAMERA_FACING_FRONT = 1;
+ /* ### QC ADD-ONS: START TBD*/
+ /** @hide
+ * camera is in ZSL mode.
+ */
+ public static final int CAMERA_SUPPORT_MODE_ZSL = 2;
+
+ /** @hide
+ * camera is in non-ZSL mode.
+ */
+ public static final int CAMERA_SUPPORT_MODE_NONZSL = 3;
+ /* ### QC ADD-ONS: END */
/**
* The direction that the camera faces. It should be
* CAMERA_FACING_BACK or CAMERA_FACING_FRONT.
@@ -513,6 +574,10 @@
mPostviewCallback = null;
mUsingPreviewAllocation = false;
mZoomListener = null;
+ /* ### QC ADD-ONS: START */
+ mCameraDataCallback = null;
+ mCameraMetaDataCallback = null;
+ /* ### QC ADD-ONS: END */
Looper looper;
if ((looper = Looper.myLooper()) != null) {
@@ -523,8 +588,17 @@
mEventHandler = null;
}
- return native_setup(new WeakReference<Camera>(this), cameraId, halVersion,
- ActivityThread.currentOpPackageName());
+ String packageName = ActivityThread.currentOpPackageName();
+
+ // Force HAL1 if the package name is in our 'blacklist'
+ String packageList = SystemProperties.get("vendor.camera.hal1.packagelist", "");
+ if (!packageList.isEmpty()) {
+ if (Arrays.asList(packageList.split(",")).contains(packageName)) {
+ halVersion = CAMERA_HAL_API_VERSION_1_0;
+ }
+ }
+
+ return native_setup(new WeakReference<Camera>(this), cameraId, halVersion, packageName);
}
private int cameraInitNormal(int cameraId) {
@@ -551,6 +625,9 @@
/** used by Camera#open, Camera#open(int) */
Camera(int cameraId) {
+ if(cameraId >= getNumberOfCameras()){
+ throw new RuntimeException("Unknown camera ID");
+ }
int err = cameraInitNormal(cameraId);
if (checkInitErrors(err)) {
if (err == -EACCES) {
@@ -1275,7 +1352,23 @@
mAutoFocusMoveCallback.onAutoFocusMoving(msg.arg1 == 0 ? false : true, mCamera);
}
return;
+ /* ### QC ADD-ONS: START */
+ case CAMERA_MSG_STATS_DATA:
+ int statsdata[] = new int[257];
+ for(int i =0; i<257; i++ ) {
+ statsdata[i] = byteToInt( (byte[])msg.obj, i*4);
+ }
+ if (mCameraDataCallback != null) {
+ mCameraDataCallback.onCameraData(statsdata, mCamera);
+ }
+ return;
+ case CAMERA_MSG_META_DATA:
+ if (mCameraMetaDataCallback != null) {
+ mCameraMetaDataCallback.onCameraMetaData((byte[])msg.obj, mCamera);
+ }
+ return;
+ /* ### QC ADD-ONS: END */
default:
Log.e(TAG, "Unknown message type " + msg.what);
return;
@@ -2140,6 +2233,27 @@
return p;
}
+ /** @hide
+ * Returns the current cct value of white balance.
+ *
+ * If it's in AWB mode, cct is determined by stats/awb module.
+ *
+ * If it's in Manual WB mode, it actually returns cct value
+ * set by user via {@link #setParameters(Camera.Parameters)}.
+ */
+ public int getWBCurrentCCT() {
+ Parameters p = new Parameters();
+ String s = native_getParameters();
+ p.unflatten(s);
+
+ int cct = 0;
+ if (p.getWBCurrentCCT() != null) {
+ cct = Integer.parseInt(p.getWBCurrentCCT());
+ }
+
+ return cct;
+ }
+
/**
* Returns an empty {@link Parameters} for testing purpose.
*
@@ -2153,6 +2267,157 @@
return camera.new Parameters();
}
+ /* ### QC ADD-ONS: START */
+ private static int byteToInt(byte[] b, int offset) {
+ int value = 0;
+ for (int i = 0; i < 4; i++) {
+ int shift = (4 - 1 - i) * 8;
+ value += (b[(3-i) + offset] & 0x000000FF) << shift;
+ }
+ return value;
+ }
+ /** @hide
+ * Handles the callback for when Camera Data is available.
+ * data is read from the camera.
+ */
+ public interface CameraDataCallback {
+ /**
+ * Callback for when camera data is available.
+ *
+ * @param data a int array of the camera data
+ * @param camera the Camera service object
+ */
+ void onCameraData(int[] data, Camera camera);
+ };
+
+ /** @hide
+ * Set camera histogram mode and registers a callback function to run.
+ * Only valid after startPreview() has been called.
+ *
+ * @param cb the callback to run
+ */
+ public final void setHistogramMode(CameraDataCallback cb)
+ {
+ mCameraDataCallback = cb;
+ native_setHistogramMode(cb!=null);
+ }
+ private native final void native_setHistogramMode(boolean mode);
+
+ /** @hide
+ * Set camera histogram command to send data.
+ *
+ */
+ public final void sendHistogramData()
+ {
+ native_sendHistogramData();
+ }
+ private native final void native_sendHistogramData();
+
+ /** @hide
+ * Handles the callback for when Camera Meta Data is available.
+ * Meta data is read from the camera.
+ */
+ public interface CameraMetaDataCallback {
+ /**
+ * Callback for when camera meta data is available.
+ *
+ * @param data a byte array of the camera meta data
+ * @param camera the Camera service object
+ */
+ void onCameraMetaData(byte[] data, Camera camera);
+ };
+
+ /** @hide
+ * Set camera meta data and registers a callback function to run.
+ * Only valid after startPreview() has been called.
+ *
+ * @param cb the callback to run
+ */
+ public final void setMetadataCb(CameraMetaDataCallback cb)
+ {
+ mCameraMetaDataCallback = cb;
+ native_setMetadataCb(cb!=null);
+ }
+ private native final void native_setMetadataCb(boolean mode);
+
+ /** @hide
+ * Set camera face detection command to send meta data.
+ */
+ public final void sendMetaData()
+ {
+ native_sendMetaData();
+ }
+ private native final void native_sendMetaData();
+
+ /** @hide
+ * Configure longshot mode. Available only in ZSL.
+ *
+ * @param enable enable/disable this mode
+ */
+ public final void setLongshot(boolean enable)
+ {
+ native_setLongshot(enable);
+ }
+ private native final void native_setLongshot(boolean enable);
+
+ /** @hide
+ * Handles the Touch Co-ordinate.
+ */
+ public class Coordinate {
+ /**
+ * Sets the x,y co-ordinates for a touch event
+ *
+ * @param x the x co-ordinate (pixels)
+ * @param y the y co-ordinate (pixels)
+ */
+ public Coordinate(int x, int y) {
+ xCoordinate = x;
+ yCoordinate = y;
+ }
+ /**
+ * Compares {@code obj} to this co-ordinate.
+ *
+ * @param obj the object to compare this co-ordinate with.
+ * @return {@code true} if the xCoordinate and yCoordinate of {@code obj} is the
+ * same as those of this coordinate. {@code false} otherwise.
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof Coordinate)) {
+ return false;
+ }
+ Coordinate c = (Coordinate) obj;
+ return xCoordinate == c.xCoordinate && yCoordinate == c.yCoordinate;
+ }
+
+ /** x co-ordinate for the touch event*/
+ public int xCoordinate;
+
+ /** y co-ordinate for the touch event */
+ public int yCoordinate;
+ };
+
+ /** @hide
+ * Returns the current focus position.
+ *
+ * If it's in AF mode, it's the lens position after af is done.
+ *
+ * If it's in Manual Focus mode, it actually returns the value
+ * set by user via {@link #setParameters(Camera.Parameters)}.
+ */
+ public int getCurrentFocusPosition() {
+ Parameters p = new Parameters();
+ String s = native_getParameters();
+ p.unflatten(s);
+
+ int focus_pos = -1;
+ if (p.getCurrentFocusPosition() != null) {
+ focus_pos = Integer.parseInt(p.getCurrentFocusPosition());
+ }
+ return focus_pos;
+ }
+
+ /* ### QC ADD-ONS: END */
/**
* Returns a copied {@link Parameters}; for shim use only.
*
@@ -2414,6 +2679,10 @@
public static final String WHITE_BALANCE_CLOUDY_DAYLIGHT = "cloudy-daylight";
public static final String WHITE_BALANCE_TWILIGHT = "twilight";
public static final String WHITE_BALANCE_SHADE = "shade";
+ /** @hide
+ * wb manual cct mode.
+ */
+ public static final String WHITE_BALANCE_MANUAL_CCT = "manual-cct";
// Values for color effect settings.
public static final String EFFECT_NONE = "none";
@@ -2461,6 +2730,11 @@
*/
public static final String FLASH_MODE_TORCH = "torch";
+ /** @hide
+ * Scene mode is off.
+ */
+ public static final String SCENE_MODE_ASD = "asd";
+
/**
* Scene mode is off.
*/
@@ -2537,6 +2811,14 @@
* Capture the naturally warm color of scenes lit by candles.
*/
public static final String SCENE_MODE_CANDLELIGHT = "candlelight";
+ /** @hide
+ * SCENE_MODE_BACKLIGHT
+ **/
+ public static final String SCENE_MODE_BACKLIGHT = "backlight";
+ /** @hide
+ * SCENE_MODE_FLOWERS
+ **/
+ public static final String SCENE_MODE_FLOWERS = "flowers";
/**
* Applications are looking for a barcode. Camera driver will be
@@ -2579,6 +2861,13 @@
*/
public static final String FOCUS_MODE_FIXED = "fixed";
+ /** @hide
+ * Normal focus mode. Applications should call
+ * {@link #autoFocus(AutoFocusCallback)} to start the focus in this
+ * mode.
+ */
+ public static final String FOCUS_MODE_NORMAL = "normal";
+
/**
* Extended depth of field (EDOF). Focusing is done digitally and
* continuously. Applications should not call {@link
@@ -2631,6 +2920,11 @@
*/
public static final String FOCUS_MODE_CONTINUOUS_PICTURE = "continuous-picture";
+ /** @hide
+ * manual focus mode
+ */
+ public static final String FOCUS_MODE_MANUAL_POSITION = "manual";
+
// Indices for focus distance array.
/**
* The array index of near focus distance for use with
@@ -2667,11 +2961,15 @@
// Formats for setPreviewFormat and setPictureFormat.
private static final String PIXEL_FORMAT_YUV422SP = "yuv422sp";
private static final String PIXEL_FORMAT_YUV420SP = "yuv420sp";
+ private static final String PIXEL_FORMAT_YUV420SP_ADRENO = "yuv420sp-adreno";
private static final String PIXEL_FORMAT_YUV422I = "yuv422i-yuyv";
private static final String PIXEL_FORMAT_YUV420P = "yuv420p";
private static final String PIXEL_FORMAT_RGB565 = "rgb565";
private static final String PIXEL_FORMAT_JPEG = "jpeg";
private static final String PIXEL_FORMAT_BAYER_RGGB = "bayer-rggb";
+ private static final String PIXEL_FORMAT_RAW = "raw";
+ private static final String PIXEL_FORMAT_YV12 = "yv12";
+ private static final String PIXEL_FORMAT_NV12 = "nv12";
/**
* Order matters: Keys that are {@link #set(String, String) set} later
@@ -3491,8 +3789,11 @@
* parameters.
*/
public void removeGpsData() {
+ remove(KEY_QC_GPS_LATITUDE_REF);
remove(KEY_GPS_LATITUDE);
+ remove(KEY_QC_GPS_LONGITUDE_REF);
remove(KEY_GPS_LONGITUDE);
+ remove(KEY_QC_GPS_ALTITUDE_REF);
remove(KEY_GPS_ALTITUDE);
remove(KEY_GPS_TIMESTAMP);
remove(KEY_GPS_PROCESSING_METHOD);
@@ -4383,6 +4684,7 @@
splitter.setString(str);
int index = 0;
for (String s : splitter) {
+ s = s.replaceAll("\\s","");
output[index++] = Integer.parseInt(s);
}
}
@@ -4516,5 +4818,1231 @@
if (s1 != null && s1.equals(s2)) return true;
return false;
}
+ /* ### QC ADD-ONS: START */
+
+ /* ### QC ADDED PARAMETER KEYS*/
+ private static final String KEY_QC_HFR_SIZE = "hfr-size";
+ private static final String KEY_QC_PREVIEW_FRAME_RATE_MODE = "preview-frame-rate-mode";
+ private static final String KEY_QC_PREVIEW_FRAME_RATE_AUTO_MODE = "frame-rate-auto";
+ private static final String KEY_QC_PREVIEW_FRAME_RATE_FIXED_MODE = "frame-rate-fixed";
+ private static final String KEY_QC_GPS_LATITUDE_REF = "gps-latitude-ref";
+ private static final String KEY_QC_GPS_LONGITUDE_REF = "gps-longitude-ref";
+ private static final String KEY_QC_GPS_ALTITUDE_REF = "gps-altitude-ref";
+ private static final String KEY_QC_GPS_STATUS = "gps-status";
+ private static final String KEY_QC_EXIF_DATETIME = "exif-datetime";
+ private static final String KEY_QC_TOUCH_AF_AEC = "touch-af-aec";
+ private static final String KEY_QC_TOUCH_INDEX_AEC = "touch-index-aec";
+ private static final String KEY_QC_TOUCH_INDEX_AF = "touch-index-af";
+ private static final String KEY_QC_MANUAL_FOCUS_POSITION = "manual-focus-position";
+ private static final String KEY_QC_MANUAL_FOCUS_POS_TYPE = "manual-focus-pos-type";
+ private static final String KEY_QC_SCENE_DETECT = "scene-detect";
+ private static final String KEY_QC_ISO_MODE = "iso";
+ private static final String KEY_QC_EXPOSURE_TIME = "exposure-time";
+ private static final String KEY_QC_MIN_EXPOSURE_TIME = "min-exposure-time";
+ private static final String KEY_QC_MAX_EXPOSURE_TIME = "max-exposure-time";
+ private static final String KEY_QC_LENSSHADE = "lensshade";
+ private static final String KEY_QC_HISTOGRAM = "histogram";
+ private static final String KEY_QC_SKIN_TONE_ENHANCEMENT = "skinToneEnhancement";
+ private static final String KEY_QC_AUTO_EXPOSURE = "auto-exposure";
+ private static final String KEY_QC_SHARPNESS = "sharpness";
+ private static final String KEY_QC_MAX_SHARPNESS = "max-sharpness";
+ private static final String KEY_QC_CONTRAST = "contrast";
+ private static final String KEY_QC_MAX_CONTRAST = "max-contrast";
+ private static final String KEY_QC_SATURATION = "saturation";
+ private static final String KEY_QC_MAX_SATURATION = "max-saturation";
+ private static final String KEY_QC_DENOISE = "denoise";
+ private static final String KEY_QC_CONTINUOUS_AF = "continuous-af";
+ private static final String KEY_QC_SELECTABLE_ZONE_AF = "selectable-zone-af";
+ private static final String KEY_QC_FACE_DETECTION = "face-detection";
+ private static final String KEY_QC_MEMORY_COLOR_ENHANCEMENT = "mce";
+ private static final String KEY_QC_REDEYE_REDUCTION = "redeye-reduction";
+ private static final String KEY_QC_ZSL = "zsl";
+ private static final String KEY_QC_CAMERA_MODE = "camera-mode";
+ private static final String KEY_QC_VIDEO_HIGH_FRAME_RATE = "video-hfr";
+ private static final String KEY_QC_VIDEO_HDR = "video-hdr";
+ private static final String KEY_QC_POWER_MODE = "power-mode";
+ private static final String KEY_QC_POWER_MODE_SUPPORTED = "power-mode-supported";
+ private static final String KEY_QC_WB_MANUAL_CCT = "wb-manual-cct";
+ private static final String KEY_QC_MIN_WB_CCT = "min-wb-cct";
+ private static final String KEY_QC_MAX_WB_CCT = "max-wb-cct";
+ private static final String KEY_QC_AUTO_HDR_ENABLE = "auto-hdr-enable";
+ private static final String KEY_QC_VIDEO_ROTATION = "video-rotation";
+
+ /** @hide
+ * KEY_QC_AE_BRACKET_HDR
+ **/
+ public static final String KEY_QC_AE_BRACKET_HDR = "ae-bracket-hdr";
+
+ /* ### QC ADDED PARAMETER VALUES*/
+
+ // Values for touch af/aec settings.
+ /** @hide
+ * TOUCH_AF_AEC_OFF
+ **/
+ public static final String TOUCH_AF_AEC_OFF = "touch-off";
+ /** @hide
+ * TOUCH_AF_AEC_ON
+ **/
+ public static final String TOUCH_AF_AEC_ON = "touch-on";
+
+ // Values for auto exposure settings.
+ /** @hide
+ * Auto exposure frame-avg
+ **/
+ public static final String AUTO_EXPOSURE_FRAME_AVG = "frame-average";
+ /** @hide
+ * Auto exposure center weighted
+ **/
+ public static final String AUTO_EXPOSURE_CENTER_WEIGHTED = "center-weighted";
+ /** @hide
+ * Auto exposure spot metering
+ **/
+ public static final String AUTO_EXPOSURE_SPOT_METERING = "spot-metering";
+
+ //Values for ISO settings
+ /** @hide
+ * ISO_AUTO
+ **/
+ public static final String ISO_AUTO = "auto";
+ /** @hide
+ * ISO_HJR
+ **/
+ public static final String ISO_HJR = "ISO_HJR";
+ /** @hide
+ * ISO_100
+ **/
+ public static final String ISO_100 = "ISO100";
+ /** @hide
+ * ISO_200
+ **/
+ public static final String ISO_200 = "ISO200";
+ /** @hide
+ * ISO_400
+ **/
+ public static final String ISO_400 = "ISO400";
+ /** @hide
+ * ISO_800
+ **/
+ public static final String ISO_800 = "ISO800";
+ /** @hide
+ * ISO_1600
+ **/
+ public static final String ISO_1600 = "ISO1600";
+
+ /** @hide
+ * ISO_3200
+ **/
+ public static final String ISO_3200 = "ISO3200";
+
+ //Values for Lens Shading
+ /** @hide
+ * LENSSHADE_ENABLE
+ **/
+ public static final String LENSSHADE_ENABLE = "enable";
+ /** @hide
+ * LENSSHADE_DISABLE
+ **/
+ public static final String LENSSHADE_DISABLE= "disable";
+
+ //Values for Histogram
+ /** @hide
+ * Histogram enable
+ **/
+ public static final String HISTOGRAM_ENABLE = "enable";
+ /** @hide
+ * Histogram disable
+ **/
+ public static final String HISTOGRAM_DISABLE= "disable";
+
+ //Values for Skin Tone Enhancement
+ /** @hide
+ * SKIN_TONE_ENHANCEMENT_ENABLE
+ **/
+ public static final String SKIN_TONE_ENHANCEMENT_ENABLE = "enable";
+ /** @hide
+ * SKIN_TONE_ENHANCEMENT_DISABLE
+ **/
+ public static final String SKIN_TONE_ENHANCEMENT_DISABLE= "disable";
+
+ // Values for MCE settings.
+ /** @hide
+ * MCE_ENaBLE
+ **/
+ public static final String MCE_ENABLE = "enable";
+ /** @hide
+ * MCE_DISABLE
+ **/
+ public static final String MCE_DISABLE = "disable";
+
+ // Values for ZSL settings.
+ /** @hide
+ * ZSL_ON
+ **/
+ public static final String ZSL_ON = "on";
+ /** @hide
+ * ZSL_OFF
+ **/
+ public static final String ZSL_OFF = "off";
+
+ // Values for HDR Bracketing settings.
+
+ /** @hide
+ * AEC bracketing off
+ **/
+ public static final String AE_BRACKET_HDR_OFF = "Off";
+ /** @hide
+ * AEC bracketing hdr
+ **/
+ public static final String AE_BRACKET_HDR = "HDR";
+ /** @hide
+ * AEC bracketing aec-bracket
+ **/
+ public static final String AE_BRACKET = "AE-Bracket";
+
+ // Values for Power mode.
+ /** @hide
+ * LOW_POWER
+ **/
+ public static final String LOW_POWER = "Low_Power";
+ /** @hide
+ * NORMAL_POWER
+ **/
+ public static final String NORMAL_POWER = "Normal_Power";
+
+ // Values for HFR settings.
+ /** @hide
+ * VIDEO_HFR_OFF
+ **/
+ public static final String VIDEO_HFR_OFF = "off";
+ /** @hide
+ * VIDEO_HFR_2X
+ **/
+ public static final String VIDEO_HFR_2X = "60";
+ /** @hide
+ * VIDEO_HFR_3X
+ **/
+ public static final String VIDEO_HFR_3X = "90";
+ /** @hide
+ * VIDEO_HFR_4X
+ **/
+ public static final String VIDEO_HFR_4X = "120";
+
+ // Values for auto scene detection settings.
+ /** @hide
+ * SCENE_DETECT_OFF
+ **/
+ public static final String SCENE_DETECT_OFF = "off";
+ /** @hide
+ * SCENE_DETECT_ON
+ **/
+ public static final String SCENE_DETECT_ON = "on";
+
+ //Values for Continuous AF
+
+ /** @hide
+ * CAF off
+ **/
+ public static final String CONTINUOUS_AF_OFF = "caf-off";
+ /** @hide
+ * CAF on
+ **/
+ public static final String CONTINUOUS_AF_ON = "caf-on";
+ /** @hide
+ * Denoise off
+ **/
+ public static final String DENOISE_OFF = "denoise-off";
+ /** @hide
+ * Denoise on
+ **/
+ public static final String DENOISE_ON = "denoise-on";
+
+ // Values for Redeye Reduction settings.
+ /** @hide
+ * REDEYE_REDUCTION_ENABLE
+ **/
+ public static final String REDEYE_REDUCTION_ENABLE = "enable";
+ /** @hide
+ * REDEYE_REDUCTION_DISABLE
+ **/
+ public static final String REDEYE_REDUCTION_DISABLE = "disable";
+
+ // Values for selectable zone af settings.
+ /** @hide
+ * SELECTABLE_ZONE_AF_AUTO
+ **/
+ public static final String SELECTABLE_ZONE_AF_AUTO = "auto";
+ /** @hide
+ * SELECTABLE_ZONE_AF_SPOTMETERING
+ **/
+ public static final String SELECTABLE_ZONE_AF_SPOTMETERING = "spot-metering";
+ /** @hide
+ * SELECTABLE_ZONE_AF_CENTER_WEIGHTED
+ **/
+ public static final String SELECTABLE_ZONE_AF_CENTER_WEIGHTED = "center-weighted";
+ /** @hide
+ * SELECTABLE_ZONE_AF_FRAME_AVERAGE
+ **/
+ public static final String SELECTABLE_ZONE_AF_FRAME_AVERAGE = "frame-average";
+
+ // Values for Face Detection settings.
+ /** @hide
+ * Face Detection off
+ **/
+ public static final String FACE_DETECTION_OFF = "off";
+ /** @hide
+ * Face Detction on
+ **/
+ public static final String FACE_DETECTION_ON = "on";
+
+ // Values for video rotation settings.
+
+ /** @hide
+ * VIDEO_ROTATION_0
+ **/
+ public static final String VIDEO_ROTATION_0 = "0";
+ /** @hide
+ * VIDEO_ROTATION_90
+ **/
+ public static final String VIDEO_ROTATION_90 = "90";
+ /** @hide
+ * VIDEO_ROTATION_180
+ **/
+ public static final String VIDEO_ROTATION_180 = "180";
+ /** @hide
+ * VIDEO_ROTATION_270
+ **/
+ public static final String VIDEO_ROTATION_270 = "270";
+
+ /* ### QC ADDED PARAMETER APIS*/
+ /** @hide
+ * Gets the supported preview sizes in high frame rate recording mode.
+ *
+ * @return a list of Size object. This method will always return a list
+ * with at least one element.
+ */
+ public List<Size> getSupportedHfrSizes() {
+ String str = get(KEY_QC_HFR_SIZE + SUPPORTED_VALUES_SUFFIX);
+ return splitSize(str);
+ }
+
+ /** @hide
+ * Gets the supported Touch AF/AEC setting.
+ *
+ * @return a List of TOUCH_AF_AEC_XXX string constants. null if TOUCH AF/AEC
+ * setting is not supported.
+ *
+ */
+ public List<String> getSupportedTouchAfAec() {
+ String str = get(KEY_QC_TOUCH_AF_AEC + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /**
+ * Gets the supported Touch AF/AEC setting.
+ *
+ * @return a List of TOUCH_AF_AEC_XXX string constants. null if TOUCH AF/AEC
+ * setting is not supported.
+ *
+ */
+
+ /** @hide
+ * Gets the supported frame rate modes.
+ *
+ * @return a List of FRAME_RATE_XXX_MODE string constant. null if this
+ * setting is not supported.
+ */
+ public List<String> getSupportedPreviewFrameRateModes() {
+ String str = get(KEY_QC_PREVIEW_FRAME_RATE_MODE + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /** @hide
+ * Gets the supported auto scene detection modes.
+ *
+ * @return a List of SCENE_DETECT_XXX string constant. null if scene detection
+ * setting is not supported.
+ *
+ */
+ public List<String> getSupportedSceneDetectModes() {
+ String str = get(KEY_QC_SCENE_DETECT + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /** @hide
+ * Gets the supported ISO values.
+ *
+ * @return a List of FLASH_MODE_XXX string constants. null if flash mode
+ * setting is not supported.
+ */
+ public List<String> getSupportedIsoValues() {
+ String str = get(KEY_QC_ISO_MODE + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /** @hide
+ * Gets the supported Lensshade modes.
+ *
+ * @return a List of LENS_MODE_XXX string constants. null if lens mode
+ * setting is not supported.
+ */
+ public List<String> getSupportedLensShadeModes() {
+ String str = get(KEY_QC_LENSSHADE + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /** @hide
+ * Gets the supported Histogram modes.
+ *
+ * @return a List of HISTOGRAM_XXX string constants. null if histogram mode
+ * setting is not supported.
+ */
+ public List<String> getSupportedHistogramModes() {
+ String str = get(KEY_QC_HISTOGRAM + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /** @hide
+ * Gets the supported Skin Tone Enhancement modes.
+ *
+ * @return a List of SKIN_TONE_ENHANCEMENT_XXX string constants. null if skin tone enhancement
+ * setting is not supported.
+ */
+ public List<String> getSupportedSkinToneEnhancementModes() {
+ String str = get(KEY_QC_SKIN_TONE_ENHANCEMENT + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /** @hide
+ * Gets the supported auto exposure setting.
+ *
+ * @return a List of AUTO_EXPOSURE_XXX string constants. null if auto exposure
+ * setting is not supported.
+ */
+ public List<String> getSupportedAutoexposure() {
+ String str = get(KEY_QC_AUTO_EXPOSURE + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /** @hide
+ * Gets the supported MCE modes.
+ *
+ * @return a List of MCE_ENABLE/DISABLE string constants. null if MCE mode
+ * setting is not supported.
+ */
+ public List<String> getSupportedMemColorEnhanceModes() {
+ String str = get(KEY_QC_MEMORY_COLOR_ENHANCEMENT + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /** @hide
+ * Gets the supported ZSL modes.
+ *
+ * @return a List of ZSL_OFF/OFF string constants. null if ZSL mode
+ * setting is not supported.
+ */
+ public List<String> getSupportedZSLModes() {
+ String str = get(KEY_QC_ZSL + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /** @hide
+ * Gets the supported Video HDR modes.
+ *
+ * @return a List of Video HDR_OFF/OFF string constants. null if
+ * Video HDR mode setting is not supported.
+ */
+ public List<String> getSupportedVideoHDRModes() {
+ String str = get(KEY_QC_VIDEO_HDR + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /** @hide
+ * Gets the supported HFR modes.
+ *
+ * @return a List of VIDEO_HFR_XXX string constants. null if hfr mode
+ * setting is not supported.
+ */
+ public List<String> getSupportedVideoHighFrameRateModes() {
+ String str = get(KEY_QC_VIDEO_HIGH_FRAME_RATE + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /** @hide
+ * Gets the supported Continuous AF modes.
+ *
+ * @return a List of CONTINUOUS_AF_XXX string constant. null if continuous AF
+ * setting is not supported.
+ *
+ */
+ public List<String> getSupportedContinuousAfModes() {
+ String str = get(KEY_QC_CONTINUOUS_AF + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /** @hide
+ * Gets the supported DENOISE modes.
+ *
+ * @return a List of DENOISE_XXX string constant. null if DENOISE
+ * setting is not supported.
+ *
+ */
+ public List<String> getSupportedDenoiseModes() {
+ String str = get(KEY_QC_DENOISE + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /** @hide
+ * Gets the supported selectable zone af setting.
+ *
+ * @return a List of SELECTABLE_ZONE_AF_XXX string constants. null if selectable zone af
+ * setting is not supported.
+ */
+ public List<String> getSupportedSelectableZoneAf() {
+ String str = get(KEY_QC_SELECTABLE_ZONE_AF + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /** @hide
+ * Gets the supported face detection modes.
+ *
+ * @return a List of FACE_DETECTION_XXX string constant. null if face detection
+ * setting is not supported.
+ *
+ */
+ public List<String> getSupportedFaceDetectionModes() {
+ String str = get(KEY_QC_FACE_DETECTION + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /** @hide
+ * Gets the supported redeye reduction modes.
+ *
+ * @return a List of REDEYE_REDUCTION_XXX string constant. null if redeye reduction
+ * setting is not supported.
+ *
+ */
+ public List<String> getSupportedRedeyeReductionModes() {
+ String str = get(KEY_QC_REDEYE_REDUCTION + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ /** @hide
+ * Sets GPS altitude reference. This will be stored in JPEG EXIF header.
+ * @param altRef reference GPS altitude in meters.
+ */
+ public void setGpsAltitudeRef(double altRef) {
+ set(KEY_QC_GPS_ALTITUDE_REF, Double.toString(altRef));
+ }
+
+ /** @hide
+ * Sets GPS Status. This will be stored in JPEG EXIF header.
+ *
+ * @param status GPS status (UTC in seconds since January 1,
+ * 1970).
+ */
+ public void setGpsStatus(double status) {
+ set(KEY_QC_GPS_STATUS, Double.toString(status));
+ }
+
+ /** @hide
+ * Sets the touch co-ordinate for Touch AEC.
+ *
+ * @param x the x co-ordinate of the touch event
+ * @param y the y co-ordinate of the touch event
+ *
+ */
+ public void setTouchIndexAec(int x, int y) {
+ String v = Integer.toString(x) + "x" + Integer.toString(y);
+ set(KEY_QC_TOUCH_INDEX_AEC, v);
+ }
+
+ /** @hide
+ * Returns the touch co-ordinates of the touch event.
+ *
+ * @return a Index object with the x and y co-ordinated
+ * for the touch event
+ *
+ */
+ public Coordinate getTouchIndexAec() {
+ String pair = get(KEY_QC_TOUCH_INDEX_AEC);
+ return strToCoordinate(pair);
+ }
+
+ /** @hide
+ * Sets the touch co-ordinate for Touch AF.
+ *
+ * @param x the x co-ordinate of the touch event
+ * @param y the y co-ordinate of the touch event
+ *
+ */
+ public void setTouchIndexAf(int x, int y) {
+ String v = Integer.toString(x) + "x" + Integer.toString(y);
+ set(KEY_QC_TOUCH_INDEX_AF, v);
+ }
+
+ /** @hide
+ * Returns the touch co-ordinates of the touch event.
+ *
+ * @return a Index object with the x and y co-ordinated
+ * for the touch event
+ *
+ */
+ public Coordinate getTouchIndexAf() {
+ String pair = get(KEY_QC_TOUCH_INDEX_AF);
+ return strToCoordinate(pair);
+ }
+ /** @hide
+ * Set Sharpness Level
+ *
+ * @param sharpness level
+ */
+ public void setSharpness(int sharpness){
+ if((sharpness < 0) || (sharpness > getMaxSharpness()) )
+ throw new IllegalArgumentException(
+ "Invalid Sharpness " + sharpness);
+
+ set(KEY_QC_SHARPNESS, String.valueOf(sharpness));
+ }
+
+ /** @hide
+ * Set Contrast Level
+ *
+ * @param contrast level
+ */
+ public void setContrast(int contrast){
+ if((contrast < 0 ) || (contrast > getMaxContrast()))
+ throw new IllegalArgumentException(
+ "Invalid Contrast " + contrast);
+
+ set(KEY_QC_CONTRAST, String.valueOf(contrast));
+ }
+
+ /** @hide
+ * Set Saturation Level
+ *
+ * @param saturation level
+ */
+ public void setSaturation(int saturation){
+ if((saturation < 0 ) || (saturation > getMaxSaturation()))
+ throw new IllegalArgumentException(
+ "Invalid Saturation " + saturation);
+
+ set(KEY_QC_SATURATION, String.valueOf(saturation));
+ }
+
+ /** @hide
+ * @return true if full size video snapshot is supported.
+ */
+ public boolean isPowerModeSupported() {
+ String str = get(KEY_QC_POWER_MODE_SUPPORTED);
+ return TRUE.equals(str);
+ }
+
+ /** @hide
+ * Get Sharpness level
+ *
+ * @return sharpness level
+ */
+ public int getSharpness(){
+ return getInt(KEY_QC_SHARPNESS);
+ }
+
+ /** @hide
+ * Get Max Sharpness Level
+ *
+ * @return max sharpness level
+ */
+ public int getMaxSharpness(){
+ return getInt(KEY_QC_MAX_SHARPNESS);
+ }
+
+ /** @hide
+ * Get Contrast level
+ *
+ * @return contrast level
+ */
+ public int getContrast(){
+ return getInt(KEY_QC_CONTRAST);
+ }
+
+ /** @hide
+ * Get Max Contrast Level
+ *
+ * @return max contrast level
+ */
+ public int getMaxContrast(){
+ return getInt(KEY_QC_MAX_CONTRAST);
+ }
+
+ /** @hide
+ * Get Saturation level
+ *
+ * @return saturation level
+ */
+ public int getSaturation(){
+ return getInt(KEY_QC_SATURATION);
+ }
+
+ /** @hide
+ * Get Max Saturation Level
+ *
+ * @return max contrast level
+ */
+ public int getMaxSaturation(){
+ return getInt(KEY_QC_MAX_SATURATION);
+ }
+
+ /** @hide
+ * Sets GPS latitude reference coordinate. This will be stored in JPEG EXIF
+ * header.
+ * @param latRef GPS latitude reference coordinate.
+ */
+ public void setGpsLatitudeRef(String latRef) {
+ set(KEY_QC_GPS_LATITUDE_REF, latRef);
+ }
+
+ /** @hide
+ * Sets GPS longitude reference coordinate. This will be stored in JPEG EXIF
+ * header.
+ * @param lonRef GPS longitude reference coordinate.
+ */
+ public void setGpsLongitudeRef(String lonRef) {
+ set(KEY_QC_GPS_LONGITUDE_REF, lonRef);
+ }
+
+ /** @hide
+ * Sets system timestamp. This will be stored in JPEG EXIF header.
+ *
+ * @param dateTime current timestamp (UTC in seconds since January 1,
+ * 1970).
+ */
+ public void setExifDateTime(String dateTime) {
+ set(KEY_QC_EXIF_DATETIME, dateTime);
+ }
+
+ /** @hide
+ * Gets the current Touch AF/AEC setting.
+ *
+ * @return one of TOUCH_AF_AEC_XXX string constant. null if Touch AF/AEC
+ * setting is not supported.
+ *
+ */
+ public String getTouchAfAec() {
+ return get(KEY_QC_TOUCH_AF_AEC);
+ }
+
+ /** @hide
+ * Sets the current TOUCH AF/AEC setting.
+ *
+ * @param value TOUCH_AF_AEC_XXX string constants.
+ *
+ */
+ public void setTouchAfAec(String value) {
+ set(KEY_QC_TOUCH_AF_AEC, value);
+ }
+
+ /** @hide
+ * Gets the current redeye reduction setting.
+ *
+ * @return one of REDEYE_REDUCTION_XXX string constant. null if redeye reduction
+ * setting is not supported.
+ *
+ */
+ public String getRedeyeReductionMode() {
+ return get(KEY_QC_REDEYE_REDUCTION);
+ }
+
+ /** @hide
+ * Sets the redeye reduction. Other parameters may be changed after changing
+ * redeye reduction. After setting redeye reduction,
+ * applications should call getParameters to know if some parameters are
+ * changed.
+ *
+ * @param value REDEYE_REDUCTION_XXX string constants.
+ *
+ */
+ public void setRedeyeReductionMode(String value) {
+ set(KEY_QC_REDEYE_REDUCTION, value);
+ }
+
+ /** @hide
+ * Gets the frame rate mode setting.
+ *
+ * @return one of FRAME_RATE_XXX_MODE string constant. null if this
+ * setting is not supported.
+ */
+ public String getPreviewFrameRateMode() {
+ return get(KEY_QC_PREVIEW_FRAME_RATE_MODE);
+ }
+
+ /** @hide
+ * Sets the frame rate mode.
+ *
+ * @param value FRAME_RATE_XXX_MODE string constants.
+ */
+ public void setPreviewFrameRateMode(String value) {
+ set(KEY_QC_PREVIEW_FRAME_RATE_MODE, value);
+ }
+
+ /** @hide
+ * Gets the current auto scene detection setting.
+ *
+ * @return one of SCENE_DETECT_XXX string constant. null if auto scene detection
+ * setting is not supported.
+ *
+ */
+ public String getSceneDetectMode() {
+ return get(KEY_QC_SCENE_DETECT);
+ }
+
+ /** @hide
+ * Sets the auto scene detect. Other parameters may be changed after changing
+ * scene detect. After setting auto scene detection,
+ * applications should call getParameters to know if some parameters are
+ * changed.
+ *
+ * @param value SCENE_DETECT_XXX string constants.
+ *
+ */
+ public void setSceneDetectMode(String value) {
+ set(KEY_QC_SCENE_DETECT, value);
+ }
+
+ /** @hide
+ * Gets the current hdr bracketing mode setting.
+ *
+ * @return current hdr bracketing mode.
+ * @see #KEY_AE_BRACKET_OFF
+ * @see #KEY_AE_BRACKET_HDR
+ * @see #KEY_AE_BRACKET_BRACKATING
+ */
+ public String getAEBracket() {
+ return get(KEY_QC_AE_BRACKET_HDR);
+ }
+
+ /** @hide
+ * Sets the Power mode.
+ *
+ * @param value Power mode.
+ * @see #getPowerMode()
+ */
+ public void setPowerMode(String value) {
+ set(KEY_QC_POWER_MODE, value);
+ }
+
+ /** @hide
+ * Gets the current power mode setting.
+ *
+ * @return current power mode. null if power mode setting is not
+ * supported.
+ * @see #POWER_MODE_LOW
+ * @see #POWER_MODE_NORMAL
+ */
+ public String getPowerMode() {
+ return get(KEY_QC_POWER_MODE);
+ }
+
+ /** @hide
+ * Set HDR-Bracketing Level
+ *
+ * @param value HDR-Bracketing
+ */
+ public void setAEBracket(String value){
+ set(KEY_QC_AE_BRACKET_HDR, value);
+ }
+
+ /** @hide
+ * Gets the current ISO setting.
+ *
+ * @return one of ISO_XXX string constant. null if ISO
+ * setting is not supported.
+ */
+ public String getISOValue() {
+ return get(KEY_QC_ISO_MODE);
+ }
+
+ /** @hide
+ * Sets the ISO.
+ *
+ * @param iso ISO_XXX string constant.
+ */
+ public void setISOValue(String iso) {
+ set(KEY_QC_ISO_MODE, iso);
+ }
+
+ /** @hide
+ * Sets the exposure time.
+ *
+ * @param value exposure time.
+ */
+ public void setExposureTime(int value) {
+ set(KEY_QC_EXPOSURE_TIME, Integer.toString(value));
+ }
+
+ /** @hide
+ * Gets the current exposure time.
+ *
+ * @return exposure time.
+ */
+ public String getExposureTime() {
+ return get(KEY_QC_EXPOSURE_TIME);
+ }
+
+ /** @hide
+ * Gets the min supported exposure time.
+ *
+ * @return min supported exposure time.
+ */
+ public String getMinExposureTime() {
+ return get(KEY_QC_MIN_EXPOSURE_TIME);
+ }
+
+ /** @hide
+ * Gets the max supported exposure time.
+ *
+ * @return max supported exposure time.
+ */
+ public String getMaxExposureTime() {
+ return get(KEY_QC_MAX_EXPOSURE_TIME);
+ }
+
+ /** @hide
+ * Gets the current LensShade Mode.
+ *
+ * @return LensShade Mode
+ */
+ public String getLensShade() {
+ return get(KEY_QC_LENSSHADE);
+ }
+
+ /** @hide
+ * Sets the current LensShade Mode.
+ *
+ * @return LensShade Mode
+ */
+ public void setLensShade(String lensshade) {
+ set(KEY_QC_LENSSHADE, lensshade);
+ }
+
+ /** @hide
+ * Gets the current auto exposure setting.
+ *
+ * @return one of AUTO_EXPOSURE_XXX string constant. null if auto exposure
+ * setting is not supported.
+ */
+ public String getAutoExposure() {
+ return get(KEY_QC_AUTO_EXPOSURE);
+ }
+
+ /** @hide
+ * Sets the current auto exposure setting.
+ *
+ * @param value AUTO_EXPOSURE_XXX string constants.
+ */
+ public void setAutoExposure(String value) {
+ set(KEY_QC_AUTO_EXPOSURE, value);
+ }
+
+ /** @hide
+ * Gets the current MCE Mode.
+ *
+ * @return MCE value
+ */
+ public String getMemColorEnhance() {
+ return get(KEY_QC_MEMORY_COLOR_ENHANCEMENT);
+ }
+
+ /** @hide
+ * Sets the current MCE Mode.
+ *
+ * @return MCE Mode
+ */
+ public void setMemColorEnhance(String mce) {
+ set(KEY_QC_MEMORY_COLOR_ENHANCEMENT, mce);
+ }
+
+ /** @hide
+ * Set white balance manual cct value.
+ *
+ * @param cct user CCT setting.
+ */
+ public void setWBManualCCT(int cct) {
+ set(KEY_QC_WB_MANUAL_CCT, Integer.toString(cct));
+ }
+
+ /** @hide
+ * Gets the WB min supported CCT.
+ *
+ * @return min cct value.
+ */
+ public String getWBMinCCT() {
+ return get(KEY_QC_MIN_WB_CCT);
+ }
+
+ /** @hide
+ * Gets the WB max supported CCT.
+ *
+ * @return max cct value.
+ */
+ public String getMaxWBCCT() {
+ return get(KEY_QC_MAX_WB_CCT);
+ }
+
+ /** @hide
+ * Gets the current WB CCT.
+ *
+ * @return CCT value
+ */
+ public String getWBCurrentCCT() {
+ return get(KEY_QC_WB_MANUAL_CCT);
+ }
+
+ /** @hide
+ * Gets the current ZSL Mode.
+ *
+ * @return ZSL mode value
+ */
+ public String getZSLMode() {
+ return get(KEY_QC_ZSL);
+ }
+
+ /** @hide
+ * Sets the current ZSL Mode. ZSL mode is set as a 0th bit in KEY_CAMERA_MODE.
+ *
+ * @return null
+ */
+ public void setZSLMode(String zsl) {
+ set(KEY_QC_ZSL, zsl);
+ }
+
+ /** @hide
+ * Sets the current Auto HDR Mode.
+ * @ auto_hdr auto hdr string for enable/disable
+ * @return null
+ */
+ public void setAutoHDRMode(String auto_hdr){
+ set(KEY_QC_AUTO_HDR_ENABLE,auto_hdr);
+ }
+
+ /** @hide
+ * Gets the current Camera Mode Flag. Camera mode includes a
+ * flag(byte) which indicates different camera modes.
+ * For now support for ZSL added at bit0
+ *
+ * @return Camera Mode.
+ */
+ public String getCameraMode() {
+ return get(KEY_QC_CAMERA_MODE);
+ }
+
+ /** @hide
+ * Sets the current Camera Mode.
+ *
+ * @return null
+ */
+ public void setCameraMode(int cameraMode) {
+ set(KEY_QC_CAMERA_MODE, cameraMode);
+ }
+
+ private static final int MANUAL_FOCUS_POS_TYPE_INDEX = 0;
+ private static final int MANUAL_FOCUS_POS_TYPE_DAC = 1;
+ /** @hide
+ * Set focus position.
+ *
+ * @param pos user setting of focus position.
+ */
+ public void setFocusPosition(int type, int pos) {
+ set(KEY_QC_MANUAL_FOCUS_POS_TYPE, Integer.toString(type));
+ set(KEY_QC_MANUAL_FOCUS_POSITION, Integer.toString(pos));
+ }
+
+ /** @hide
+ * Gets the current focus position.
+ *
+ * @return current focus position
+ */
+ public String getCurrentFocusPosition() {
+ return get(KEY_QC_MANUAL_FOCUS_POSITION);
+ }
+
+
+ /** @hide
+ * Gets the current HFR Mode.
+ *
+ * @return VIDEO_HFR_XXX string constants
+ */
+ public String getVideoHighFrameRate() {
+ return get(KEY_QC_VIDEO_HIGH_FRAME_RATE);
+ }
+
+ /** @hide
+ * Sets the current HFR Mode.
+ *
+ * @param hfr VIDEO_HFR_XXX string constants
+ */
+ public void setVideoHighFrameRate(String hfr) {
+ set(KEY_QC_VIDEO_HIGH_FRAME_RATE, hfr);
+ }
+
+ /** @hide
+ * Gets the current Video HDR Mode.
+ *
+ * @return Video HDR mode value
+ */
+ public String getVideoHDRMode() {
+ return get(KEY_QC_VIDEO_HDR);
+ }
+
+ /** @hide
+ * Sets the current Video HDR Mode.
+ *
+ * @return null
+ */
+ public void setVideoHDRMode(String videohdr) {
+ set(KEY_QC_VIDEO_HDR, videohdr);
+ }
+
+ /** @hide
+ * Gets the current DENOISE setting.
+ *
+ * @return one of DENOISE_XXX string constant. null if Denoise
+ * setting is not supported.
+ *
+ */
+ public String getDenoise() {
+ return get(KEY_QC_DENOISE);
+ }
+
+ /** @hide
+ * Gets the current Continuous AF setting.
+ *
+ * @return one of CONTINUOUS_AF_XXX string constant. null if continuous AF
+ * setting is not supported.
+ *
+ */
+ public String getContinuousAf() {
+ return get(KEY_QC_CONTINUOUS_AF);
+ }
+
+ /** @hide
+ * Sets the current Denoise mode.
+ * @param value DENOISE_XXX string constants.
+ *
+ */
+
+ public void setDenoise(String value) {
+ set(KEY_QC_DENOISE, value);
+ }
+
+ /** @hide
+ * Sets the current Continuous AF mode.
+ * @param value CONTINUOUS_AF_XXX string constants.
+ *
+ */
+ public void setContinuousAf(String value) {
+ set(KEY_QC_CONTINUOUS_AF, value);
+ }
+
+ /** @hide
+ * Gets the current selectable zone af setting.
+ *
+ * @return one of SELECTABLE_ZONE_AF_XXX string constant. null if selectable zone af
+ * setting is not supported.
+ */
+ public String getSelectableZoneAf() {
+ return get(KEY_QC_SELECTABLE_ZONE_AF);
+ }
+
+ /** @hide
+ * Sets the current selectable zone af setting.
+ *
+ * @param value SELECTABLE_ZONE_AF_XXX string constants.
+ */
+ public void setSelectableZoneAf(String value) {
+ set(KEY_QC_SELECTABLE_ZONE_AF, value);
+ }
+
+ /** @hide
+ * Gets the current face detection setting.
+ *
+ * @return one of FACE_DETECTION_XXX string constant. null if face detection
+ * setting is not supported.
+ *
+ */
+ public String getFaceDetectionMode() {
+ return get(KEY_QC_FACE_DETECTION);
+ }
+
+ /** @hide
+ * Sets the auto scene detect. Other settings like Touch AF/AEC might be
+ * changed after setting face detection.
+ *
+ * @param value FACE_DETECTION_XXX string constants.
+ *
+ */
+ public void setFaceDetectionMode(String value) {
+ set(KEY_QC_FACE_DETECTION, value);
+ }
+
+ /** @hide
+ * Gets the current video rotation setting.
+ *
+ * @return one of VIDEO_QC_ROTATION_XXX string constant. null if video rotation
+ * setting is not supported.
+ */
+ public String getVideoRotation() {
+ return get(KEY_QC_VIDEO_ROTATION);
+ }
+
+ /** @hide
+ * Sets the current video rotation setting.
+ *
+ * @param value VIDEO_QC_ROTATION_XXX string constants.
+ */
+ public void setVideoRotation(String value) {
+ set(KEY_QC_VIDEO_ROTATION, value);
+ }
+ /** @hide
+ * Gets the supported video rotation modes.
+ *
+ * @return a List of VIDEO_QC_ROTATION_XXX string constant. null if this
+ * setting is not supported.
+ */
+ public List<String> getSupportedVideoRotationValues() {
+ String str = get(KEY_QC_VIDEO_ROTATION + SUPPORTED_VALUES_SUFFIX);
+ return split(str);
+ }
+
+ // Splits a comma delimited string to an ArrayList of Coordinate.
+ // Return null if the passing string is null or the Coordinate is 0.
+ private ArrayList<Coordinate> splitCoordinate(String str) {
+ if (str == null) return null;
+ TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(',');
+ splitter.setString(str);
+ ArrayList<Coordinate> coordinateList = new ArrayList<Coordinate>();
+ for (String s : splitter) {
+ Coordinate coordinate = strToCoordinate(s);
+ if (coordinate != null) coordinateList.add(coordinate);
+ }
+ if (coordinateList.size() == 0) return null;
+ return coordinateList;
+ }
+
+ // Parses a string (ex: "500x500") to Coordinate object.
+ // Return null if the passing string is null.
+ private Coordinate strToCoordinate(String str) {
+ if (str == null) return null;
+
+ int pos = str.indexOf('x');
+ if (pos != -1) {
+ String x = str.substring(0, pos);
+ String y = str.substring(pos + 1);
+ return new Coordinate(Integer.parseInt(x),
+ Integer.parseInt(y));
+ }
+ Log.e(TAG, "Invalid Coordinate parameter string=" + str);
+ return null;
+ }
+ /* ### QC ADD-ONS: END */
};
}
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index 7f834af..006d980 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -22,6 +22,7 @@
import android.annotation.RequiresPermission;
import android.annotation.SystemService;
import android.annotation.TestApi;
+import android.app.ActivityThread;
import android.content.Context;
import android.hardware.CameraInfo;
import android.hardware.CameraStatus;
@@ -43,6 +44,8 @@
import android.os.ServiceManager;
import android.os.ServiceSpecificException;
import android.os.SystemProperties;
+import android.text.TextUtils;
+import android.util.Log;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
@@ -1236,8 +1239,26 @@
private String[] extractCameraIdListLocked() {
String[] cameraIds = null;
+
+ boolean exposeAuxCamera = true;
+ String packageName = ActivityThread.currentOpPackageName();
+ String packageList = SystemProperties.get("vendor.camera.aux.packagelist", "");
+ String packageBlacklist = SystemProperties.get("vendor.camera.aux.packageblacklist", "");
+ if (!packageList.isEmpty()) {
+ exposeAuxCamera = false;
+ if (Arrays.asList(packageList.split(",")).contains(packageName)) {
+ exposeAuxCamera = true;
+ }
+ } else if (!packageBlacklist.isEmpty()) {
+ exposeAuxCamera = true;
+ if (Arrays.asList(packageBlacklist.split(",")).contains(packageName)) {
+ exposeAuxCamera = false;
+ }
+ }
+
int idCount = 0;
for (int i = 0; i < mDeviceStatus.size(); i++) {
+ if(!exposeAuxCamera && (i == 2)) break;
int status = mDeviceStatus.valueAt(i);
if (status == ICameraServiceListener.STATUS_NOT_PRESENT
|| status == ICameraServiceListener.STATUS_ENUMERATING) continue;
@@ -1246,6 +1267,7 @@
cameraIds = new String[idCount];
idCount = 0;
for (int i = 0; i < mDeviceStatus.size(); i++) {
+ if(!exposeAuxCamera && (i == 2)) break;
int status = mDeviceStatus.valueAt(i);
if (status == ICameraServiceListener.STATUS_NOT_PRESENT
|| status == ICameraServiceListener.STATUS_ENUMERATING) continue;
@@ -1697,6 +1719,32 @@
}
private void onStatusChangedLocked(int status, String id) {
+ /* Force to ignore the last mono/aux camera status update
+ * if the package name does not falls in this bucket
+ */
+ boolean exposeMonoCamera = true;
+ String packageName = ActivityThread.currentOpPackageName();
+ String packageList = SystemProperties.get("vendor.camera.aux.packagelist", "");
+ String packageBlacklist = SystemProperties.get("vendor.camera.aux.packageblacklist", "");
+ if (!packageList.isEmpty()) {
+ exposeMonoCamera = false;
+ if (Arrays.asList(packageList.split(",")).contains(packageName)) {
+ exposeMonoCamera = true;
+ }
+ } else if (!packageBlacklist.isEmpty()) {
+ exposeMonoCamera = true;
+ if (Arrays.asList(packageBlacklist.split(",")).contains(packageName)) {
+ exposeMonoCamera = false;
+ }
+ }
+
+ if (exposeMonoCamera == false) {
+ if (Integer.parseInt(id) >= 2) {
+ Log.w(TAG, "[soar.cts] ignore the status update of camera: " + id);
+ return;
+ }
+ }
+
if (DEBUG) {
Log.v(TAG,
String.format("Camera id %s has status changed to 0x%x", id, status));
diff --git a/core/java/android/hardware/display/AmbientDisplayConfiguration.java b/core/java/android/hardware/display/AmbientDisplayConfiguration.java
index ece5c28..fd1a0ff 100644
--- a/core/java/android/hardware/display/AmbientDisplayConfiguration.java
+++ b/core/java/android/hardware/display/AmbientDisplayConfiguration.java
@@ -35,12 +35,18 @@
private final Context mContext;
private final boolean mAlwaysOnByDefault;
+ private final boolean mDeviceHasSoli;
+ private final boolean mDeviceWithWeirdDtSensor;
+ private final boolean mDeviceHasElmyra;
/** {@hide} */
@TestApi
public AmbientDisplayConfiguration(Context context) {
mContext = context;
mAlwaysOnByDefault = mContext.getResources().getBoolean(R.bool.config_dozeAlwaysOnEnabled);
+ mDeviceHasSoli = mContext.getResources().getBoolean(R.bool.config_has_Soli);
+ mDeviceWithWeirdDtSensor = mContext.getResources().getBoolean(R.bool.config_has_weird_dt_sensor);
+ mDeviceHasElmyra = mContext.getResources().getBoolean(R.bool.config_has_elmyra);
}
/** {@hide} */
@@ -52,7 +58,10 @@
|| wakeDisplayGestureEnabled(user)
|| pickupGestureEnabled(user)
|| tapGestureEnabled(user)
- || doubleTapGestureEnabled(user);
+ || doubleTapGestureEnabled(user)
+ || isPowerBtnFlashlightEnabled(user)
+ || isAmbientTickerEnabled(user)
+ || deviceHasElmyra();
}
/** {@hide} */
@@ -218,4 +227,37 @@
private boolean boolSetting(String name, int user, int def) {
return Settings.Secure.getIntForUser(mContext.getContentResolver(), name, def, user) != 0;
}
+
+ /** {@hide} */
+ public boolean isPowerBtnFlashlightEnabled(int user) {
+ return Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.TORCH_POWER_BUTTON_GESTURE, 0, user) != 0;
+ }
+
+ /** {@hide} */
+ public boolean isAmbientTickerEnabled(int user) {
+ return Settings.System.getIntForUser(mContext.getContentResolver(),
+ Settings.System.PULSE_ON_NEW_TRACKS, 1, user) != 0;
+ }
+
+ /** {@hide} */
+ public boolean deviceHasSoli() {
+ return mDeviceHasSoli;
+ }
+
+ /** {@hide} */
+ public boolean isAmbientGestureEnabled(int user) {
+ return !mDeviceHasSoli && Settings.System.getIntForUser(mContext.getContentResolver(),
+ Settings.System.AMBIENT_WAKE_GESTURES, 1, user) != 0;
+ }
+
+ /** {@hide} */
+ public boolean deviceHasWeirtdDtSensor() {
+ return mDeviceWithWeirdDtSensor;
+ }
+
+ /** {@hide} */
+ public boolean deviceHasElmyra() {
+ return mDeviceHasElmyra;
+ }
}
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index 6900105..38341a5 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -769,7 +769,7 @@
throw e.rethrowFromSystemServer();
}
} else {
- Slog.w(TAG, "isFingerprintHardwareDetected(): Service not connected!");
+ if (DEBUG) Slog.w(TAG, "isFingerprintHardwareDetected(): Service not connected!");
}
return false;
}
@@ -1006,13 +1006,15 @@
* @hide
*/
public static String getErrorString(Context context, int errMsg, int vendorCode) {
+ final String retry = context.getString(
+ com.android.internal.R.string.fingerprint_error_unable_to_process);
+
switch (errMsg) {
case FINGERPRINT_ERROR_HW_UNAVAILABLE:
return context.getString(
com.android.internal.R.string.fingerprint_error_hw_not_available);
case FINGERPRINT_ERROR_UNABLE_TO_PROCESS:
- return context.getString(
- com.android.internal.R.string.fingerprint_error_unable_to_process);
+ return retry;
case FINGERPRINT_ERROR_TIMEOUT:
return context.getString(com.android.internal.R.string.fingerprint_error_timeout);
case FINGERPRINT_ERROR_NO_SPACE:
@@ -1046,7 +1048,7 @@
}
}
Slog.w(TAG, "Invalid error message: " + errMsg + ", " + vendorCode);
- return null;
+ return retry;
}
/**
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 1926ea2..5eba5ea 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -470,6 +470,11 @@
*/
private IBinder mCurHideInputToken;
+ int mVolumeKeyCursorControl;
+ private static final int VOLUME_CURSOR_OFF = 0;
+ private static final int VOLUME_CURSOR_ON = 1;
+ private static final int VOLUME_CURSOR_ON_REVERSE = 2;
+
final ViewTreeObserver.OnComputeInternalInsetsListener mInsetsComputer = info -> {
onComputeInsets(mTmpInsets);
if (!mViewsCreated) {
@@ -2601,6 +2606,26 @@
}
return false;
}
+ if (event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_UP) {
+ mVolumeKeyCursorControl = Settings.System.getInt(getContentResolver(),
+ Settings.System.VOLUME_KEY_CURSOR_CONTROL, 0);
+ if (isInputViewShown() && (mVolumeKeyCursorControl != VOLUME_CURSOR_OFF)) {
+ sendDownUpKeyEvents((mVolumeKeyCursorControl == VOLUME_CURSOR_ON_REVERSE)
+ ? KeyEvent.KEYCODE_DPAD_RIGHT : KeyEvent.KEYCODE_DPAD_LEFT);
+ return true;
+ }
+ return false;
+ }
+ if (event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_DOWN) {
+ mVolumeKeyCursorControl = Settings.System.getInt(getContentResolver(),
+ Settings.System.VOLUME_KEY_CURSOR_CONTROL, 0);
+ if (isInputViewShown() && (mVolumeKeyCursorControl != VOLUME_CURSOR_OFF)) {
+ sendDownUpKeyEvents((mVolumeKeyCursorControl == VOLUME_CURSOR_ON_REVERSE)
+ ? KeyEvent.KEYCODE_DPAD_LEFT : KeyEvent.KEYCODE_DPAD_RIGHT);
+ return true;
+ }
+ return false;
+ }
return doMovementKey(keyCode, event, MOVEMENT_DOWN);
}
@@ -2651,6 +2676,15 @@
return handleBack(true);
}
}
+ if (event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_UP
+ || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
+ mVolumeKeyCursorControl = Settings.System.getInt(getContentResolver(),
+ Settings.System.VOLUME_KEY_CURSOR_CONTROL, 0);
+ if (isInputViewShown() && (mVolumeKeyCursorControl != VOLUME_CURSOR_OFF)) {
+ return true;
+ }
+ return false;
+ }
return doMovementKey(keyCode, event, MOVEMENT_UP);
}
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index 651494d..78312c9 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -81,6 +81,9 @@
*/
private final transient boolean mParcelSensitiveFields;
+ private int mTcpDelayedAckSegments = 1;
+ private int mTcpUserCfg = 0;
+
private static final int MIN_MTU = 68;
/* package-visibility - Used in other files (such as Ikev2VpnProfile) as minimum iface MTU. */
static final int MIN_MTU_V6 = 1280;
@@ -202,6 +205,8 @@
mWakeOnLanSupported = source.mWakeOnLanSupported;
mCaptivePortalApiUrl = source.mCaptivePortalApiUrl;
mCaptivePortalData = source.mCaptivePortalData;
+ mTcpDelayedAckSegments = source.mTcpDelayedAckSegments;
+ mTcpUserCfg = source.mTcpUserCfg;
}
/**
@@ -681,6 +686,45 @@
return mTcpBufferSizes;
}
+ /**
+ * Number of full MSS to receive before Acking RFC2581
+ * @param segments The number of segments to receive
+ *
+ * @hide
+ */
+ public void setTcpDelayedAckSegments(int segments) {
+ mTcpDelayedAckSegments = segments;
+ }
+
+ /**
+ * Gets the number of segments before acking
+ *
+ * @hide
+ */
+ public int getTcpDelayedAckSegments() {
+ return mTcpDelayedAckSegments;
+ }
+
+ /**
+ * Sets the value for TCP usercfg
+ *
+ * @param value 0/1 currently to disable/enable
+ *
+ * @hide
+ */
+ public void setTcpUserCfg(int value) {
+ mTcpUserCfg = value;
+ }
+
+ /**
+ * Gets the value of TCP usercfg
+ *
+ * @hide
+ */
+ public int getTcpUserCfg() {
+ return mTcpUserCfg;
+ }
+
private RouteInfo routeWithInterface(RouteInfo route) {
return new RouteInfo(
route.getDestination(),
@@ -904,6 +948,8 @@
mWakeOnLanSupported = false;
mCaptivePortalApiUrl = null;
mCaptivePortalData = null;
+ mTcpDelayedAckSegments = 1;
+ mTcpUserCfg = 0;
}
/**
diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java
index f807a49..f83ce97 100644
--- a/core/java/android/net/Network.java
+++ b/core/java/android/net/Network.java
@@ -106,6 +106,8 @@
// code search audits are possible.
private final transient boolean mPrivateDnsBypass;
+ private java.net.Proxy mProxy = null;
+
/**
* @hide
*/
@@ -327,6 +329,22 @@
}
}
+ private java.net.Proxy getProxy() throws IOException {
+ if (mProxy == null) {
+ final ConnectivityManager cm = ConnectivityManager.getInstanceOrNull();
+ if (cm == null) {
+ throw new IOException("No ConnectivityManager yet constructed, please construct one");
+ }
+ final ProxyInfo proxyInfo = cm.getProxyForNetwork(this);
+ if (proxyInfo != null) {
+ mProxy = proxyInfo.makeProxy();
+ } else {
+ mProxy = java.net.Proxy.NO_PROXY;
+ }
+ }
+ return mProxy;
+ }
+
/**
* Opens the specified {@link URL} on this {@code Network}, such that all traffic will be sent
* on this Network. The URL protocol must be {@code HTTP} or {@code HTTPS}.
@@ -337,19 +355,7 @@
* @see java.net.URL#openConnection()
*/
public URLConnection openConnection(URL url) throws IOException {
- final ConnectivityManager cm = ConnectivityManager.getInstanceOrNull();
- if (cm == null) {
- throw new IOException("No ConnectivityManager yet constructed, please construct one");
- }
- // TODO: Should this be optimized to avoid fetching the global proxy for every request?
- final ProxyInfo proxyInfo = cm.getProxyForNetwork(this);
- final java.net.Proxy proxy;
- if (proxyInfo != null) {
- proxy = proxyInfo.makeProxy();
- } else {
- proxy = java.net.Proxy.NO_PROXY;
- }
- return openConnection(url, proxy);
+ return openConnection(url, getProxy());
}
/**
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
index 0b2cfdd..c758031 100644
--- a/core/java/android/nfc/INfcAdapter.aidl
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -1,4 +1,7 @@
/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -31,6 +34,7 @@
import android.nfc.ITagRemovedCallback;
import android.nfc.INfcDta;
import android.os.Bundle;
+import android.os.IBinder;
/**
* @hide
@@ -42,6 +46,8 @@
INfcFCardEmulation getNfcFCardEmulationInterface();
INfcAdapterExtras getNfcAdapterExtrasInterface(in String pkg);
INfcDta getNfcDtaInterface(in String pkg);
+ IBinder getNfcAdapterVendorInterface(in String vendor);
+
int getState();
boolean disable(boolean saveState);
boolean enable();
diff --git a/core/java/android/nfc/cardemulation/AidGroup.java b/core/java/android/nfc/cardemulation/AidGroup.java
index 2436e57..d4c966b 100644
--- a/core/java/android/nfc/cardemulation/AidGroup.java
+++ b/core/java/android/nfc/cardemulation/AidGroup.java
@@ -1,4 +1,7 @@
/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -39,7 +42,7 @@
*
* @hide
*/
-public final class AidGroup implements Parcelable {
+public class AidGroup implements Parcelable {
/**
* The maximum number of AIDs that can be present in any one group.
*/
@@ -48,11 +51,11 @@
static final String TAG = "AidGroup";
@UnsupportedAppUsage
- final List<String> aids;
+ protected List<String> aids;
@UnsupportedAppUsage
- final String category;
+ protected String category;
@UnsupportedAppUsage
- final String description;
+ protected String description;
/**
* Creates a new AidGroup object.
diff --git a/core/java/android/nfc/cardemulation/ApduServiceInfo.java b/core/java/android/nfc/cardemulation/ApduServiceInfo.java
index d7c2e05..1cdf14f 100644
--- a/core/java/android/nfc/cardemulation/ApduServiceInfo.java
+++ b/core/java/android/nfc/cardemulation/ApduServiceInfo.java
@@ -1,4 +1,7 @@
/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
* Copyright (C) 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -48,24 +51,24 @@
/**
* @hide
*/
-public final class ApduServiceInfo implements Parcelable {
+public class ApduServiceInfo implements Parcelable {
static final String TAG = "ApduServiceInfo";
/**
* The service that implements this
*/
@UnsupportedAppUsage
- final ResolveInfo mService;
+ protected ResolveInfo mService;
/**
* Description of the service
*/
- final String mDescription;
+ protected String mDescription;
/**
* Whether this service represents AIDs running on the host CPU
*/
- final boolean mOnHost;
+ protected boolean mOnHost;
/**
* Offhost reader name.
@@ -83,33 +86,33 @@
* Mapping from category to static AID group
*/
@UnsupportedAppUsage
- final HashMap<String, AidGroup> mStaticAidGroups;
+ protected HashMap<String, AidGroup> mStaticAidGroups;
/**
* Mapping from category to dynamic AID group
*/
@UnsupportedAppUsage
- final HashMap<String, AidGroup> mDynamicAidGroups;
+ protected HashMap<String, AidGroup> mDynamicAidGroups;
/**
* Whether this service should only be started when the device is unlocked.
*/
- final boolean mRequiresDeviceUnlock;
+ protected boolean mRequiresDeviceUnlock;
/**
* The id of the service banner specified in XML.
*/
- final int mBannerResourceId;
+ protected int mBannerResourceId;
/**
* The uid of the package the service belongs to
*/
- final int mUid;
+ protected int mUid;
/**
* Settings Activity for this service
*/
- final String mSettingsActivityName;
+ protected String mSettingsActivityName;
/**
* @hide
diff --git a/core/java/android/nfc/tech/MifareClassic.java b/core/java/android/nfc/tech/MifareClassic.java
index 080e058..9cae043 100644
--- a/core/java/android/nfc/tech/MifareClassic.java
+++ b/core/java/android/nfc/tech/MifareClassic.java
@@ -1,4 +1,6 @@
/*
+ * Copyright (C) 2018 NXP Semiconductors
+ * The original Work has been changed by NXP Semiconductors.
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -173,6 +175,10 @@
mType = TYPE_CLASSIC;
mSize = SIZE_4K;
break;
+ case 0x19:
+ mType = TYPE_CLASSIC;
+ mSize = SIZE_2K;
+ break;
case 0x28:
mType = TYPE_CLASSIC;
mSize = SIZE_1K;
diff --git a/core/java/android/nfc/tech/NfcA.java b/core/java/android/nfc/tech/NfcA.java
index 88730f9..819e9e3 100644
--- a/core/java/android/nfc/tech/NfcA.java
+++ b/core/java/android/nfc/tech/NfcA.java
@@ -1,4 +1,6 @@
/*
+ * Copyright (C) 2018 NXP Semiconductors
+ * The original Work has been changed by NXP Semiconductors.
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -66,8 +68,15 @@
/** @hide */
public NfcA(Tag tag) throws RemoteException {
super(tag, TagTechnology.NFC_A);
- Bundle extras = tag.getTechExtras(TagTechnology.NFC_A);
- mSak = extras.getShort(EXTRA_SAK);
+ Bundle extras;
+ mSak = 0;
+ if(tag.hasTech(TagTechnology.MIFARE_CLASSIC))
+ {
+ extras = tag.getTechExtras(TagTechnology.MIFARE_CLASSIC);
+ mSak = extras.getShort(EXTRA_SAK);
+ }
+ extras = tag.getTechExtras(TagTechnology.NFC_A);
+ mSak |= extras.getShort(EXTRA_SAK);
mAtqa = extras.getByteArray(EXTRA_ATQA);
}
diff --git a/core/java/android/os/BaseBundle.java b/core/java/android/os/BaseBundle.java
index 81deba4..b8d5f8e 100644
--- a/core/java/android/os/BaseBundle.java
+++ b/core/java/android/os/BaseBundle.java
@@ -298,7 +298,14 @@
} else {
throw e;
}
- } finally {
+ } catch (RuntimeException e) {
+ if (sShouldDefuse && (e.getCause() instanceof ClassNotFoundException)) {
+ Log.w(TAG, "Failed to parse Bundle, but defusing quietly", e);
+ map.erase();
+ } else {
+ throw e;
+ }
+ }finally {
mMap = map;
if (recycleParcel) {
recycleParcel(parcelledData);
diff --git a/core/java/android/os/BatteryManager.java b/core/java/android/os/BatteryManager.java
index 12ec0a0..b1a178e 100644
--- a/core/java/android/os/BatteryManager.java
+++ b/core/java/android/os/BatteryManager.java
@@ -164,6 +164,27 @@
@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 detect fast charging
+ * {@hide}
+ */
+ public static final String EXTRA_DASH_CHARGER = "dash_charger";
+
+ /**
+ * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+ * boolean value to detect fast charging
+ * {@hide}
+ */
+ public static final String EXTRA_WARP_CHARGER = "warp_charger";
+
+ /**
+ * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+ * boolean value to detect fast charging
+ * {@hide}
+ */
+ public static final String EXTRA_VOOC_CHARGER = "vooc_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/Build.java b/core/java/android/os/Build.java
index 018bb2c..8c6fca5 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -63,6 +63,12 @@
public static final String BOARD = getString("ro.product.board");
/**
+ * The build date
+ * @hide
+ */
+ public static final String DATE = getString("ro.build.date");
+
+ /**
* The name of the instruction set (CPU type + ABI convention) of native code.
*
* @deprecated Use {@link #SUPPORTED_ABIS} instead.
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index 87e7043..27f1d48 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -1266,11 +1266,13 @@
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/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl
index f171441..f224969 100644
--- a/core/java/android/os/IPowerManager.aidl
+++ b/core/java/android/os/IPowerManager.aidl
@@ -99,4 +99,11 @@
// Forces the system to suspend even if there are held wakelocks.
boolean forceSuspend();
+
+ // update the uids being synchronized by network socket request manager
+ void updateBlockedUids(int uid, boolean isBlocked);
+
+ // temporarily overrides the button brightness settings to allow the user to
+ // see the effect of a settings change without applying it immediately
+ void setTemporaryButtonBrightnessSettingOverride(int brightness);
}
diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java
index c084787..7bfdc57 100644
--- a/core/java/android/os/ParcelFileDescriptor.java
+++ b/core/java/android/os/ParcelFileDescriptor.java
@@ -205,7 +205,11 @@
IoUtils.setFdOwner(mCommFd, this);
}
- mGuard.open("close");
+ try {
+ mGuard.open("close");
+ } catch(Throwable e) {
+ Log.w("ParcelFileDescriptor", "Explicit termination method 'close' not called");
+ }
}
/**
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index e3a0d18..79aab1a 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -635,6 +635,16 @@
/**
* The value to pass as the 'reason' argument to reboot() to reboot into
+ * bootloader mode if you need to get to the choppa (cit)
+ * <p>
+ * Requires {@link android.Manifest.permission#REBOOT}).
+ * </p>
+ * @hide
+ */
+ public static final String REBOOT_BOOTLOADER = "bootloader";
+
+ /**
+ * The value to pass as the 'reason' argument to reboot() to reboot into
* recovery mode for applying system updates.
* <p>
* Requires the {@link android.Manifest.permission#RECOVERY}
diff --git a/core/java/android/os/RemoteCallbackList.java b/core/java/android/os/RemoteCallbackList.java
index df4ade0..ee29366 100644
--- a/core/java/android/os/RemoteCallbackList.java
+++ b/core/java/android/os/RemoteCallbackList.java
@@ -18,6 +18,7 @@
import android.compat.annotation.UnsupportedAppUsage;
import android.util.ArrayMap;
+import android.util.Log;
import android.util.Slog;
import java.io.PrintWriter;
@@ -239,8 +240,8 @@
public int beginBroadcast() {
synchronized (mCallbacks) {
if (mBroadcastCount > 0) {
- throw new IllegalStateException(
- "beginBroadcast() called while already in a broadcast");
+ Log.e(TAG, "beginBroadcast() called while already in a broadcast");
+ return 0;
}
final int N = mBroadcastCount = mCallbacks.size();
@@ -303,8 +304,8 @@
public void finishBroadcast() {
synchronized (mCallbacks) {
if (mBroadcastCount < 0) {
- throw new IllegalStateException(
- "finishBroadcast() called outside of a broadcast");
+ Log.e(TAG, "finishBroadcast() called outside of a broadcast");
+ return;
}
Object[] active = mActiveBroadcast;
diff --git a/core/java/android/os/UpdateEngine.java b/core/java/android/os/UpdateEngine.java
index e907e22..e6c065e 100644
--- a/core/java/android/os/UpdateEngine.java
+++ b/core/java/android/os/UpdateEngine.java
@@ -425,6 +425,17 @@
}
/**
+ * @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/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java
index 39038f5..3fb26a4 100644
--- a/core/java/android/os/ZygoteProcess.java
+++ b/core/java/android/os/ZygoteProcess.java
@@ -86,7 +86,7 @@
* not be used if the devices has a DeviceConfig profile pushed to it that contains a value for
* this key.
*/
- private static final String USAP_POOL_ENABLED_DEFAULT = "false";
+ private static final String USAP_POOL_ENABLED_DEFAULT = "true";
/**
* The name of the socket used to communicate with the primary zygote.
diff --git a/core/java/android/os/storage/DiskInfo.java b/core/java/android/os/storage/DiskInfo.java
index df3c4d5..d3098e5 100644
--- a/core/java/android/os/storage/DiskInfo.java
+++ b/core/java/android/os/storage/DiskInfo.java
@@ -50,6 +50,8 @@
public static final int FLAG_DEFAULT_PRIMARY = 1 << 1;
public static final int FLAG_SD = 1 << 2;
public static final int FLAG_USB = 1 << 3;
+ public static final int FLAG_EMMC = 1 << 4;
+ public static final int FLAG_NON_REMOVABLE = 1 << 5;
public final String id;
@UnsupportedAppUsage
@@ -152,6 +154,10 @@
return (flags & FLAG_USB) != 0;
}
+ public boolean isNonRemovable() {
+ return (flags & FLAG_NON_REMOVABLE) != 0;
+ }
+
@Override
public String toString() {
final CharArrayWriter writer = new CharArrayWriter();
diff --git a/core/java/android/os/storage/StorageVolume.java b/core/java/android/os/storage/StorageVolume.java
index a63b82e..6963b77 100644
--- a/core/java/android/os/storage/StorageVolume.java
+++ b/core/java/android/os/storage/StorageVolume.java
@@ -323,17 +323,21 @@
}
/**
- * Parse and return volume UUID as FAT volume ID, or return -1 if unable to
+ * Parse and return volume UUID as volume ID, or return -1 if unable to
* parse or UUID is unknown.
* @hide
*/
- @UnsupportedAppUsage
- public int getFatVolumeId() {
- if (mFsUuid == null || mFsUuid.length() != 9) {
+ public int getVolumeId() {
+ String id = mFsUuid;
+ if (id == null) {
return -1;
}
+ id = id.replace("-", "");
+ if (id.length() > 8) {
+ id = id.substring(0, 8);
+ }
try {
- return (int) Long.parseLong(mFsUuid.replace("-", ""), 16);
+ return (int) Long.parseLong(id, 16);
} catch (NumberFormatException e) {
return -1;
}
diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java
index f508dda..b57a9a2 100644
--- a/core/java/android/preference/Preference.java
+++ b/core/java/android/preference/Preference.java
@@ -1575,6 +1575,14 @@
mDefaultValue = defaultValue;
}
+ /**
+ * Returns whether the preference can be found in persistent storage
+ * @hide
+ */
+ protected boolean isPersisted() {
+ return getSharedPreferences().contains(mKey);
+ }
+
private void dispatchSetInitialValue() {
if (getPreferenceDataStore() != null) {
onSetInitialValue(true, mDefaultValue);
@@ -1583,7 +1591,7 @@
// By now, we know if we are persistent.
final boolean shouldPersist = shouldPersist();
- if (!shouldPersist || !getSharedPreferences().contains(mKey)) {
+ if (!shouldPersist || !isPersisted()) {
if (mDefaultValue != null) {
onSetInitialValue(false, mDefaultValue);
}
diff --git a/core/java/android/provider/Downloads.java b/core/java/android/provider/Downloads.java
index 48410a7..214c71a 100644
--- a/core/java/android/provider/Downloads.java
+++ b/core/java/android/provider/Downloads.java
@@ -646,6 +646,11 @@
public static final int STATUS_QUEUED_FOR_WIFI = 196;
/**
+ * This download is paused manually.
+ */
+ public static final int STATUS_PAUSED_MANUAL = 197;
+
+ /**
* This download couldn't be completed due to insufficient storage
* space. Typically, this is because the SD card is full.
*/
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index df14720..d4f80b3 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3890,6 +3890,20 @@
"lock_pattern_tactile_feedback_enabled";
/**
+ * Whether to scramble a pin unlock layout
+ * @hide
+ */
+ public static final String LOCKSCREEN_PIN_SCRAMBLE_LAYOUT =
+ "lockscreen_scramble_pin_layout";
+
+ /**
+ * Whether to use the custom quick unlock screen control
+ * @hide
+ */
+ public static final String LOCKSCREEN_QUICK_UNLOCK_CONTROL =
+ "lockscreen_quick_unlock_control";
+
+ /**
* A formatted string of the next alarm that is set, or the empty string
* if there is no alarm set.
*
@@ -4463,6 +4477,12 @@
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
@@ -4767,7 +4787,15 @@
* 1 - Show percentage
* @hide
*/
- public static final String SHOW_BATTERY_PERCENT = "status_bar_show_battery_percent";
+ public static final String SHOW_BATTERY_PERCENT = "dummy_show_battery_percent";
+
+ /**
+ * Setting to determine whether or not to show the battery percentage in the qs status bar header.
+ * 0 - Show remaining time
+ * 1 - Show percentage
+ * @hide
+ */
+ public static final String QS_SHOW_BATTERY_PERCENT = "qs_header_show_battery_percent";
/**
* Whether or not to enable multiple audio focus.
@@ -4778,6 +4806,38 @@
public static final String MULTI_AUDIO_FOCUS_ENABLED = "multi_audio_focus_enabled";
/**
+ * media artwork wallpaper blur level on lockscreen
+ * @hide
+ */
+ public static final String LOCKSCREEN_MEDIA_BLUR = "lockscreen_media_blur";
+
+ /**
+ * @hide
+ */
+ public static final String SCREENSHOT_SHUTTER_SOUND = "screenshot_shutter_sound";
+
+ /**
+
+ /** Whether to skip music track with volume rocker
+ /**
+ * @hide
+ */
+ public static final String VOLUME_BUTTON_MUSIC_CONTROL = "volume_button_music_control";
+
+ /** Whether to pulse ambient on new music tracks
+ *
+ * @hide
+ */
+ public static final String PULSE_ON_NEW_TRACKS = "pulse_on_new_tracks";
+
+ /** Whether to show ambient or lockscreen if AoD is disabled
+ * and we do a wake gesture like lift to wake or double tap
+ *
+ * @hide
+ */
+ public static final String AMBIENT_WAKE_GESTURES = "ambient_wake_gestures";
+
+ /**
* 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
@@ -4785,6 +4845,520 @@
*/
/**
+ * Change quick settings tiles animation style
+ *
+ * @hide
+ */
+ public static final String ANIM_TILE_STYLE = "anim_tile_style";
+
+ /**
+ * Change quick settings tiles animation duration
+ *
+ * @hide
+ */
+ public static final String ANIM_TILE_DURATION = "anim_tile_duration";
+
+ /**
+ * Change quick settings tiles interpolator
+ *
+ * @hide
+ */
+ public static final String ANIM_TILE_INTERPOLATOR = "anim_tile_interpolator";
+
+ /**
+ * Enable statusbar double tap gesture on to put device to sleep
+ * @hide
+ */
+ public static final String DOUBLE_TAP_SLEEP_GESTURE = "double_tap_sleep_gesture";
+
+ /**
+ * Double tap on lockscreen to sleep
+ * @hide
+ */
+ public static final String DOUBLE_TAP_SLEEP_LOCKSCREEN =
+ "double_tap_sleep_lockscreen";
+
+ /**
+ * Three Finger Gesture from Oppo
+ * @hide
+ */
+ public static final String THREE_FINGER_GESTURE = "three_finger_gesture";
+
+ /**
+ * Volume rocker wake
+ * @hide
+ */
+ public static final String VOLUME_ROCKER_WAKE = "volume_rocker_wake";
+
+ /**
+ * Number of qs columns on landscape orientation
+ * @hide
+ */
+ public static final String QS_LAYOUT_COLUMNS_LANDSCAPE = "qs_layout_columns_landscape";
+
+ /**
+ * @hide
+ */
+ public static final String QS_LAYOUT_COLUMNS = "qs_layout_columns";
+
+ /**
+ * Whether to display qs tile titles in the qs panel
+ * @hide
+ */
+ public static final String QS_TILE_TITLE_VISIBILITY = "qs_tile_title_visibility";
+
+ /**
+ * @hide
+ */
+ public static final String QS_LAYOUT_ROWS = "qs_layout_rows";
+
+ /**
+ * Number of qs columns on quickbar
+ * @hide
+ */
+ public static final String QS_QUICKBAR_COLUMNS = "qs_quickbar_columns";
+
+ /**
+ * Home wake button
+ * @hide
+ */
+ public static final String HOME_WAKE_BUTTON = "home_wake_button";
+
+ /**
+ * Change volume up and down handlign based on rotation
+ * @hide
+ */
+ public static final String SWAP_VOLUME_BUTTONS = "swap_volume_buttons";
+
+ /**
+ * Disable power menu on secure lock screens
+ *
+ * @hide
+ */
+ public static final String LOCK_POWER_MENU_DISABLED = "lockscreen_power_menu_disabled";
+
+ /**
+ * Toast icon
+ * @hide
+ */
+ public static final String TOAST_ICON = "toast_icon";
+
+ /**
+ * Whether user is allowed to pull down quick settings on secure keyguard.
+ * @hide
+ */
+ public static final String STATUS_BAR_LOCKED_ON_SECURE_KEYGUARD =
+ "status_bar_locked_on_secure_keyguard";
+
+ /**
+ * Whether to show the battery info on the lockscreen while charging
+ * @hide
+ */
+ public static final String LOCKSCREEN_BATTERY_INFO = "lockscreen_battery_info";
+
+ /**
+ * Applications list where heasdup should't show
+ *
+ * @hide
+ */
+ public static final String HEADS_UP_STOPLIST_VALUES = "heads_up_stoplist_values";
+
+
+ /**
+ * Which applications to disable heads up notifications for
+ *
+ * @hide
+ */
+ public static final String HEADS_UP_BLACKLIST_VALUES = "heads_up_blacklist_values";
+
+ /**
+ * Whether to enable status and navigation bar color in battery saver mode.
+ * Heads up timeout configuration
+ * @hide
+ */
+ public static final String HEADS_UP_TIMEOUT = "heads_up_timeout";
+
+ /**
+ * Defines the global heads up notification snooze
+ * @hide
+ */
+ public static final String HEADS_UP_NOTIFICATION_SNOOZE = "heads_up_notification_snooze";
+
+ /**
+ * Allow users to pull down the status bar quickly
+ * @hide
+ */
+ public static final String STATUS_BAR_QUICK_QS_PULLDOWN = "status_bar_quick_qs_pulldown";
+
+ /**
+ * Show or hide clock
+ * 0 - hide
+ * 1 - show (default)
+ * @hide
+ */
+ public static final String STATUSBAR_CLOCK = "statusbar_clock";
+
+ /**
+ * Style of clock
+ * 0 - Left Clock (default)
+ * 1 - Center Clock
+ * 2 - Right Clock
+ * @hide
+ */
+ public static final String STATUSBAR_CLOCK_STYLE = "statusbar_clock_style";
+
+ /**
+ * Whether to show seconds next to clock in status bar
+ * 0 - hide (default)
+ * 1 - show
+ * @hide
+ */
+ public static final String STATUSBAR_CLOCK_SECONDS = "statusbar_clock_seconds";
+
+ /**
+ * AM/PM Style for clock options
+ * 0 - Normal AM/PM
+ * 1 - Small AM/PM
+ * 2 - No AM/PM (default)
+ * @hide
+ */
+ public static final String STATUSBAR_CLOCK_AM_PM_STYLE = "statusbar_clock_am_pm_style";
+
+ /**
+ * Shows custom date before clock time
+ * 0 - No Date
+ * 1 - Small Date
+ * 2 - Normal Date
+ * @hide
+ */
+ public static final String STATUSBAR_CLOCK_DATE_DISPLAY = "statusbar_clock_date_display";
+
+ /**
+ * Sets the date string style
+ * 0 - Regular style
+ * 1 - Lowercase
+ * 2 - Uppercase
+ * @hide
+ */
+ public static final String STATUSBAR_CLOCK_DATE_STYLE = "statusbar_clock_date_style";
+
+ /**
+ * Stores the java DateFormat string for the date
+ * @hide
+ */
+ public static final String STATUSBAR_CLOCK_DATE_FORMAT = "statusbar_clock_date_format";
+
+ /**
+ * Position of date
+ * 0 - Left of clock
+ * 1 - Right of clock
+ * @hide
+ */
+ public static final String STATUSBAR_CLOCK_DATE_POSITION = "statusbar_clock_date_position";
+
+ /**
+ * Whether to show or hide the running services icon
+ * @hide
+ */
+ public static final String QS_RUNNING_SERVICES_TOGGLE = "qs_running_services_toggle";
+
+ /**
+ * Whether to show or hide the edit icon
+ * @hide
+ */
+ public static final String QS_EDIT_TOGGLE = "qs_edit_toggle";
+
+ /**
+ * Whether to wake the display when plugging or unplugging the charger
+ *
+ * @hide
+ */
+ public static final String WAKE_WHEN_PLUGGED_OR_UNPLUGGED = "wake_when_plugged_or_unplugged";
+
+ /**
+ * Whether user can swap the order of the Alert Slider.
+ * * Whether user can invert the order of the Alert Slider.
+ * 0: Default
+ * 1: Inverted
+ * @hide
+ */
+ public static final String ALERT_SLIDER_ORDER = "alert_slider_order";
+
+ /**
+ * Preferred silent mode for Alert Slider..
+ * 0: Alarms only.
+ * 1: Total silence
+ * @hide
+ */
+ public static final String ALERT_SLIDER_SILENT_MODE = "alert_slider_silent_mode";
+
+ /**
+ * Whether to show or hide alert slider notifications on supported devices
+ * @hide
+ */
+ public static final String ALERT_SLIDER_NOTIFICATIONS = "alert_slider_notifications";
+
+ /**
+ * Whether to display our Bliss logo in the statusbar for extra swag
+ * @hide
+ */
+ public static final String STATUS_BAR_LOGO = "status_bar_logo";
+
+ /**
+ * Wheter to show network traffic indicator in statusbar
+ * @hide
+ */
+ public static final String NETWORK_TRAFFIC_STATE = "network_traffic_state";
+
+ /**
+ * Network traffic inactivity threshold (default is 1 kBs)
+ * @hide
+ */
+ public static final String NETWORK_TRAFFIC_AUTOHIDE_THRESHOLD = "network_traffic_autohide_threshold";
+
+ /**
+ * What to show in network traffic indicator in statusbar
+ * @hide
+ */
+ public static final String NETWORK_TRAFFIC_TYPE = "network_traffic_type";
+
+ /**
+ * Whether to disable showing arrows in statusbar network traffic indicators
+ * @hide
+ */
+ public static final String NETWORK_TRAFFIC_ARROW = "network_traffic_arrow";
+
+ /**
+ * What size to show for network traffic indicator in statusbar
+ * @hide
+ */
+ public static final String NETWORK_TRAFFIC_FONT_SIZE = "network_traffic_font_size";
+
+ /**
+ * Show network traffic indicator
+ * 0 - Statusbar (default)
+ * 1 - QS Header
+ * @hide
+ */
+ public static final String NETWORK_TRAFFIC_VIEW_LOCATION = "network_traffic_view_location";
+
+ /**
+ * whether to enable or disable vibration on succesful fingerprint auth
+ *
+ * @hide
+ */
+ public static final String FP_SUCCESS_VIBRATE = "fingerprint_success_vib";
+
+ /**
+ * Volume keys control cursor in text fields (default is 0)
+ * 0 - Disabled
+ * 1 - Volume up/down moves cursor left/right
+ * 2 - Volume up/down moves cursor right/left
+ * @hide
+ */
+ public static final String VOLUME_KEY_CURSOR_CONTROL = "volume_key_cursor_control";
+
+ /**
+ * Whether the phone vibrates on call connect
+ * @hide
+ */
+ public static final String VIBRATE_ON_CONNECT = "vibrate_on_connect";
+
+ /**
+ * Whether the phone vibrates on call waiting
+ * @hide
+ */
+ public static final String VIBRATE_ON_CALLWAITING = "vibrate_on_callwaiting";
+
+ /**
+ * Whether the phone vibrates on disconnect
+ * @hide
+ */
+ public static final String VIBRATE_ON_DISCONNECT = "vibrate_on_disconnect";
+
+ /**
+ * Custom button brightness value for manual mode
+ *
+ * @hide
+ */
+ public static final String CUSTOM_BUTTON_BRIGHTNESS = "custom_button_brightness";
+
+ /**
+ * use same value for buttons as for screen (manual and auto mode)
+ *
+ * @hide
+ */
+ public static final String CUSTOM_BUTTON_USE_SCREEN_BRIGHTNESS = "custom_button_use_screen_brightness";
+
+ /**
+ * disable all button brightness (manual and auto mode)
+ *
+ * @hide
+ */
+ public static final String BUTTON_BACKLIGHT_ENABLE = "button_backlight_enable";
+
+ /**
+ * Timeout value for button lights. 0 = disabled
+ * @hide
+ */
+ public static final String BUTTON_BACKLIGHT_TIMEOUT = "button_backlight_timeout";
+
+ /**
+ * @hide
+ */
+ public static final String BUTTON_BACKLIGHT_ON_TOUCH_ONLY = "button_backlight_on_touch_only";
+
+ /**
+ * Disable hw buttons - actions, brightness, haptic feedback, overflow menu
+ * @hide
+ */
+ public static final String HARDWARE_KEYS_DISABLE = "hardware_keys_disable";
+
+ /**
+ * Enable and disable Lockscreen visualizer
+ * @hide
+ */
+ public static final String LOCKSCREEN_VISUALIZER_ENABLED = "lockscreen_visualizer_enabled";
+
+ /**
+ * Lockscreen lavalamp psychedelic colors
+ * @hide
+ */
+ public static final String LOCKSCREEN_LAVALAMP_ENABLED = "lockscreen_lavalamp_enabled";
+
+ /**
+ * Lockscreen lavalamp animation speed
+ * @hide
+ */
+ public static final String LOCKSCREEN_LAVALAMP_SPEED = "lockscreen_lavalamp_speed";
+
+ /**
+ * Whether to use automatic color for visualizer
+ * @hide
+ */
+ public static final String LOCKSCREEN_VISUALIZER_AUTOCOLOR = "lockscreen_visualizer_autocolor";
+
+ /**
+ * Number of bars shown in visualizer
+ * @hide
+ */
+ public static final String LOCKSCREEN_SOLID_UNITS_COUNT = "lockscreen_solid_units_count";
+
+ /**
+ * Visualizer sanity level
+ * @hide
+ */
+ public static final String LOCKSCREEN_SOLID_FUDGE_FACTOR = "lockscreen_solid_fudge_factor";
+
+ /**
+ * Visualizer opacity
+ * @hide
+ */
+ public static final String LOCKSCREEN_SOLID_UNITS_OPACITY = "lockscreen_solid_units_opacity";
+
+ /**
+ * Battery style
+ * @hide
+ */
+ public static final String STATUS_BAR_BATTERY_STYLE = "status_bar_battery_style";
+
+ /**
+ * Statusbar Battery %
+ * 0: Hide the battery percentage
+ * 1: Display the battery percentage inside the icon
+ * 2: Display the battery percentage next to Icon
+ * @hide
+ */
+ public static final String STATUS_BAR_SHOW_BATTERY_PERCENT = "status_bar_show_battery_percent";
+
+ /**
+ * Whether to show the battery bar
+ * @hide
+ */
+ public static final String STATUSBAR_BATTERY_BAR = "statusbar_battery_bar_no_navbar_list";
+
+ /**
+ * @hide
+ */
+ public static final String STATUSBAR_BATTERY_BAR_COLOR = "statusbar_battery_bar_color";
+
+ /**
+ * @hide
+ */
+ public static final String STATUSBAR_BATTERY_BAR_THICKNESS =
+ "statusbar_battery_bar_thickness";
+
+ /**
+ * @hide
+ */
+ public static final String STATUSBAR_BATTERY_BAR_STYLE = "statusbar_battery_bar_style";
+
+ /**
+ * @hide
+ */
+ public static final String STATUSBAR_BATTERY_BAR_ANIMATE = "statusbar_battery_bar_animate";
+
+ /**
+ * @hide
+ */
+ public static final String STATUSBAR_BATTERY_BAR_CHARGING_COLOR =
+ "statusbar_battery_bar_charging_color";
+
+ /**
+ * @hide
+ */
+ public static final String STATUSBAR_BATTERY_BAR_BATTERY_LOW_COLOR =
+ "statusbar_battery_bar_battery_low_color";
+
+ /**
+ * @hide
+ */
+ public static final String STATUSBAR_BATTERY_BAR_ENABLE_CHARGING_COLOR =
+ "statusbar_battery_bar_enable_charging_color";
+
+ /**
+ * @hide
+ */
+ public static final String STATUSBAR_BATTERY_BAR_BLEND_COLORS = "statusbar_battery_bar_blend_color";
+
+ /**
+ * @hide
+ */
+ public static final String STATUSBAR_BATTERY_BAR_BLEND_COLORS_REVERSE =
+ "statusbar_battery_bar_blend_color_reverse";
+
+ /**
+ * Whether to show heads up only for dialer and sms apps
+ * @hide
+ */
+ public static final String LESS_BORING_HEADS_UP = "less_boring_heads_up";
+
+ /**
+ * Whether to show the kill app button in notification guts
+ *
+ * @hide
+ */
+ public static final String NOTIFICATION_GUTS_KILL_APP_BUTTON =
+ "notification_guts_kill_app_button";
+
+ /**
+ * Status bar carrier label
+ * 0: Hide
+ * 1: Display on keyguard status bar
+ * 2: Display on Normal status bar
+ * 3: Enabled for both
+ * @hide
+ */
+ public static final String STATUS_BAR_SHOW_CARRIER = "status_bar_show_carrier";
+
+ /**
+ * custom carrier label. The value is
+ * String.
+ * @hide
+ */
+ public static final String CUSTOM_CARRIER_LABEL = "custom_carrier_label";
+
+ /**
* Keys we no longer back up under the current schema, but want to continue to
* process when restoring historical backup datasets.
*
@@ -4903,6 +5477,21 @@
PRIVATE_SETTINGS.add(EGG_MODE);
PRIVATE_SETTINGS.add(SHOW_BATTERY_PERCENT);
PRIVATE_SETTINGS.add(DISPLAY_COLOR_MODE);
+ PRIVATE_SETTINGS.add(DOUBLE_TAP_SLEEP_GESTURE);
+ PRIVATE_SETTINGS.add(DOUBLE_TAP_SLEEP_LOCKSCREEN);
+ PRIVATE_SETTINGS.add(QS_LAYOUT_COLUMNS_LANDSCAPE);
+ PRIVATE_SETTINGS.add(QS_LAYOUT_COLUMNS);
+ PRIVATE_SETTINGS.add(QS_TILE_TITLE_VISIBILITY);
+ PRIVATE_SETTINGS.add(QS_LAYOUT_ROWS);
+ PRIVATE_SETTINGS.add(STATUSBAR_CLOCK);
+ PRIVATE_SETTINGS.add(STATUSBAR_CLOCK_STYLE);
+ PRIVATE_SETTINGS.add(STATUSBAR_CLOCK_SECONDS);
+ PRIVATE_SETTINGS.add(STATUSBAR_CLOCK_AM_PM_STYLE);
+ PRIVATE_SETTINGS.add(STATUSBAR_CLOCK_DATE_DISPLAY);
+ PRIVATE_SETTINGS.add(STATUSBAR_CLOCK_DATE_STYLE);
+ PRIVATE_SETTINGS.add(STATUSBAR_CLOCK_DATE_FORMAT);
+ PRIVATE_SETTINGS.add(STATUSBAR_CLOCK_DATE_POSITION);
+ PRIVATE_SETTINGS.add(NETWORK_TRAFFIC_VIEW_LOCATION);
}
/**
@@ -8286,6 +8875,18 @@
"camera_double_tap_power_gesture_disabled";
/**
+ * Whether the torch launch gesture to double tap or long press the power button when the
+ * screen is off should be enabled.
+ *
+ * 0: disabled
+ * 1: double tap power for torch
+ * 2: long tap power for torch
+ * @hide
+ */
+ public static final String TORCH_POWER_BUTTON_GESTURE =
+ "torch_power_button_gesture";
+
+ /**
* Whether the camera double twist gesture to flip between front and back mode should be
* enabled.
*
@@ -8535,6 +9136,12 @@
*/
public static final int VR_DISPLAY_MODE_OFF = 1;
+ /** Whether to vibrate when quick settings tile is pressed.
+ *
+ * @hide
+ */
+ public static final String QUICK_SETTINGS_TILES_VIBRATE = "quick_settings_vibrate";
+
/**
* The latest SDK version that CarrierAppUtils#disableCarrierAppsUntilPrivileged has been
* executed for.
@@ -8769,7 +9376,7 @@
/**
* What behavior should be invoked when the volume hush gesture is triggered
- * One of VOLUME_HUSH_OFF, VOLUME_HUSH_VIBRATE, VOLUME_HUSH_MUTE.
+ * One of VOLUME_HUSH_OFF, VOLUME_HUSH_VIBRATE, VOLUME_HUSH_MUTE, VOLUME_HUSH_MUTE_NO_MEDIA.
*
* @hide
*/
@@ -8785,6 +9392,9 @@
/** @hide */
@SystemApi
public static final int VOLUME_HUSH_MUTE = 2;
+ /** @hide */
+ @SystemApi
+ public static final int VOLUME_HUSH_MUTE_NO_MEDIA = 3;
/**
* The number of times (integer) the user has manually enabled battery saver.
@@ -9085,6 +9695,12 @@
public static void setLocationProviderEnabled(ContentResolver cr,
String provider, boolean enabled) {
}
+
+ /** Whether to show lockscreen media art
+ *
+ * @hide
+ */
+ public static final String LOCKSCREEN_MEDIA_METADATA = "lockscreen_media_metadata";
}
/**
@@ -13333,6 +13949,10 @@
*/
public static final String MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY =
"max_sound_trigger_detection_service_ops_per_day";
+ /**
+ * @hide
+ */
+ public static final String SHOW_CPU_OVERLAY = "show_cpu_overlay";
/** {@hide} */
public static final String ISOLATED_STORAGE_LOCAL = "isolated_storage_local";
diff --git a/core/java/android/security/net/config/PinSet.java b/core/java/android/security/net/config/PinSet.java
index d3c975e..87fcde9 100644
--- a/core/java/android/security/net/config/PinSet.java
+++ b/core/java/android/security/net/config/PinSet.java
@@ -22,6 +22,7 @@
/** @hide */
public final class PinSet {
+ private static Set<String> algorithms;
public static final PinSet EMPTY_PINSET =
new PinSet(Collections.<Pin>emptySet(), Long.MAX_VALUE);
public final long expirationTime;
@@ -36,10 +37,11 @@
}
Set<String> getPinAlgorithms() {
- // TODO: Cache this.
- Set<String> algorithms = new ArraySet<String>();
- for (Pin pin : pins) {
- algorithms.add(pin.digestAlgorithm);
+ if(algorithms == null){
+ algorithms = new ArraySet<String>();
+ for (Pin pin : pins) {
+ algorithms.add(pin.digestAlgorithm);
+ }
}
return algorithms;
}
diff --git a/core/java/android/service/dreams/DreamManagerInternal.java b/core/java/android/service/dreams/DreamManagerInternal.java
index 7bf5c38..7a1612c 100644
--- a/core/java/android/service/dreams/DreamManagerInternal.java
+++ b/core/java/android/service/dreams/DreamManagerInternal.java
@@ -59,4 +59,9 @@
* active dream component.
*/
public abstract ComponentName getActiveDreamComponent(boolean doze);
+
+ /**
+ * Called by the power manager to determine whether the dream has gone to doze mode.
+ */
+ public abstract boolean isDozing();
}
diff --git a/core/java/android/service/dreams/IDreamManager.aidl b/core/java/android/service/dreams/IDreamManager.aidl
index 6496de3..9d8dbb7 100644
--- a/core/java/android/service/dreams/IDreamManager.aidl
+++ b/core/java/android/service/dreams/IDreamManager.aidl
@@ -35,6 +35,7 @@
void testDream(int userId, in ComponentName componentName);
@UnsupportedAppUsage
boolean isDreaming();
+ boolean isDozing();
void finishSelf(in IBinder token, boolean immediate);
void startDozing(in IBinder token, int screenState, int screenBrightness);
void stopDozing(in IBinder token);
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index 0827fef..28596ed 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -405,7 +405,7 @@
}
private static int[] generateMinuteBuckets() {
- final int maxHrs = 12;
+ final int maxHrs = 24;
final int[] buckets = new int[maxHrs + 3];
buckets[0] = 15;
buckets[1] = 30;
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 00fc672..e2570dd 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -21,6 +21,7 @@
import com.android.internal.policy.IShortcutService;
import android.app.IAssistDataReceiver;
+import android.content.Intent;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.graphics.Bitmap;
@@ -762,4 +763,9 @@
*/
void requestScrollCapture(int displayId, IBinder behindClient, int taskId,
IScrollCaptureController controller);
+
+ /**
+ * Send some ActionHandler commands to WindowManager.
+ */
+ void sendCustomAction(in Intent intent);
}
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 14a324d..494570f 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -153,6 +153,18 @@
public static final String OVERDRAW_PROPERTY_SHOW = "show";
/**
+ * Defines the rendering pipeline to be used by the ThreadedRenderer.
+ *
+ * Possible values:
+ * "opengl", will use the existing OpenGL renderer
+ * "skiagl", will use Skia's OpenGL renderer
+ * "skiavk", will use Skia's Vulkan renderer
+ *
+ * @hide
+ */
+ public static final String DEBUG_RENDERER_PROPERTY = "debug.hwui.renderer";
+
+ /**
* Turn on to debug non-rectangular clip operations.
*
* Possible values:
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index 8fd2f07f..71c993f3 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -244,7 +244,7 @@
* The coefficient of friction applied to flings/scrolls.
*/
@UnsupportedAppUsage
- private static final float SCROLL_FRICTION = 0.015f;
+ private static final float SCROLL_FRICTION = 0.012f;
/**
* Max distance in dips to overscroll for edge effects
@@ -254,7 +254,7 @@
/**
* Max distance in dips to overfling for edge effects
*/
- private static final int OVERFLING_DISTANCE = 6;
+ private static final int OVERFLING_DISTANCE = 0;
/**
* Amount to scroll in response to a horizontal {@link MotionEvent#ACTION_SCROLL} event,
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 77fedd7..a1bd499 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -5232,8 +5232,7 @@
}
if (child.getParent() != null) {
- throw new IllegalStateException("The specified child already has a parent. " +
- "You must call removeView() on the child's parent first.");
+ ((ViewGroup) child.getParent()).removeView(child);
}
if (mTransition != null) {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 18e9ef0..f4d07ff 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -7695,6 +7695,14 @@
mRemoved = true;
if (mAdded) {
dispatchDetachedFromWindow();
+ } else {
+ Log.w(mTag, "add view failed and remove related objects");
+
+ mAccessibilityManager.removeAccessibilityStateChangeListener(
+ mAccessibilityInteractionConnectionManager);
+ mAccessibilityManager.removeHighTextContrastStateChangeListener(
+ mHighContrastTextManager);
+ mDisplayManager.unregisterDisplayListener(mDisplayListener);
}
if (mAdded && !mFirst) {
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 446e7aa..9e697d2 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -1166,6 +1166,11 @@
setFlags(0, flags);
}
+ /** @hide */
+ public void clearPrivateFlags(int flags) {
+ setPrivateFlags(0, flags);
+ }
+
/**
* Set the flags of the window, as per the
* {@link WindowManager.LayoutParams WindowManager.LayoutParams}
@@ -1193,6 +1198,10 @@
}
private void setPrivateFlags(int flags, int mask) {
+ if ((flags & mask & WindowManager.LayoutParams.PRIVATE_FLAG_PREVENT_POWER_KEY) != 0) {
+ mContext.enforceCallingOrSelfPermission("android.permission.PREVENT_POWER_KEY",
+ "No permission to prevent power key");
+ }
final WindowManager.LayoutParams attrs = getAttributes();
attrs.privateFlags = (attrs.privateFlags & ~mask) | (flags & mask);
dispatchWindowAttributesChanged(attrs);
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 2a711f6..84706a2 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -2039,6 +2039,12 @@
public static final int PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME = 0x40000000;
/**
+ * Window flag: Overrides default power key behavior
+ * @hide
+ */
+ public static final int PRIVATE_FLAG_PREVENT_POWER_KEY = 0x20000000;
+
+ /**
* An internal annotation for flags that can be specified to {@link #softInputMode}.
*
* @hide
diff --git a/core/java/android/webkit/WebChromeClient.java b/core/java/android/webkit/WebChromeClient.java
index 4a65511..207f8d45 100644
--- a/core/java/android/webkit/WebChromeClient.java
+++ b/core/java/android/webkit/WebChromeClient.java
@@ -59,6 +59,15 @@
boolean precomposed) {}
/**
+ * Notify the host application of a new theme color.
+ * @param view The WebView that initiated the callback.
+ * @param color The newly set theme color, which may be partially transparent.
+ * A value of Color.TRANSPARENT denotes no theme color being set.
+ * @hide
+ */
+ public void onThemeColorChanged(WebView view, int color) {}
+
+ /**
* A callback interface used by the host application to notify
* the current page that its custom view has been dismissed.
*/
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index f9a713a..d717678 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -29,6 +29,7 @@
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Canvas;
+import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Picture;
import android.graphics.Rect;
@@ -69,6 +70,8 @@
import java.io.File;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
@@ -114,6 +117,8 @@
@UnsupportedAppUsage
private static volatile boolean sEnforceThreadChecking = false;
+ private Method mGetThemeColorMethod;
+
/**
* Transportation object for returning WebView across thread boundaries.
*/
@@ -432,6 +437,13 @@
checkThread();
ensureProviderCreated();
+
+ try {
+ mGetThemeColorMethod = mProvider.getClass().getMethod("getThemeColor");
+ } catch (Exception e) {
+ // ignored, no theme color support
+ }
+
mProvider.init(javaScriptInterfaces, privateBrowsing);
// Post condition of creating a webview is the CookieSyncManager.getInstance() is allowed.
CookieSyncManager.setGetInstanceIsAllowed();
@@ -1330,6 +1342,37 @@
}
/**
+ * Checks whether the WebView implementation has support for fetching
+ * the theme color set by the page.
+ *
+ * @return true if the WebView supports the getThemeColor() method
+ * @hide
+ */
+ public boolean isThemeColorSupported() {
+ return mGetThemeColorMethod != null;
+ }
+
+ /**
+ * Gets the theme color set by the page.
+ *
+ * The returned color may not be fully opaque. If the page didn't set
+ * any theme color, Color.TRANSPARENT is returned.
+ *
+ * @return theme color set by the page
+ * @hide
+ */
+ public int getThemeColor() {
+ if (mGetThemeColorMethod != null) {
+ try {
+ return (Integer) mGetThemeColorMethod.invoke(mProvider);
+ } catch (IllegalAccessException | InvocationTargetException e) {
+ // ignored, fall back to returning transparent
+ }
+ }
+ return Color.TRANSPARENT;
+ }
+
+ /**
* Gets the height of the HTML content.
*
* @return the height of the HTML content
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 16e87f8..6ed7aee 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -659,6 +659,7 @@
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];
@@ -924,6 +925,7 @@
mVerticalScrollFactor = configuration.getScaledVerticalScrollFactor();
mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
+ mDecacheThreshold = mMaximumVelocity / 2;
mOverscrollDistance = configuration.getScaledOverscrollDistance();
mOverflingDistance = configuration.getScaledOverflingDistance();
@@ -4656,7 +4658,7 @@
// 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);
}
@@ -4672,6 +4674,11 @@
// 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);
@@ -4751,6 +4758,10 @@
// 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);
@@ -4759,7 +4770,8 @@
if (!mSuppressIdleStateChangeCall) {
reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
}
- clearScrollingCache();
+ if (clearCache)
+ clearScrollingCache();
mScroller.abortAnimation();
if (mFlingStrictSpan != null) {
diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java
index 11a6acf..78351c4 100644
--- a/core/java/android/widget/AbsSeekBar.java
+++ b/core/java/android/widget/AbsSeekBar.java
@@ -1005,7 +1005,15 @@
progress += scale * range + getMin();
setHotspot(x, y);
- setProgressInternal(Math.round(progress), true, false);
+ setProgressInternal(updateTouchProgress(getProgress(),
+ Math.round(progress)), true, false);
+ }
+
+ /**
+ * @hide
+ */
+ protected int updateTouchProgress(int lastProgress, int newProgress) {
+ return newProgress;
}
/**
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 3847d6b..6adec8a 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -89,7 +89,7 @@
private final Rect mTempRect = new Rect();
@UnsupportedAppUsage
- private OverScroller mScroller;
+ private static OverScroller mScroller;
/**
* Tracks the state of the top edge glow.
*
@@ -142,7 +142,7 @@
* Determines speed during touch scrolling
*/
@UnsupportedAppUsage
- private VelocityTracker mVelocityTracker;
+ private static VelocityTracker mVelocityTracker;
/**
* When set to true, the scroll view measure its child to make it fill the currently
@@ -221,7 +221,6 @@
attrs, a, defStyleAttr, defStyleRes);
setFillViewport(a.getBoolean(R.styleable.ScrollView_fillViewport, false));
-
a.recycle();
if (context.getResources().getConfiguration().uiMode == Configuration.UI_MODE_TYPE_WATCH) {
@@ -567,7 +566,7 @@
}
}
- private void recycleVelocityTracker() {
+ private static void recycleVelocityTracker() {
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
mVelocityTracker = null;
@@ -798,7 +797,9 @@
if (overScrollBy(0, deltaY, 0, mScrollY, 0, range, 0, mOverscrollDistance, true)
&& !hasNestedScrollingParent()) {
// Break our velocity if we hit a scroll barrier.
- mVelocityTracker.clear();
+ if (mVelocityTracker != null) {
+ mVelocityTracker.clear();
+ }
}
final int scrolledDeltaY = mScrollY - oldY;
diff --git a/core/java/android/widget/ToastPresenter.java b/core/java/android/widget/ToastPresenter.java
index fb5d55d..db2afb0 100644
--- a/core/java/android/widget/ToastPresenter.java
+++ b/core/java/android/widget/ToastPresenter.java
@@ -22,11 +22,14 @@
import android.app.INotificationManager;
import android.app.ITransientNotificationCallback;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.os.RemoteException;
+import android.provider.Settings;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
@@ -203,6 +206,21 @@
adjustLayoutParams(mParams, windowToken, duration, gravity, xOffset, yOffset,
horizontalMargin, verticalMargin);
+
+ ImageView appIcon = (ImageView) mView.findViewById(android.R.id.icon);
+ if ((Settings.System.getInt(mContext.getContentResolver(), Settings.System.TOAST_ICON, 0) == 1)) {
+ if (appIcon != null) {
+ PackageManager pm = mContext.getPackageManager();
+ Drawable icon = null;
+ try {
+ icon = pm.getApplicationIcon(mPackageName);
+ } catch (PackageManager.NameNotFoundException e) {
+ // nothing to do
+ }
+ appIcon.setImageDrawable(icon);
+ }
+ }
+
if (mView.getParent() != null) {
mWindowManager.removeView(mView);
}
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 796a557..b042909 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -239,7 +239,7 @@
// TODO(b/121287224): Re-evaluate this limit
private static final int SHARE_TARGET_QUERY_PACKAGE_LIMIT = 20;
- private static final int QUERY_TARGET_SERVICE_LIMIT = 5;
+ private static final int QUERY_TARGET_SERVICE_LIMIT = 3;
private static final int DEFAULT_SALT_EXPIRATION_DAYS = 7;
private int mMaxHashSaltDays = DeviceConfig.getInt(DeviceConfig.NAMESPACE_SYSTEMUI,
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 6a0b443..ff26b0a 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -161,4 +161,7 @@
/** {@hide} */
boolean setChargingStateUpdateDelayMillis(int delay);
+
+ /** @hide **/
+ void resetStatistics();
}
diff --git a/core/java/com/android/internal/app/LocalePicker.java b/core/java/com/android/internal/app/LocalePicker.java
index 3343593f..3ac5a3d 100644
--- a/core/java/com/android/internal/app/LocalePicker.java
+++ b/core/java/com/android/internal/app/LocalePicker.java
@@ -168,7 +168,7 @@
public static ArrayAdapter<LocaleInfo> constructAdapter(Context context,
final int layoutId, final int fieldId) {
boolean isInDeveloperMode = Settings.Global.getInt(context.getContentResolver(),
- Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
+ Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1) != 0;
final List<LocaleInfo> localeInfos = getAllAssetLocales(context, isInDeveloperMode);
final LayoutInflater inflater =
diff --git a/core/java/com/android/internal/app/LocaleStore.java b/core/java/com/android/internal/app/LocaleStore.java
index 1c5ca59..6dde295 100644
--- a/core/java/com/android/internal/app/LocaleStore.java
+++ b/core/java/com/android/internal/app/LocaleStore.java
@@ -269,7 +269,7 @@
Set<String> simCountries = getSimCountries(context);
final boolean isInDeveloperMode = Settings.Global.getInt(context.getContentResolver(),
- Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
+ Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1) != 0;
for (String localeId : LocalePicker.getSupportedLocales(context)) {
if (localeId.isEmpty()) {
throw new IllformedLocaleException("Bad locale entry in locale_config.xml");
diff --git a/core/java/com/android/internal/bliss/hardware/HIDLHelper.java b/core/java/com/android/internal/bliss/hardware/HIDLHelper.java
new file mode 100644
index 0000000..8bc43e1
--- /dev/null
+++ b/core/java/com/android/internal/bliss/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.bliss.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/bliss/hardware/LineageHardwareManager.java b/core/java/com/android/internal/bliss/hardware/LineageHardwareManager.java
new file mode 100644
index 0000000..1fade1e
--- /dev/null
+++ b/core/java/com/android/internal/bliss/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.bliss.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.bliss.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/bliss/hardware/TouchscreenGesture.aidl b/core/java/com/android/internal/bliss/hardware/TouchscreenGesture.aidl
new file mode 100644
index 0000000..4b47d24
--- /dev/null
+++ b/core/java/com/android/internal/bliss/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.bliss.hardware;
+
+parcelable TouchscreenGesture;
diff --git a/core/java/com/android/internal/bliss/hardware/TouchscreenGesture.java b/core/java/com/android/internal/bliss/hardware/TouchscreenGesture.java
new file mode 100644
index 0000000..7c79de6
--- /dev/null
+++ b/core/java/com/android/internal/bliss/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.bliss.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 41be5c4..5cb1aa5 100644
--- a/core/java/com/android/internal/notification/SystemNotificationChannels.java
+++ b/core/java/com/android/internal/notification/SystemNotificationChannels.java
@@ -103,7 +103,7 @@
DEVELOPER_IMPORTANT,
context.getString(R.string.notification_channel_developer_important),
NotificationManager.IMPORTANCE_HIGH);
- developer.setBlockable(true);
+ developerImportant.setBlockable(true);
channelsList.add(developerImportant);
final NotificationChannel updates = new NotificationChannel(
@@ -137,6 +137,7 @@
VPN,
context.getString(R.string.notification_channel_vpn),
NotificationManager.IMPORTANCE_LOW);
+ vpn.setBlockable(true);
channelsList.add(vpn);
final NotificationChannel deviceAdmin = new NotificationChannel(
@@ -161,6 +162,7 @@
USB,
context.getString(R.string.notification_channel_usb),
NotificationManager.IMPORTANCE_MIN);
+ usb.setBlockable(true);
channelsList.add(usb);
NotificationChannel foregroundChannel = new NotificationChannel(
diff --git a/core/java/com/android/internal/os/BatteryStatsHelper.java b/core/java/com/android/internal/os/BatteryStatsHelper.java
index b131ab8..6bb5091 100644
--- a/core/java/com/android/internal/os/BatteryStatsHelper.java
+++ b/core/java/com/android/internal/os/BatteryStatsHelper.java
@@ -263,6 +263,16 @@
mStats = null;
}
+ private void clearAllStats() {
+ clearStats();
+ sStatsXfer = null;
+ sBatteryBroadcastXfer = null;
+ for (File f : sFileXfer.keySet()) {
+ f.delete();
+ }
+ sFileXfer.clear();
+ }
+
@UnsupportedAppUsage
public BatteryStats getStats() {
if (mStats == null) {
@@ -905,7 +915,10 @@
}
}
- smearScreenBatterySipper(sippers, screenSipper);
+ //Only valid screen power consumption need to smear
+ if(screenSipper != null){
+ smearScreenBatterySipper(sippers, screenSipper);
+ }
return proportionalSmearPowerMah;
}
@@ -1053,6 +1066,15 @@
}
}
+ public void resetStatistics() {
+ try {
+ clearAllStats();
+ mBatteryInfo.resetStatistics();
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException:", e);
+ }
+ }
+
private static BatteryStatsImpl getStats(IBatteryStats service) {
try {
ParcelFileDescriptor pfd = service.getStatisticsStream();
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 0000000..8902337
--- /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/java/com/android/internal/os/KernelCpuUidTimeReader.java b/core/java/com/android/internal/os/KernelCpuUidTimeReader.java
index f7fad2c..51491ef 100644
--- a/core/java/com/android/internal/os/KernelCpuUidTimeReader.java
+++ b/core/java/com/android/internal/os/KernelCpuUidTimeReader.java
@@ -20,6 +20,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.os.Build;
import android.os.StrictMode;
import android.os.SystemClock;
import android.util.IntArray;
@@ -501,7 +502,11 @@
CharBuffer buf;
while ((buf = iter.nextLine()) != null) {
if (asLongs(buf, mBuffer) != mBuffer.length) {
- Slog.wtf(mTag, "Invalid line: " + buf.toString());
+ if (Build.IS_ENG) {
+ Slog.wtf(mTag, "Invalid line: " + buf.toString());
+ } else {
+ Slog.w(mTag, "Invalid line: " + buf.toString());
+ }
continue;
}
processUidDelta(cb);
diff --git a/core/java/com/android/internal/os/KernelWakelockReader.java b/core/java/com/android/internal/os/KernelWakelockReader.java
index cffb0ad..d44c332 100644
--- a/core/java/com/android/internal/os/KernelWakelockReader.java
+++ b/core/java/com/android/internal/os/KernelWakelockReader.java
@@ -102,7 +102,7 @@
is = new FileInputStream(sWakeupSourceFile);
wakeup_sources = true;
} catch (java.io.FileNotFoundException e2) {
- Slog.wtf(TAG, "neither " + sWakelockFile + " nor " +
+ Slog.w(TAG, "neither " + sWakelockFile + " nor " +
sWakeupSourceFile + " exists");
return null;
}
@@ -116,7 +116,7 @@
is.close();
} catch (java.io.IOException e) {
- Slog.wtf(TAG, "failed to read kernel wakelocks", e);
+ Slog.w(TAG, "failed to read kernel wakelocks", e);
return null;
} finally {
StrictMode.setThreadPolicyMask(oldMask);
@@ -129,7 +129,7 @@
if (len > 0) {
if (len >= mKernelWakelockBuffer.length) {
- Slog.wtf(TAG, "Kernel wake locks exceeded mKernelWakelockBuffer size "
+ Slog.w(TAG, "Kernel wake locks exceeded mKernelWakelockBuffer size "
+ mKernelWakelockBuffer.length);
}
int i;
@@ -163,7 +163,7 @@
mSuspendControlService = ISuspendControlService.Stub.asInterface(
ServiceManager.getServiceOrThrow("suspend_control"));
} catch (ServiceNotFoundException e) {
- Slog.wtf(TAG, "Required service suspend_control not available", e);
+ Slog.w(TAG, "Required service suspend_control not available", e);
return null;
}
}
@@ -172,7 +172,7 @@
wlStats = mSuspendControlService.getWakeLockStats();
updateWakelockStats(wlStats, staleStats);
} catch (RemoteException e) {
- Slog.wtf(TAG, "Failed to obtain wakelock stats from ISuspendControlService", e);
+ Slog.w(TAG, "Failed to obtain wakelock stats from ISuspendControlService", e);
return null;
}
@@ -272,10 +272,10 @@
}
} else if (!parsed) {
try {
- Slog.wtf(TAG, "Failed to parse proc line: " +
+ Slog.w(TAG, "Failed to parse proc line: " +
new String(wlBuffer, startIndex, endIndex - startIndex));
} catch (Exception e) {
- Slog.wtf(TAG, "Failed to parse proc line!");
+ Slog.w(TAG, "Failed to parse proc line!");
}
}
startIndex = endIndex + 1;
diff --git a/core/java/com/android/internal/os/PowerProfile.java b/core/java/com/android/internal/os/PowerProfile.java
index add2304..e3cfe1e 100644
--- a/core/java/com/android/internal/os/PowerProfile.java
+++ b/core/java/com/android/internal/os/PowerProfile.java
@@ -22,7 +22,8 @@
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.util.proto.ProtoOutputStream;
-
+import android.os.SystemProperties;
+import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.XmlUtils;
@@ -39,6 +40,7 @@
* [hidden]
*/
public class PowerProfile {
+ private static final String TAG = "PowerProfile";
/*
* POWER_CPU_SUSPEND: Power consumption when CPU is in power collapse mode.
@@ -259,8 +261,7 @@
}
private void readPowerValuesFromXml(Context context, boolean forTest) {
- final int id = forTest ? com.android.internal.R.xml.power_profile_test :
- com.android.internal.R.xml.power_profile;
+ int id = getPowerProfileResId(context, forTest);
final Resources resources = context.getResources();
XmlResourceParser parser = resources.getXml(id);
boolean parsingArray = false;
@@ -424,6 +425,30 @@
return 0;
}
+ private int getPowerProfileResId(final Context context, boolean forTest) {
+ if (forTest) {
+ return com.android.internal.R.xml.power_profile_test;
+ }
+
+ /*
+ * If ro.power_profile.override is set, use it to override the default.
+ * This is used for devices, which need to dynamically define the power profile.
+ */
+ String powerProfileOverride = SystemProperties.get("ro.power_profile.override");
+ if (!powerProfileOverride.isEmpty()) {
+ int id = context.getResources().getIdentifier(powerProfileOverride, "xml", "android");
+ if (id > 0) {
+ Slog.i(TAG, "getPowerProfileResId: using power profile \""
+ + powerProfileOverride + "\"");
+ return id;
+ }
+ Slog.e(TAG, "getPowerProfileResId: could not retrieve power profile \""
+ + powerProfileOverride + "\", using default instead");
+ }
+
+ return com.android.internal.R.xml.power_profile;
+ }
+
/**
* Returns the number of memory bandwidth buckets defined in power_profile.xml, or a
* default value if the subsystem has no recorded value.
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index d90a022..a8f33c3 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -89,6 +89,7 @@
import android.view.MotionEvent;
import android.view.ScrollCaptureCallback;
import android.view.SearchEvent;
+import android.view.Surface;
import android.view.SurfaceHolder.Callback2;
import android.view.View;
import android.view.ViewConfiguration;
@@ -1917,6 +1918,30 @@
// If we have a session send it the volume command, otherwise
// use the suggested stream.
if (mMediaController != null) {
+ int direction = 0;
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_VOLUME_UP:
+ direction = AudioManager.ADJUST_RAISE;
+ break;
+ case KeyEvent.KEYCODE_VOLUME_DOWN:
+ direction = AudioManager.ADJUST_LOWER;
+ break;
+ case KeyEvent.KEYCODE_VOLUME_MUTE:
+ direction = AudioManager.ADJUST_TOGGLE_MUTE;
+ break;
+ }
+ final int rotation = getWindowManager().getDefaultDisplay().getRotation();
+ final Configuration config = getContext().getResources().getConfiguration();
+ final boolean swapKeys = Settings.System.getInt(getContext().getContentResolver(),
+ Settings.System.SWAP_VOLUME_BUTTONS, 0) == 1;
+
+ if (swapKeys
+ && (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_180)
+ && config.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR) {
+ direction = keyCode == KeyEvent.KEYCODE_VOLUME_UP
+ ? AudioManager.ADJUST_LOWER
+ : AudioManager.ADJUST_RAISE;
+ }
getMediaSessionManager().dispatchVolumeKeyEventAsSystemService(
mMediaController.getSessionToken(), event);
} else {
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index 8c5fdf5..d3c44b3 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -36,6 +36,7 @@
void animateExpandSettingsPanel(String subPanel);
void animateCollapsePanels();
void togglePanel();
+ void toggleSettingsPanel();
void showWirelessChargingAnimation(int batteryLevel);
@@ -227,4 +228,17 @@
* display.
*/
void suppressAmbientDisplay(boolean suppress);
+
+ /**
+ * Toggle Camera Flash
+ */
+ void toggleCameraFlash(boolean proximityCheck);
+
+ /**
+ * Used to show or hide in display fingerprint view.
+ */
+ void showInDisplayFingerprintView();
+ void hideInDisplayFingerprintView();
+
+ void triggerElmyraAction(String action);
}
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index 4999ec0..bbf5ddc 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -39,6 +39,7 @@
@UnsupportedAppUsage
void collapsePanels();
void togglePanel();
+ void toggleSettingsPanel();
@UnsupportedAppUsage
void disable(int what, IBinder token, String pkg);
void disableForUser(int what, IBinder token, String pkg, int userId);
@@ -91,6 +92,7 @@
*/
void shutdown();
void reboot(boolean safeMode);
+ void advancedReboot(String mode);
void addTile(in ComponentName tile);
void remTile(in ComponentName tile);
@@ -147,4 +149,22 @@
* display.
*/
void suppressAmbientDisplay(boolean suppress);
+
+ /**
+ * Toggle Camera Flash
+ */
+ void toggleCameraFlash(boolean proximityCheck);
+
+ /**
+ * Used to show or hide in display fingerprint view.
+ */
+ void showInDisplayFingerprintView();
+ void hideInDisplayFingerprintView();
+
+ void triggerElmyraAction(String action);
+ void toggleRecentApps();
+ void toggleSplitScreen();
+ void preloadRecentApps();
+ void cancelPreloadRecentApps();
+ void startAssist(in Bundle args);
}
diff --git a/core/java/com/android/internal/util/DogbinException.java b/core/java/com/android/internal/util/DogbinException.java
new file mode 100644
index 0000000..719e111
--- /dev/null
+++ b/core/java/com/android/internal/util/DogbinException.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2018 Potato Open Sauce 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.util;
+
+public class DogbinException extends Exception {
+
+ private static final long serialVersionUID = 666L;
+
+ public DogbinException(String message) {
+ super(message);
+ }
+}
\ No newline at end of file
diff --git a/core/java/com/android/internal/util/DogbinUtils.java b/core/java/com/android/internal/util/DogbinUtils.java
new file mode 100644
index 0000000..49b5816
--- /dev/null
+++ b/core/java/com/android/internal/util/DogbinUtils.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2018 Potato Open Sauce 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.util;
+
+import android.util.JsonReader;
+import android.os.Handler;
+import android.os.HandlerThread;
+
+
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.URL;
+
+import javax.net.ssl.HttpsURLConnection;
+
+/**
+ * Helper functions for uploading to del.dog
+ */
+public final class DogbinUtils {
+ private static final String TAG = "DogbinUtils";
+ private static final String BASE_URL = "https://del.dog";
+ private static final String API_URL = String.format("%s/documents", BASE_URL);
+ private static Handler handler;
+
+ private DogbinUtils() {
+ }
+
+ /**
+ * Uploads {@code content} to dogbin
+ *
+ * @param content the content to upload to dogbin
+ * @param callback the callback to call on success / failure
+ */
+ public static void upload(String content, UploadResultCallback callback) {
+ getHandler().post(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ HttpsURLConnection urlConnection = (HttpsURLConnection) new URL(API_URL).openConnection();
+ try {
+ urlConnection.setRequestProperty("Accept-Charset", "UTF-8");
+ urlConnection.setDoOutput(true);
+
+ try (OutputStream output = urlConnection.getOutputStream()) {
+ output.write(content.getBytes("UTF-8"));
+ }
+ String key = "";
+ try (JsonReader reader = new JsonReader(
+ new InputStreamReader(urlConnection.getInputStream(), "UTF-8"))) {
+ reader.beginObject();
+ while (reader.hasNext()) {
+ String name = reader.nextName();
+ if (name.equals("key")) {
+ key = reader.nextString();
+ break;
+ } else {
+ reader.skipValue();
+ }
+ }
+ reader.endObject();
+ }
+ if (!key.isEmpty()) {
+ callback.onSuccess(getUrl(key));
+ } else {
+ String msg = "Failed to upload to dogbin: No key retrieved";
+ callback.onFail(msg, new DogbinException(msg));
+ }
+ } finally {
+ urlConnection.disconnect();
+ }
+ } catch (Exception e) {
+ callback.onFail("Failed to upload to dogbin", e);
+ }
+ }
+ });
+ }
+
+ /**
+ * Get the view URL from a key
+ */
+ private static String getUrl(String key) {
+ return String.format("%s/%s", BASE_URL, key);
+ }
+
+ private static Handler getHandler() {
+ if (handler == null) {
+ HandlerThread handlerThread = new HandlerThread("dogbinThread");
+ if (!handlerThread.isAlive())
+ handlerThread.start();
+ handler = new Handler(handlerThread.getLooper());
+ }
+ return handler;
+ }
+
+ public interface UploadResultCallback {
+ void onSuccess(String url);
+
+ void onFail(String message, Exception e);
+ }
+}
\ No newline at end of file
diff --git a/core/java/com/android/internal/util/bliss/BlissUtils.java b/core/java/com/android/internal/util/bliss/BlissUtils.java
new file mode 100644
index 0000000..2947165
--- /dev/null
+++ b/core/java/com/android/internal/util/bliss/BlissUtils.java
@@ -0,0 +1,431 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2014-2021 BlissRoms 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.util.bliss;
+
+import android.Manifest;
+import android.app.ActivityManager;
+import android.app.NotificationManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.om.IOverlayManager;
+import android.content.om.OverlayInfo;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.hardware.input.InputManager;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
+import android.graphics.Color;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraManager;
+import android.hardware.fingerprint.FingerprintManager;
+import android.hardware.input.InputManager;
+import android.net.NetworkInfo;
+import android.media.AudioManager;
+import android.net.ConnectivityManager;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.PowerManager;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.os.SystemClock;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.text.format.Time;
+import android.os.Vibrator;
+import android.util.DisplayMetrics;
+import android.util.TypedValue;
+import android.os.SystemProperties;
+import android.util.Log;
+import android.view.InputDevice;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
+import android.provider.MediaStore;
+import android.view.IWindowManager;
+import android.view.WindowManagerGlobal;
+import android.widget.Toast;
+
+import com.android.internal.R;
+import com.android.internal.statusbar.IStatusBarService;
+
+import static android.content.Context.NOTIFICATION_SERVICE;
+import static android.content.Context.VIBRATOR_SERVICE;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import java.util.Locale;
+
+public class BlissUtils {
+
+ public static final String INTENT_SCREENSHOT = "action_take_screenshot";
+ public static final String INTENT_REGION_SCREENSHOT = "action_take_region_screenshot";
+
+ // Check to see if device is WiFi only
+ public static boolean isWifiOnly(Context context) {
+ ConnectivityManager cm = (ConnectivityManager)context.getSystemService(
+ Context.CONNECTIVITY_SERVICE);
+ return (cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE) == false);
+ }
+
+ // Check to see if a package is installed
+ public static boolean isPackageInstalled(Context context, String pkg, boolean ignoreState) {
+ if (pkg != null) {
+ try {
+ PackageInfo pi = context.getPackageManager().getPackageInfo(pkg, 0);
+ if (!pi.applicationInfo.enabled && !ignoreState) {
+ return false;
+ }
+ } catch (NameNotFoundException e) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public static boolean isPackageInstalled(Context context, String pkg) {
+ return isPackageInstalled(context, pkg, true);
+ }
+
+ // Check to see if device supports the Fingerprint scanner
+ public static boolean hasFingerprintSupport(Context context) {
+ FingerprintManager fingerprintManager = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
+ return context.getApplicationContext().checkSelfPermission(Manifest.permission.USE_FINGERPRINT) == PackageManager.PERMISSION_GRANTED &&
+ (fingerprintManager != null && fingerprintManager.isHardwareDetected());
+ }
+
+ // Check to see if device not only supports the Fingerprint scanner but also if is enrolled
+ public static boolean hasFingerprintEnrolled(Context context) {
+ FingerprintManager fingerprintManager = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
+ return context.getApplicationContext().checkSelfPermission(Manifest.permission.USE_FINGERPRINT) == PackageManager.PERMISSION_GRANTED &&
+ (fingerprintManager != null && fingerprintManager.isHardwareDetected() && fingerprintManager.hasEnrolledFingerprints());
+ }
+
+ // Check to see if device has a camera
+ public static boolean hasCamera(Context context) {
+ return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);
+ }
+
+ // Check to see if device supports NFC
+ public static boolean hasNFC(Context context) {
+ return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC);
+ }
+
+ // Check to see if device supports Wifi
+ public static boolean hasWiFi(Context context) {
+ return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI);
+ }
+
+ // Check to see if device supports Bluetooth
+ public static boolean hasBluetooth(Context context) {
+ return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH);
+ }
+
+ // Check to see if device supports an alterative ambient display package
+ /*public static boolean hasAltAmbientDisplay(Context context) {
+ return context.getResources().getBoolean(com.android.internal.R.bool.config_alt_ambient_display);
+ }*/
+
+ // Check to see if device supports A/B (seamless) system updates
+ public static boolean isABdevice(Context context) {
+ return SystemProperties.getBoolean("ro.build.ab_update", false);
+ }
+
+ // Check for Chinese language
+ public static boolean isChineseLanguage() {
+ return Resources.getSystem().getConfiguration().locale.getLanguage().startsWith(
+ Locale.CHINESE.getLanguage());
+ }
+
+ // Screen on
+ public static void switchScreenOn(Context context) {
+ PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+ if (pm == null) return;
+ pm.wakeUp(SystemClock.uptimeMillis(), "com.android.systemui:CAMERA_GESTURE_PREVENT_LOCK");
+ }
+
+ public static boolean deviceHasFlashlight(Context ctx) {
+ return ctx.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
+ }
+
+ public static void toggleCameraFlash(boolean proximityCheck) {
+ FireActions.toggleCameraFlash(proximityCheck);
+ }
+
+ private static final class FireActions {
+ private static IStatusBarService mStatusBarService = null;
+
+ private static IStatusBarService getStatusBarService() {
+ synchronized (FireActions.class) {
+ if (mStatusBarService == null) {
+ mStatusBarService = IStatusBarService.Stub.asInterface(
+ ServiceManager.getService("statusbar"));
+ }
+ return mStatusBarService;
+ }
+ }
+
+ public static void toggleCameraFlash(boolean proximityCheck) {
+ IStatusBarService service = getStatusBarService();
+ if (service != null) {
+ try {
+ service.toggleCameraFlash(proximityCheck);
+ } catch (RemoteException e) {
+ // do nothing.
+ }
+ }
+ }
+
+ // Toggle notifications panel
+ public static void toggleNotifications() {
+ IStatusBarService service = getStatusBarService();
+ if (service != null) {
+ try {
+ service.togglePanel();
+ } catch (RemoteException e) {}
+ }
+ }
+
+ // Toggle qs panel
+ public static void toggleQsPanel() {
+ IStatusBarService service = getStatusBarService();
+ if (service != null) {
+ try {
+ service.expandSettingsPanel(null);
+ } catch (RemoteException e) {}
+ }
+ }
+
+ // Clear notifications
+ public static void clearAllNotifications() {
+ IStatusBarService service = getStatusBarService();
+ if (service != null) {
+ try {
+ service.onClearAllNotifications(ActivityManager.getCurrentUser());
+ } catch (RemoteException e) {}
+ }
+ }
+
+ // Clear notifications
+ public static void startAssist() {
+ IStatusBarService service = getStatusBarService();
+ if (service != null) {
+ try {
+ service.startAssist(new Bundle());
+ } catch (RemoteException e) {}
+ }
+ }
+ }
+
+ public static void clearAllNotifications() {
+ FireActions.clearAllNotifications();
+ }
+
+ public static void toggleQsPanel() {
+ FireActions.toggleQsPanel();
+ }
+
+ public static void toggleNotifications() {
+ FireActions.toggleNotifications();
+ }
+
+ public static void startAssist() {
+ FireActions.startAssist();
+ }
+
+ public static boolean isPackageEnabled(String packageName, PackageManager pm) {
+ try {
+ ApplicationInfo ai = pm.getApplicationInfo(packageName, 0);
+ return ai.enabled;
+ } catch (PackageManager.NameNotFoundException notFound) {
+ return false;
+ }
+ }
+
+ public static boolean isPackageEnabled(String packageName, Context context) {
+ return isPackageEnabled(packageName, context.getPackageManager());
+ }
+
+ /**
+ * Checks if a package is available to handle the given action.
+ */
+ public static boolean resolveIntent(Context context, Intent intent) {
+ // check whether the target handler exist in system
+ PackageManager pm = context.getPackageManager();
+ List<ResolveInfo> results = pm.queryIntentActivitiesAsUser(intent,
+ PackageManager.MATCH_SYSTEM_ONLY,
+ UserHandle.myUserId());
+ for (ResolveInfo resolveInfo : results) {
+ // check is it installed in system.img, exclude the application
+ // installed by user
+ if ((resolveInfo.activityInfo.applicationInfo.flags &
+ ApplicationInfo.FLAG_SYSTEM) != 0) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static boolean resolveIntent(Context context, String action) {
+ return resolveIntent(context, new Intent(action));
+ }
+
+
+ public static boolean isPackageAvailable(String packageName, Context context) {
+ Context mContext = context;
+ final PackageManager pm = mContext.getPackageManager();
+ try {
+ pm.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES);
+ int enabled = pm.getApplicationEnabledSetting(packageName);
+ return enabled != PackageManager.COMPONENT_ENABLED_STATE_DISABLED &&
+ enabled != PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
+ } catch (PackageManager.NameNotFoundException e) {
+ return false;
+ }
+ }
+
+ public static void sendKeycode(int keycode) {
+ long when = SystemClock.uptimeMillis();
+ final KeyEvent evDown = new KeyEvent(when, when, KeyEvent.ACTION_DOWN, keycode, 0,
+ 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
+ KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY,
+ InputDevice.SOURCE_KEYBOARD);
+ final KeyEvent evUp = KeyEvent.changeAction(evDown, KeyEvent.ACTION_UP);
+
+ final Handler handler = new Handler(Looper.getMainLooper());
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ InputManager.getInstance().injectInputEvent(evDown,
+ InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
+ }
+ });
+ handler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ InputManager.getInstance().injectInputEvent(evUp,
+ InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
+ }
+ }, 20);
+ }
+
+ // Method to turn off the screen
+ public static void switchScreenOff(Context ctx) {
+ PowerManager pm = (PowerManager) ctx.getSystemService(Context.POWER_SERVICE);
+ if (pm!= null && pm.isScreenOn()) {
+ pm.goToSleep(SystemClock.uptimeMillis());
+ }
+ }
+
+ // Cycle ringer modes
+ public static void toggleRingerModes (Context context) {
+ AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+ Vibrator mVibrator = (Vibrator) context.getSystemService(VIBRATOR_SERVICE);
+
+ switch (am.getRingerMode()) {
+ case AudioManager.RINGER_MODE_NORMAL:
+ if (mVibrator.hasVibrator()) {
+ am.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
+ }
+ break;
+ case AudioManager.RINGER_MODE_VIBRATE:
+ am.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
+ NotificationManager notificationManager =
+ (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
+ notificationManager.setInterruptionFilter(
+ NotificationManager.INTERRUPTION_FILTER_PRIORITY);
+ break;
+ case AudioManager.RINGER_MODE_SILENT:
+ am.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
+ break;
+ }
+ }
+
+ // Volume panel
+ public static void toggleVolumePanel(Context context) {
+ AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+ am.adjustVolume(AudioManager.ADJUST_SAME, AudioManager.FLAG_SHOW_UI);
+ }
+
+ public static void launchCamera(Context context) {
+ Intent intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ context.startActivity(intent);
+ }
+
+ public static void launchVoiceSearch(Context context) {
+ Intent intent = new Intent(Intent.ACTION_SEARCH_LONG_PRESS);
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(intent);
+ }
+
+ public static void triggerHushMute(Context context) {
+ // We can't call AudioService#silenceRingerModeInternal from here, so this is a partial copy of it
+ int silenceRingerSetting = Settings.Secure.getIntForUser(context.getContentResolver(),
+ Settings.Secure.VOLUME_HUSH_GESTURE, Settings.Secure.VOLUME_HUSH_OFF,
+ UserHandle.USER_CURRENT);
+
+ int ringerMode;
+ int toastText;
+ if (silenceRingerSetting == Settings.Secure.VOLUME_HUSH_VIBRATE) {
+ ringerMode = AudioManager.RINGER_MODE_VIBRATE;
+ toastText = com.android.internal.R.string.volume_dialog_ringer_guidance_vibrate;
+ } else {
+ // VOLUME_HUSH_MUTE and VOLUME_HUSH_OFF
+ ringerMode = AudioManager.RINGER_MODE_SILENT;
+ toastText = com.android.internal.R.string.volume_dialog_ringer_guidance_silent;
+ }
+ AudioManager audioMan = (AudioManager)
+ context.getSystemService(Context.AUDIO_SERVICE);
+ audioMan.setRingerModeInternal(ringerMode);
+ Toast.makeText(context, toastText, Toast.LENGTH_SHORT).show();
+ }
+
+ public static void takeScreenshot(boolean full) {
+ final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
+ try {
+ wm.sendCustomAction(new Intent(full? INTENT_SCREENSHOT : INTENT_REGION_SCREENSHOT));
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static void showPowerMenu() {
+ final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
+ try {
+ wm.showGlobalActions();
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ }
+
+ // Check if device has a notch
+ public static boolean hasNotch(Context context) {
+ String displayCutout = context.getResources().getString(R.string.config_mainBuiltInDisplayCutout);
+ boolean maskDisplayCutout = context.getResources().getBoolean(R.bool.config_maskMainBuiltInDisplayCutout);
+ boolean displayCutoutExists = (!TextUtils.isEmpty(displayCutout) && !maskDisplayCutout);
+ return displayCutoutExists;
+ }
+}
diff --git a/core/java/com/android/internal/util/bliss/ColorAnimator.java b/core/java/com/android/internal/util/bliss/ColorAnimator.java
new file mode 100644
index 0000000..7219dc4
--- /dev/null
+++ b/core/java/com/android/internal/util/bliss/ColorAnimator.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2016 The DirtyUnicorns Project
+ * 2019 crDroid Android 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.util.bliss;
+
+import android.animation.ValueAnimator;
+import android.graphics.Color;
+
+public class ColorAnimator implements ValueAnimator.AnimatorUpdateListener {
+ public interface ColorAnimationListener {
+ public void onColorChanged(ColorAnimator colorAnimator, int color);
+ public void onStartAnimation(ColorAnimator colorAnimator, int firstColor);
+ public void onStopAnimation(ColorAnimator colorAnimator, int lastColor);
+ }
+
+ public static final int ANIM_DEF_DURATION = 10 * 1000;
+ public static final String RED = "#ffff8080";
+ public static final String BLUE = "#ff8080ff";
+
+ protected final float[] from = new float[3], to = new float[3], hsv = new float[3];
+
+ protected ValueAnimator mColorAnim;
+ protected long mAnimTime = ANIM_DEF_DURATION;
+ protected int mFromColor = Color.parseColor(RED);
+ protected int mToColor = Color.parseColor(BLUE);
+ protected int mLastColor = Color.parseColor(RED);
+ protected boolean mIsRunning;
+
+ protected ColorAnimationListener mListener;
+
+ public ColorAnimator() {
+ this(ValueAnimator.ofFloat(0, 1));
+ }
+
+ public ColorAnimator(ValueAnimator valueAnimator) {
+ this(valueAnimator, ANIM_DEF_DURATION);
+ }
+
+ public ColorAnimator(ValueAnimator valueAnimator, long animDurationMillis) {
+ this(valueAnimator, animDurationMillis, Color.parseColor(RED), Color.parseColor(BLUE));
+ }
+
+ public ColorAnimator(ValueAnimator valueAnimator, long animDurationMillis, int fromColor,
+ int toColor) {
+ mAnimTime = animDurationMillis;
+ mFromColor = fromColor;
+ mToColor = toColor;
+ mColorAnim = valueAnimator;
+ mColorAnim.addUpdateListener(this);
+ }
+
+ public void start() {
+ stop();
+ Color.colorToHSV(mFromColor, from);
+ Color.colorToHSV(mToColor, to);
+ mColorAnim.setDuration(mAnimTime);
+ mColorAnim.setRepeatMode(ValueAnimator.REVERSE);
+ mColorAnim.setRepeatCount(ValueAnimator.INFINITE);
+ if (mListener != null) {
+ mListener.onStartAnimation(this, mFromColor);
+ }
+ mColorAnim.start();
+ mIsRunning = true;
+ }
+
+ public void stop() {
+ if (mColorAnim.isStarted()) {
+ mColorAnim.end();
+ mIsRunning = false;
+ if (mListener != null) {
+ mListener.onStopAnimation(this, mLastColor);
+ }
+ }
+ }
+
+ public boolean isRunning() {
+ return mIsRunning;
+ }
+
+ public void setAnimationTime(long millis) {
+ if (mAnimTime != millis) {
+ mAnimTime = millis;
+ if (mColorAnim.isRunning()) {
+ start();
+ }
+ }
+ }
+
+ public void setColorAnimatorListener(ColorAnimationListener listener) {
+ mListener = listener;
+ }
+
+ public void removeColorAnimatorListener(ColorAnimationListener listener) {
+ mListener = null;
+ }
+
+ public void onAnimationUpdate(ValueAnimator animation) {
+ // Transition along each axis of HSV (hue, saturation, value)
+ hsv[0] = from[0] + (to[0] - from[0]) * animation.getAnimatedFraction();
+ hsv[1] = from[1] + (to[1] - from[1]) * animation.getAnimatedFraction();
+ hsv[2] = from[2] + (to[2] - from[2]) * animation.getAnimatedFraction();
+
+ mLastColor = Color.HSVToColor(hsv);
+
+ if (mListener != null) {
+ mListener.onColorChanged(this, mLastColor);
+ }
+ }
+
+ public int getCurrentColor() {
+ return mLastColor;
+ }
+}
diff --git a/core/java/com/android/internal/util/bliss/LineageButtons.java b/core/java/com/android/internal/util/bliss/LineageButtons.java
new file mode 100644
index 0000000..a0c28b0
--- /dev/null
+++ b/core/java/com/android/internal/util/bliss/LineageButtons.java
@@ -0,0 +1,283 @@
+/**
+ * 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.internal.util.bliss;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.res.Resources;
+import android.database.ContentObserver;
+import android.media.AudioManager;
+import android.media.session.MediaController;
+import android.media.session.MediaSessionLegacyHelper;
+import android.media.session.MediaSessionManager;
+import android.media.session.PlaybackState;
+import android.os.Handler;
+import android.os.Message;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.view.KeyEvent;
+import android.view.ViewConfiguration;
+
+import com.android.internal.util.bliss.BlissUtils;
+
+import java.util.List;
+
+public final class LineageButtons {
+ private final String TAG = "LineageButtons";
+
+ private static final int MSG_DISPATCH_VOLKEY_WITH_WAKELOCK = 1;
+
+ private final Context mContext;
+ private final ButtonHandler mHandler;
+
+ private boolean mIsLongPress = false;
+
+ private boolean mVolBtnMusicControls = false;
+ private final MediaSessionManager mMediaSessionManager;
+
+ private class ButtonHandler extends Handler {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_DISPATCH_VOLKEY_WITH_WAKELOCK:
+ KeyEvent ev = (KeyEvent) msg.obj;
+ mIsLongPress = true;
+ onSkipTrackEvent(ev);
+ break;
+ }
+ }
+ }
+
+ private static final Object sInstanceLock = new Object();
+ private static LineageButtons sInstance;
+
+ public static LineageButtons getAttachedInstance(Context context) {
+ synchronized (sInstanceLock) {
+ if (sInstance != null) {
+ return sInstance;
+ }
+ return new LineageButtons(context);
+ }
+ }
+
+ public LineageButtons(Context context) {
+ mContext = context;
+ mHandler = new ButtonHandler();
+ mMediaSessionManager = mContext.getSystemService(MediaSessionManager.class);
+
+ SettingsObserver observer = new SettingsObserver(new Handler());
+ observer.observe();
+
+ sInstance = this;
+ }
+
+ public boolean handleVolumeKey(KeyEvent event, boolean isInteractive) {
+ final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
+ final int keyCode = event.getKeyCode();
+
+ if (isInteractive) {
+ // nothing to do here for now
+ return false;
+ }
+
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_VOLUME_DOWN:
+ case KeyEvent.KEYCODE_VOLUME_UP:
+ if (!mVolBtnMusicControls) {
+ return false;
+ }
+
+ if (down) {
+ mIsLongPress = false;
+ // queue skip event
+ int newKeyCode = (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
+ ? KeyEvent.KEYCODE_MEDIA_PREVIOUS
+ : KeyEvent.KEYCODE_MEDIA_NEXT);
+ KeyEvent newEvent = new KeyEvent(event.getDownTime(), event.getEventTime(),
+ event.getAction(), newKeyCode, 0);
+ Message msg = mHandler.obtainMessage(MSG_DISPATCH_VOLKEY_WITH_WAKELOCK,
+ newEvent);
+ msg.setAsynchronous(true);
+ mHandler.sendMessageDelayed(msg, ViewConfiguration.getLongPressTimeout());
+ } else {
+ // cancel skip event
+ mHandler.removeMessages(MSG_DISPATCH_VOLKEY_WITH_WAKELOCK);
+
+ if (mIsLongPress) {
+ // if key was long pressed, media next/prev action has been performed,
+ // so don't change volume
+ break;
+ }
+ // sendVolumeKeyEvent will only change the volume on ACTION_DOWN,
+ // so fake the ACTION_DOWN event.
+ KeyEvent newEvent = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
+ MediaSessionLegacyHelper.getHelper(mContext).sendVolumeKeyEvent(newEvent,
+ AudioManager.USE_DEFAULT_STREAM_TYPE, true);
+ }
+ break;
+ default:
+ // key unhandled
+ return false;
+ }
+ return true;
+ }
+
+ private void triggerKeyEvents(KeyEvent evDown, MediaController controller) {
+ final KeyEvent evUp = KeyEvent.changeAction(evDown, KeyEvent.ACTION_UP);
+ mHandler.post(() -> controller.dispatchMediaButtonEvent(evDown));
+ mHandler.postDelayed(() -> controller.dispatchMediaButtonEvent(evUp), 20);
+ }
+
+ public void onSkipTrackEvent(KeyEvent ev) {
+ if (mMediaSessionManager != null) {
+ final List<MediaController> sessions
+ = mMediaSessionManager.getActiveSessionsForUser(
+ null, UserHandle.USER_ALL);
+ for (MediaController aController : sessions) {
+ if (PlaybackState.STATE_PLAYING ==
+ getMediaControllerPlaybackState(aController)) {
+ triggerKeyEvents(ev, aController);
+ break;
+ }
+ }
+ }
+ }
+
+ public void skipTrack() {
+ long when = SystemClock.uptimeMillis();
+ KeyEvent newEvent = new KeyEvent(when, when,
+ KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_NEXT, 0);
+ onSkipTrackEvent(newEvent);
+ }
+
+ public void previousTrack() {
+ long when = SystemClock.uptimeMillis();
+ KeyEvent newEvent = new KeyEvent(when, when,
+ KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PREVIOUS, 0);
+ onSkipTrackEvent(newEvent);
+ }
+
+ private int getMediaControllerPlaybackState(MediaController controller) {
+ if (controller != null) {
+ final PlaybackState playbackState = controller.getPlaybackState();
+ if (playbackState != null) {
+ return playbackState.getState();
+ }
+ }
+ return PlaybackState.STATE_NONE;
+ }
+
+ class SettingsObserver extends ContentObserver {
+ SettingsObserver(Handler handler) {
+ super(handler);
+ }
+
+ void observe() {
+ ContentResolver resolver = mContext.getContentResolver();
+
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.VOLUME_BUTTON_MUSIC_CONTROL),
+ false, this, UserHandle.USER_ALL);
+
+ update();
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ update();
+ }
+
+ private void update() {
+ ContentResolver resolver = mContext.getContentResolver();
+
+ mVolBtnMusicControls = Settings.System.getIntForUser(
+ resolver, Settings.System.VOLUME_BUTTON_MUSIC_CONTROL, 1,
+ UserHandle.USER_CURRENT) == 1;
+ }
+ }
+
+ // Elmyra app actions
+ public void performTriggeredAction(String action, Context context, boolean interactive) {
+ switch(action) {
+ case "flashlight":
+ BlissUtils.toggleCameraFlash(false);
+ break;
+ case "assist":
+ BlissUtils.startAssist();
+ break;
+ case "screenshot":
+ // already disabled when screen is OFF by Elmyra app
+ BlissUtils.takeScreenshot(true/*full*/);
+ break;
+ case "partialscreenshot":
+ // already disabled when screen is OFF by Elmyra app
+ BlissUtils.takeScreenshot(false/*full*/);
+ break;
+ case "camera":
+ if (!interactive) {
+ BlissUtils.switchScreenOff(context);
+ }
+ BlissUtils.launchCamera(context);
+ break;
+ case "mute":
+ BlissUtils.triggerHushMute(context);
+ break;
+ case "screen":
+ if (interactive) {
+ BlissUtils.switchScreenOff(context);
+ } else {
+ BlissUtils.switchScreenOn(context);
+ }
+ break;
+ case "skiptrack":
+ skipTrack();
+ break;
+ case "previoustrack":
+ previousTrack();
+ break;
+ case "voicesearch":
+ BlissUtils.launchVoiceSearch(context);
+ break;
+ case "volumepanel":
+ // already disabled when screen is OFF by Elmyra app
+ BlissUtils.toggleVolumePanel(context);
+ break;
+ case "powermenu":
+ // already disabled when screen is OFF by Elmyra app
+ BlissUtils.showPowerMenu();
+ break;
+ case "toggleqspanel":
+ // already disabled when screen is OFF by Elmyra app
+ BlissUtils.toggleQsPanel();
+ break;
+ case "togglenotificationspanel":
+ // already disabled when screen is OFF by Elmyra app
+ BlissUtils.toggleNotifications();
+ break;
+ case "clearallnotifications":
+ // already disabled when screen is OFF by Elmyra app
+ BlissUtils.clearAllNotifications();
+ break;
+ case "toggleringermodes":
+ BlissUtils.toggleRingerModes(context);
+ break;
+ default:
+ break;
+ }
+ }
+}
diff --git a/core/java/com/android/internal/util/hwkeys/ActionConstants.java b/core/java/com/android/internal/util/hwkeys/ActionConstants.java
new file mode 100644
index 0000000..1007b92
--- /dev/null
+++ b/core/java/com/android/internal/util/hwkeys/ActionConstants.java
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2015 TeamEos project
+ * Author Randall Rushing aka bigrushdog, randall.rushing@gmail.com
+ *
+ * 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.
+ *
+ * ActionConstants.java: A helper class to assist Config.java with loading
+ * and assigning default feature configurations. Nested classes implement
+ * the static interface Defaults, which allows Settings and Config.java
+ * to handle configurations in a non-implementation specific way, allowing
+ * for more generalized code structures.
+ *
+ * Of strong importance is the ConfigMap pojo class. Current settings use
+ * a ActionPreference which sets a single action. Therefore, we must have a
+ * way to map individual actions to their associated buttons. ActionPreference
+ * key MUST match the tag associated with the target ConfigMap.
+ *
+ */
+
+package com.android.internal.util.hwkeys;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.android.internal.util.hwkeys.ActionHandler.SystemAction;
+import com.android.internal.util.hwkeys.Config.ActionConfig;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.util.Log;
+import android.util.TypedValue;
+
+public class ActionConstants {
+ public static interface Defaults {
+ public int getConfigType();
+ public String getUri();
+ public String getDefaultConfig();
+ public int getMaxButtons();
+ public Map<String, ConfigMap> getActionMap();
+ public Bundle getConfigs(Context context);
+ }
+
+ public static final String ACTION_DELIMITER = "|";
+ public static final String EMPTY = "empty";
+ public static final int HWKEYS = 1;
+
+ private static final Hwkeys hwkeys = new Hwkeys();
+
+ public static Defaults getDefaults(int type) {
+ if (type == HWKEYS) {
+ return hwkeys;
+ } else {
+ return null;
+ }
+ }
+
+ public static String dl(String s) {
+ return s + ACTION_DELIMITER;
+ }
+
+ public static class Hwkeys implements Defaults {
+ public static final int HWKEY_MAX_BUTTONS = 7;
+ public static final String HWKEY_DEF_BUTTONS = "5";
+ public static final String BACK_BUTTON_TAG = "hwkeys_button_back";
+ public static final String HOME_BUTTON_TAG = "hwkeys_button_home";
+ public static final String OVERVIEW_BUTTON_TAG = "hwkeys_button_overview";
+ public static final String MENU_BUTTON_TAG = "hwkeys_button_menu";
+ public static final String ASSIST_BUTTON_TAG = "hwkeys_button_assist";
+ public static final String EXTRA1_BUTTON_TAG = "hwkeys_button_camera";
+ public static final String EXTRA2_BUTTON_TAG = "hwkeys_button_extra";
+
+ public static final String BACK_BUTTON_SINGLE_TAP_TAG = "hwkeys_button_back_single_tap";
+ public static final String HOME_BUTTON_SINGLE_TAP_TAG = "hwkeys_button_home_single_tap";
+ public static final String OVERVIEW_BUTTON_SINGLE_TAP_TAG = "hwkeys_button_overview_single_tap";
+ public static final String MENU_BUTTON_SINGLE_TAP_TAG = "hwkeys_button_menu_single_tap";
+ public static final String ASSIST_BUTTON_SINGLE_TAP_TAG = "hwkeys_button_assist_single_tap";
+
+ public static final String BACK_BUTTON_LONG_PRESS_TAG = "hwkeys_button_back_long_press";
+ public static final String HOME_BUTTON_LONG_PRESS_TAG = "hwkeys_button_home_long_press";
+ public static final String OVERVIEW_BUTTON_LONG_PRESS_TAG = "hwkeys_button_overview_long_press";
+ public static final String MENU_BUTTON_LONG_PRESS_TAG = "hwkeys_button_menu_long_press";
+ public static final String ASSIST_BUTTON_LONG_PRESS_TAG = "hwkeys_button_assist_long_press";
+
+ public static final String BACK_BUTTON_DOUBLE_TAP_TAG = "hwkeys_button_back_double_tap";
+ public static final String HOME_BUTTON_DOUBLE_TAP_TAG = "hwkeys_button_home_double_tap";
+ public static final String OVERVIEW_BUTTON_DOUBLE_TAP_TAG = "hwkeys_button_overview_double_tap";
+ public static final String MENU_BUTTON_DOUBLE_TAP_TAG = "hwkeys_button_menu_double_tap";
+ public static final String ASSIST_BUTTON_DOUBLE_TAP_TAG = "hwkeys_button_assist_double_tap";
+
+ private static final Map<String, ConfigMap> configMap = new HashMap<String, ConfigMap>();
+
+ static {
+ configMap.put(BACK_BUTTON_SINGLE_TAP_TAG, new ConfigMap(0, ActionConfig.PRIMARY));
+ configMap.put(HOME_BUTTON_SINGLE_TAP_TAG, new ConfigMap(1, ActionConfig.PRIMARY));
+ configMap.put(OVERVIEW_BUTTON_SINGLE_TAP_TAG, new ConfigMap(2, ActionConfig.PRIMARY));
+ configMap.put(MENU_BUTTON_SINGLE_TAP_TAG, new ConfigMap(3, ActionConfig.PRIMARY));
+ configMap.put(ASSIST_BUTTON_SINGLE_TAP_TAG, new ConfigMap(4, ActionConfig.PRIMARY));
+ configMap.put(BACK_BUTTON_LONG_PRESS_TAG, new ConfigMap(0, ActionConfig.SECOND));
+ configMap.put(HOME_BUTTON_LONG_PRESS_TAG, new ConfigMap(1, ActionConfig.SECOND));
+ configMap.put(OVERVIEW_BUTTON_LONG_PRESS_TAG, new ConfigMap(2, ActionConfig.SECOND));
+ configMap.put(MENU_BUTTON_LONG_PRESS_TAG, new ConfigMap(3, ActionConfig.SECOND));
+ configMap.put(ASSIST_BUTTON_LONG_PRESS_TAG, new ConfigMap(4, ActionConfig.SECOND));
+ configMap.put(BACK_BUTTON_DOUBLE_TAP_TAG, new ConfigMap(0, ActionConfig.THIRD));
+ configMap.put(HOME_BUTTON_DOUBLE_TAP_TAG, new ConfigMap(1, ActionConfig.THIRD));
+ configMap.put(OVERVIEW_BUTTON_DOUBLE_TAP_TAG, new ConfigMap(2, ActionConfig.THIRD));
+ configMap.put(MENU_BUTTON_DOUBLE_TAP_TAG, new ConfigMap(3, ActionConfig.THIRD));
+ configMap.put(ASSIST_BUTTON_DOUBLE_TAP_TAG, new ConfigMap(4, ActionConfig.THIRD));
+ }
+
+ public static final String HWKEYS_CONFIG_DEFAULT =
+ dl(HWKEY_DEF_BUTTONS)
+ + dl(BACK_BUTTON_TAG)
+ + dl(SystemAction.Back.mAction) + dl(SystemAction.Back.mLabelRes) + dl(EMPTY) // single tap (PRIMARY)
+ + dl(SystemAction.KillApp.mAction) + dl(SystemAction.KillApp.mLabelRes) + dl(EMPTY) // long press (SECOND)
+ + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + dl(EMPTY) // double tap (THIRD)
+
+ + dl(HOME_BUTTON_TAG)
+ + dl(SystemAction.Home.mAction) + dl(SystemAction.Home.mLabelRes) + dl(EMPTY)
+ + dl(SystemAction.Overview.mAction) + dl(SystemAction.Overview.mLabelRes) + dl(EMPTY)
+ + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + dl(EMPTY)
+
+ + dl(OVERVIEW_BUTTON_TAG)
+ + dl(SystemAction.Overview.mAction) + dl(SystemAction.Overview.mLabelRes) + dl(EMPTY)
+ + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + dl(EMPTY)
+ + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + dl(EMPTY)
+
+ + dl(MENU_BUTTON_TAG)
+ + dl(SystemAction.Menu.mAction) + dl(SystemAction.Menu.mLabelRes) + dl(EMPTY)
+ + dl(SystemAction.LastApp.mAction) + dl(SystemAction.LastApp.mLabelRes) + dl(EMPTY)
+ + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + dl(EMPTY)
+
+ + dl(ASSIST_BUTTON_TAG)
+ + dl(SystemAction.GoogleAssistant.mAction) + dl(SystemAction.GoogleAssistant.mLabelRes) + dl(EMPTY)
+ + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + dl(EMPTY)
+ + dl(SystemAction.NoAction.mAction) + dl(SystemAction.NoAction.mLabelRes) + EMPTY;
+
+ @Override
+ public int getConfigType() {
+ return HWKEYS;
+ }
+
+ @Override
+ public String getUri() {
+ //return Settings.System.HWKEY_BUTTON_ACTIONS;
+ return "hwkey_config";
+ }
+
+ @Override
+ public String getDefaultConfig() {
+ return HWKEYS_CONFIG_DEFAULT;
+ }
+
+ @Override
+ public int getMaxButtons() {
+ return HWKEY_MAX_BUTTONS;
+ }
+
+ @Override
+ public Map<String, ConfigMap> getActionMap() {
+ return configMap;
+ }
+
+ @Override
+ public Bundle getConfigs(Context context) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ }
+
+ private static Bundle loadConfigsFromMap(Context ctx, Map<String, ConfigHolder> configMap) {
+ Bundle b = new Bundle();
+ for (Map.Entry<String, ConfigHolder> entry : configMap.entrySet()) {
+ ConfigHolder holder = entry.getValue();
+ Object obj = ActionUtils.getValue(ctx, holder.name, holder.type, holder.format,
+ holder.pkg);
+ ActionUtils.putValue(holder.name, obj, holder.type, b);
+ }
+ return b;
+ }
+
+ private static class ConfigHolder {
+ public String pkg;
+ public String name;
+ public String format;
+ public String type;
+
+ public ConfigHolder(String pkg, String name, String type) {
+ this(pkg, name, null, type);
+ }
+
+ public ConfigHolder(String pkg, String name, String format, String type) {
+ this.pkg = pkg;
+ this.name = name;
+ this.format = format;
+ this.type = type;
+ }
+ }
+
+ public static class ConfigMap {
+ public int button = -1;
+ public int action = -1;
+
+ public ConfigMap() {
+ };
+
+ public ConfigMap(int button, int action) {
+ this.button = button;
+ this.action = action;
+ }
+ }
+
+}
diff --git a/core/java/com/android/internal/util/hwkeys/ActionHandler.java b/core/java/com/android/internal/util/hwkeys/ActionHandler.java
new file mode 100644
index 0000000..fe8075c
--- /dev/null
+++ b/core/java/com/android/internal/util/hwkeys/ActionHandler.java
@@ -0,0 +1,1040 @@
+/*
+ * Copyright (C) 2015 The TeamEos Project
+ * Copyright (C) 2016-2017 The DirtyUnicorns 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.
+ *
+ * Launches actions assigned to widgets. Creates bundles of state based
+ * on the type of action passed.
+ *
+ */
+
+package com.android.internal.util.hwkeys;
+
+import android.app.ActivityManager;
+import android.app.ActivityManagerNative;
+import android.app.ActivityOptions;
+import android.app.IActivityManager;
+import android.app.SearchManager;
+import android.app.ActivityManager.RunningAppProcessInfo;
+import android.app.ActivityManager.StackInfo;
+import android.app.usage.UsageStats;
+import android.app.usage.UsageStatsManager;
+import android.bluetooth.BluetoothAdapter;
+import android.content.ActivityNotFoundException;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.hardware.input.InputManager;
+import android.media.AudioManager;
+import android.media.ToneGenerator;
+import android.media.session.MediaSessionLegacyHelper;
+import android.net.ConnectivityManager;
+import android.net.wifi.WifiManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.PowerManager;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.os.Vibrator;
+import android.provider.Settings;
+import android.service.wallpaper.WallpaperService;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.Slog;
+import android.view.IWindowManager;
+import android.view.InputDevice;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
+import android.view.WindowManagerGlobal;
+//import android.view.WindowManagerPolicyControl;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.Toast;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.android.internal.statusbar.IStatusBarService;
+import com.android.internal.util.hwkeys.Config.ActionConfig;
+
+public class ActionHandler {
+ public static String TAG = ActionHandler.class.getSimpleName();
+
+ public static final String SYSTEM_PREFIX = "task";
+ public static final String SYSTEMUI = "com.android.systemui";
+
+ // track and filter special actions
+ public static final String TASK_IME = "task_ime";
+ public static final String TASK_MEDIA = "task_media";
+ public static final String TASK_SOUNDMODE = "task_soundmode";
+
+ public static final String SYSTEMUI_TASK_NO_ACTION = "task_no_action";
+ public static final String SYSTEMUI_TASK_SETTINGS_PANEL = "task_settings_panel";
+ public static final String SYSTEMUI_TASK_NOTIFICATION_PANEL = "task_notification_panel";
+ public static final String SYSTEMUI_TASK_SCREENSHOT = "task_screenshot";
+ public static final String SYSTEMUI_TASK_REGION_SCREENSHOT = "task_region_screenshot";
+ public static final String SYSTEMUI_TASK_SCREENRECORD = "task_screenrecord";
+ // public static final String SYSTEMUI_TASK_AUDIORECORD =
+ // "task_audiorecord";
+ public static final String SYSTEMUI_TASK_EXPANDED_DESKTOP = "task_expanded_desktop";
+ public static final String SYSTEMUI_TASK_SCREENOFF = "task_screenoff";
+ public static final String SYSTEMUI_TASK_KILL_PROCESS = "task_killcurrent";
+ public static final String SYSTEMUI_TASK_GOOGLE_ASSISTANT = "task_google_assistant";
+ public static final String SYSTEMUI_TASK_POWER_MENU = "task_powermenu";
+ public static final String SYSTEMUI_TASK_TORCH = "task_torch";
+ public static final String SYSTEMUI_TASK_CAMERA = "task_camera";
+ public static final String SYSTEMUI_TASK_BT = "task_bt";
+ public static final String SYSTEMUI_TASK_WIFI = "task_wifi";
+ public static final String SYSTEMUI_TASK_WIFIAP = "task_wifiap";
+ public static final String SYSTEMUI_TASK_RECENTS = "task_recents";
+ public static final String SYSTEMUI_TASK_LAST_APP = "task_last_app";
+ public static final String SYSTEMUI_TASK_APP_SEARCH = "task_app_search";
+ public static final String SYSTEMUI_TASK_MENU = "task_menu";
+ public static final String SYSTEMUI_TASK_BACK = "task_back";
+ public static final String SYSTEMUI_TASK_HOME = "task_home";
+ public static final String SYSTEMUI_TASK_IME_SWITCHER = "task_ime_switcher";
+ public static final String SYSTEMUI_TASK_IME_NAVIGATION_LEFT = "task_ime_navigation_left";
+ public static final String SYSTEMUI_TASK_IME_NAVIGATION_RIGHT = "task_ime_navigation_right";
+ public static final String SYSTEMUI_TASK_IME_NAVIGATION_UP = "task_ime_navigation_up";
+ public static final String SYSTEMUI_TASK_IME_NAVIGATION_DOWN = "task_ime_navigation_down";
+ public static final String SYSTEMUI_TASK_MEDIA_PREVIOUS = "task_media_previous";
+ public static final String SYSTEMUI_TASK_MEDIA_NEXT = "task_media_next";
+ public static final String SYSTEMUI_TASK_MEDIA_PLAY_PAUSE = "task_media_play_pause";
+ public static final String SYSTEMUI_TASK_SOUNDMODE_VIB = "task_soundmode_vib";
+ public static final String SYSTEMUI_TASK_SOUNDMODE_SILENT = "task_soundmode_silent";
+ public static final String SYSTEMUI_TASK_SOUNDMODE_VIB_SILENT = "task_soundmode_vib_silent";
+ public static final String SYSTEMUI_TASK_WAKE_DEVICE = "task_wake_device";
+ public static final String SYSTEMUI_TASK_STOP_SCREENPINNING = "task_stop_screenpinning";
+ public static final String SYSTEMUI_TASK_CLEAR_NOTIFICATIONS = "task_clear_notifications";
+ public static final String SYSTEMUI_TASK_VOLUME_PANEL = "task_volume_panel";
+ public static final String SYSTEMUI_TASK_SPLIT_SCREEN = "task_split_screen";
+ public static final String SYSTEMUI_TASK_ONE_HANDED_MODE_LEFT = "task_one_handed_mode_left";
+ public static final String SYSTEMUI_TASK_ONE_HANDED_MODE_RIGHT = "task_one_handed_mode_right";
+ public static final String SYSTEMUI_TASK_ASSISTANT_SOUND_SEARCH = "task_assistant_sound_search";
+
+ public static final String INTENT_SHOW_POWER_MENU = "action_handler_show_power_menu";
+ public static final String INTENT_TOGGLE_SCREENRECORD = "action_handler_toggle_screenrecord";
+ public static final String INTENT_SCREENSHOT = "action_take_screenshot";
+ public static final String INTENT_REGION_SCREENSHOT = "action_take_region_screenshot";
+
+ // remove actions from here as they come back on deck
+ static final Set<String> sDisabledActions = new HashSet<String>();
+ static {
+ sDisabledActions.add(SYSTEMUI_TASK_SCREENRECORD);
+ sDisabledActions.add(SYSTEMUI_TASK_EXPANDED_DESKTOP);
+ sDisabledActions.add(SYSTEMUI_TASK_ONE_HANDED_MODE_LEFT);
+ sDisabledActions.add(SYSTEMUI_TASK_ONE_HANDED_MODE_RIGHT);
+ // we need to make this more reliable when the user tap the partial screenshot button
+ // quickly and more times
+ sDisabledActions.add(SYSTEMUI_TASK_REGION_SCREENSHOT);
+ sDisabledActions.add(SYSTEMUI_TASK_STOP_SCREENPINNING);
+ sDisabledActions.add(SYSTEMUI_TASK_ASSISTANT_SOUND_SEARCH);
+ sDisabledActions.add(SYSTEMUI_TASK_POWER_MENU);
+ }
+
+ static enum SystemAction {
+ NoAction(SYSTEMUI_TASK_NO_ACTION, SYSTEMUI, "label_action_no_action", "ic_sysbar_no_action"),
+ SettingsPanel(SYSTEMUI_TASK_SETTINGS_PANEL, SYSTEMUI, "label_action_settings_panel", "ic_sysbar_settings_panel"),
+ NotificationPanel(SYSTEMUI_TASK_NOTIFICATION_PANEL, SYSTEMUI, "label_action_notification_panel", "ic_sysbar_notification_panel"),
+ Screenshot(SYSTEMUI_TASK_SCREENSHOT, SYSTEMUI, "label_action_screenshot", "ic_sysbar_screenshot"),
+ RegionScreenshot(SYSTEMUI_TASK_REGION_SCREENSHOT, SYSTEMUI, "label_action_region_screenshot", "ic_sysbar_region_screenshot"),
+ Screenrecord(SYSTEMUI_TASK_SCREENRECORD, SYSTEMUI, "label_action_screenrecord", "ic_sysbar_record_screen"),
+ ExpandedDesktop(SYSTEMUI_TASK_EXPANDED_DESKTOP, SYSTEMUI, "label_action_expanded_desktop", "ic_sysbar_expanded_desktop"),
+ ScreenOff(SYSTEMUI_TASK_SCREENOFF, SYSTEMUI, "label_action_screen_off", "ic_sysbar_screen_off"),
+ KillApp(SYSTEMUI_TASK_KILL_PROCESS, SYSTEMUI, "label_action_force_close_app", "ic_sysbar_killtask"),
+ GoogleAssistant(SYSTEMUI_TASK_GOOGLE_ASSISTANT, SYSTEMUI, "label_action_google_assistant", "ic_sysbar_google_assistant"),
+ InAppSearch(SYSTEMUI_TASK_APP_SEARCH, SYSTEMUI, "label_action_in_app_search", "ic_sysbar_in_app_search"),
+ Flashlight(SYSTEMUI_TASK_TORCH, SYSTEMUI, "label_action_flashlight", "ic_sysbar_torch"),
+ Bluetooth(SYSTEMUI_TASK_BT, SYSTEMUI, "label_action_bluetooth", "ic_sysbar_bt"),
+ WiFi(SYSTEMUI_TASK_WIFI, SYSTEMUI, "label_action_wifi", "ic_sysbar_wifi"),
+ Hotspot(SYSTEMUI_TASK_WIFIAP, SYSTEMUI, "label_action_hotspot", "ic_sysbar_hotspot"),
+ LastApp(SYSTEMUI_TASK_LAST_APP, SYSTEMUI, "label_action_last_app", "ic_sysbar_lastapp"),
+ Overview(SYSTEMUI_TASK_RECENTS, SYSTEMUI, "label_action_overview", "ic_sysbar_recent_hw"),
+ PowerMenu(SYSTEMUI_TASK_POWER_MENU, SYSTEMUI, "label_action_power_menu", "ic_sysbar_power_menu"),
+ Menu(SYSTEMUI_TASK_MENU, SYSTEMUI, "label_action_menu", "ic_sysbar_menu_hw"),
+ Back(SYSTEMUI_TASK_BACK, SYSTEMUI, "label_action_back", "ic_sysbar_back_hw"),
+ Home(SYSTEMUI_TASK_HOME, SYSTEMUI, "label_action_home", "ic_sysbar_home_hw"),
+ Ime(SYSTEMUI_TASK_IME_SWITCHER, SYSTEMUI, "label_action_ime_switcher", "ic_ime_switcher_smartbar"),
+ StopScreenPinning(SYSTEMUI_TASK_STOP_SCREENPINNING, SYSTEMUI, "label_action_stop_screenpinning", "ic_smartbar_screen_pinning_off"),
+ ImeArrowDown(SYSTEMUI_TASK_IME_NAVIGATION_DOWN, SYSTEMUI, "label_action_ime_down", "ic_sysbar_ime_down"),
+ ImeArrowLeft(SYSTEMUI_TASK_IME_NAVIGATION_LEFT, SYSTEMUI, "label_action_ime_left", "ic_sysbar_ime_left"),
+ ImeArrowRight(SYSTEMUI_TASK_IME_NAVIGATION_RIGHT, SYSTEMUI, "label_action_ime_right", "ic_sysbar_ime_right"),
+ ImeArrowUp(SYSTEMUI_TASK_IME_NAVIGATION_UP, SYSTEMUI, "label_action_ime_up", "ic_sysbar_ime_up"),
+ ClearNotifications(SYSTEMUI_TASK_CLEAR_NOTIFICATIONS, SYSTEMUI, "label_action_clear_notifications", "ic_sysbar_clear_notifications"),
+ VolumePanel(SYSTEMUI_TASK_VOLUME_PANEL, SYSTEMUI, "label_action_volume_panel", "ic_sysbar_volume_panel"),
+ SplitScreen(SYSTEMUI_TASK_SPLIT_SCREEN, SYSTEMUI, "label_action_split_screen", "ic_sysbar_docked_hw"),
+ OneHandedModeLeft(SYSTEMUI_TASK_ONE_HANDED_MODE_LEFT, SYSTEMUI, "label_action_one_handed_mode_left", "ic_sysbar_one_handed_mode_left"),
+ OneHandedModeRight(SYSTEMUI_TASK_ONE_HANDED_MODE_RIGHT, SYSTEMUI, "label_action_one_handed_mode_right", "ic_sysbar_one_handed_mode_right"),
+ MediaArrowLeft(SYSTEMUI_TASK_MEDIA_PREVIOUS, SYSTEMUI, "label_action_media_left", "ic_skip_previous"),
+ MediaArrowRight(SYSTEMUI_TASK_MEDIA_NEXT, SYSTEMUI, "label_action_media_right", "ic_skip_next"),
+ AssistantSoundSearch(SYSTEMUI_TASK_ASSISTANT_SOUND_SEARCH, SYSTEMUI, "label_action_assistant_sound_search", "ic_assistant_sound_search");
+
+ String mAction;
+ String mResPackage;
+ String mLabelRes;
+ String mIconRes;
+ String mDarkIconRes;
+
+ private SystemAction(String action, String resPackage, String labelRes, String iconRes) {
+ mAction = action;
+ mResPackage = resPackage;
+ mLabelRes = labelRes;
+ mIconRes = iconRes;
+ mDarkIconRes = iconRes + "_dark";
+ }
+
+ private ActionConfig create(Context ctx) {
+ return new ActionConfig(ctx, mAction);
+ }
+ }
+
+ /*
+ * Enumerated system actions with label and drawable support
+ */
+ static SystemAction[] systemActions = new SystemAction[] {
+ SystemAction.NoAction, SystemAction.SettingsPanel,
+ SystemAction.NotificationPanel, SystemAction.Screenshot,
+ SystemAction.ScreenOff, SystemAction.KillApp,
+ SystemAction.Flashlight, SystemAction.Bluetooth,
+ SystemAction.WiFi, SystemAction.Hotspot,
+ SystemAction.LastApp, SystemAction.PowerMenu,
+ SystemAction.Overview,SystemAction.Menu,
+ SystemAction.Back, SystemAction.GoogleAssistant,
+ SystemAction.Home, SystemAction.ExpandedDesktop,
+ SystemAction.Screenrecord, SystemAction.Ime,
+ SystemAction.StopScreenPinning, SystemAction.ImeArrowDown,
+ SystemAction.ImeArrowLeft, SystemAction.ImeArrowRight,
+ SystemAction.ImeArrowUp, SystemAction.InAppSearch,
+ SystemAction.VolumePanel, SystemAction.ClearNotifications,
+ SystemAction.SplitScreen, SystemAction.RegionScreenshot,
+ SystemAction.OneHandedModeLeft, SystemAction.OneHandedModeRight,
+ SystemAction.MediaArrowLeft, SystemAction.MediaArrowRight,
+ SystemAction.AssistantSoundSearch
+ };
+
+ public static class ActionIconResources {
+ Drawable[] mDrawables;
+ Drawable[] mDarkDrawables;
+ Map<String, Integer> mIndexMap;
+
+ public ActionIconResources(Resources res) {
+ mDrawables = new Drawable[systemActions.length];
+ mDarkDrawables = new Drawable[systemActions.length];
+ mIndexMap = new HashMap<String, Integer>();
+ for (int i = 0; i < systemActions.length; i++) {
+ mIndexMap.put(systemActions[i].mAction, i);
+ mDrawables[i] = ActionUtils.getDrawable(res, systemActions[i].mIconRes,
+ systemActions[i].mResPackage);
+ mDarkDrawables[i] = ActionUtils.getDrawable(res, systemActions[i].mDarkIconRes,
+ systemActions[i].mResPackage);
+ }
+ }
+
+ public void updateResources(Resources res) {
+ for (int i = 0; i < mDrawables.length; i++) {
+ mDrawables[i] = ActionUtils.getDrawable(res, systemActions[i].mIconRes,
+ systemActions[i].mResPackage);
+ mDarkDrawables[i] = ActionUtils.getDrawable(res, systemActions[i].mDarkIconRes,
+ systemActions[i].mResPackage);
+ }
+ }
+
+ public Drawable getActionDrawable(String action) {
+ return mDrawables[mIndexMap.get(action)];
+ }
+
+ public Drawable getDarkActionDrawable(String action) {
+ return mDarkDrawables[mIndexMap.get(action)];
+ }
+ }
+
+ /*
+ * Default list to display in an action picker
+ * Filter by device capabilities and actions used internally
+ * but we don't really want as assignable
+ */
+ public static ArrayList<ActionConfig> getSystemActions(Context context) {
+ ArrayList<ActionConfig> bundle = new ArrayList<ActionConfig>();
+ for (int i = 0; i < systemActions.length; i++) {
+ ActionConfig c = systemActions[i].create(context);
+ String action = c.getAction();
+ if (sDisabledActions.contains(action)) {
+ continue;
+ }
+ if (TextUtils.equals(action, SYSTEMUI_TASK_STOP_SCREENPINNING)
+ || TextUtils.equals(action, SYSTEMUI_TASK_IME_NAVIGATION_DOWN)
+ || TextUtils.equals(action, SYSTEMUI_TASK_IME_NAVIGATION_LEFT)
+ || TextUtils.equals(action, SYSTEMUI_TASK_IME_NAVIGATION_RIGHT)
+ || TextUtils.equals(action, SYSTEMUI_TASK_IME_NAVIGATION_UP)
+ || TextUtils.equals(action, SYSTEMUI_TASK_IME_SWITCHER)
+ || TextUtils.equals(action, SYSTEMUI_TASK_MEDIA_PREVIOUS)
+ || TextUtils.equals(action, SYSTEMUI_TASK_MEDIA_NEXT)) {
+ continue;
+ } else if (TextUtils.equals(action, SYSTEMUI_TASK_WIFIAP)
+ && !ActionUtils.deviceSupportsMobileData(context)) {
+ continue;
+ } else if (TextUtils.equals(action, SYSTEMUI_TASK_BT)
+ && !ActionUtils.deviceSupportsBluetooth()) {
+ continue;
+ } else if (TextUtils.equals(action, SYSTEMUI_TASK_TORCH)
+ && !ActionUtils.deviceSupportsFlashLight(context)) {
+ continue;
+ } else if (TextUtils.equals(action, SYSTEMUI_TASK_CAMERA)
+ && context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
+ continue;
+ } else if (TextUtils.equals(action, SYSTEMUI_TASK_SCREENRECORD)) {
+ if (!ActionUtils.getBoolean(context, "config_enableScreenrecordChord",
+ ActionUtils.PACKAGE_ANDROID)) {
+ continue;
+ }
+ }
+ bundle.add(c);
+ }
+ Collections.sort(bundle);
+ return bundle;
+ }
+
+ private static final class StatusBarHelper {
+ private static boolean isPreloaded = false;
+ private static IStatusBarService mService = null;
+
+ private static IStatusBarService getStatusBarService() {
+ synchronized (StatusBarHelper.class) {
+ if (mService == null) {
+ try {
+ mService = IStatusBarService.Stub.asInterface(
+ ServiceManager.getService("statusbar"));
+ } catch (Exception e) {
+ }
+ }
+ return mService;
+ }
+ }
+
+ private static void toggleFlashlight() {
+ IStatusBarService service = getStatusBarService();
+ try {
+ service.toggleCameraFlash(false);
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private static void toggleRecentsApps() {
+ IStatusBarService service = getStatusBarService();
+ if (service != null) {
+ try {
+ sendCloseSystemWindows("recentapps");
+ service.toggleRecentApps();
+ } catch (RemoteException e) {
+ return;
+ }
+ isPreloaded = false;
+ }
+ }
+
+ private static void cancelPreloadRecentApps() {
+ if (isPreloaded == false)
+ return;
+ IStatusBarService service = getStatusBarService();
+ if (service != null) {
+ try {
+ service.cancelPreloadRecentApps();
+ } catch (Exception e) {
+ return;
+ }
+ }
+ isPreloaded = false;
+ }
+
+ private static void preloadRecentApps() {
+ IStatusBarService service = getStatusBarService();
+ if (service != null) {
+ try {
+ service.preloadRecentApps();
+ } catch (RemoteException e) {
+ isPreloaded = false;
+ return;
+ }
+ isPreloaded = true;
+ }
+ }
+
+ private static void expandNotificationPanel() {
+ IStatusBarService service = getStatusBarService();
+ if (service != null) {
+ try {
+ service.expandNotificationsPanel();
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
+ private static void expandSettingsPanel() {
+ IStatusBarService service = getStatusBarService();
+ if (service != null) {
+ try {
+ service.expandSettingsPanel(null);
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
+ private static void fireGoogleAssistant() {
+ IStatusBarService service = getStatusBarService();
+ if (service != null) {
+ try {
+ service.startAssist(new Bundle());
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
+ private static void splitScreen() {
+ IStatusBarService service = getStatusBarService();
+ if (service != null) {
+ try {
+ service.toggleSplitScreen();
+ } catch (RemoteException e) {
+ }
+ }
+ }
+/*
+ private static void fireIntentAfterKeyguard(Intent intent) {
+ IStatusBarService service = getStatusBarService();
+ if (service != null) {
+ try {
+ service.showCustomIntentAfterKeyguard(intent);
+ } catch (RemoteException e) {
+ }
+ }
+ }
+*/
+ private static void clearAllNotifications() {
+ IStatusBarService service = getStatusBarService();
+ if (service != null) {
+ try {
+ service.onClearAllNotifications(ActivityManager.getCurrentUser());
+ } catch (RemoteException e) {
+ }
+ }
+ }
+ }
+
+ public static void toggleRecentApps() {
+ StatusBarHelper.toggleRecentsApps();
+ }
+
+ public static void cancelPreloadRecentApps() {
+ StatusBarHelper.cancelPreloadRecentApps();
+ }
+
+ public static void preloadRecentApps() {
+ StatusBarHelper.preloadRecentApps();
+ }
+/*
+ public static void performTaskFromKeyguard(Context ctx, String action) {
+ // null: throw it out
+ if (action == null) {
+ return;
+ }
+ // not a system action, should be intent
+ if (!action.startsWith(SYSTEM_PREFIX)) {
+ Intent intent = ActionUtils.getIntent(action);
+ if (intent == null) {
+ return;
+ }
+ StatusBarHelper.fireIntentAfterKeyguard(intent);
+ } else {
+ performTask(ctx, action);
+ }
+ }
+*/
+
+ public static void performTask(Context context, String action) {
+ // null: throw it out
+ if (action == null) {
+ return;
+ }
+ if (sDisabledActions.contains(action)) {
+ return;
+ }
+ // not a system action, should be intent
+ if (!action.startsWith(SYSTEM_PREFIX)) {
+ Intent intent = ActionUtils.getIntent(action);
+ if (intent == null) {
+ return;
+ }
+ launchActivity(context, intent);
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_NO_ACTION)) {
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_KILL_PROCESS)) {
+ killProcess(context);
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_SCREENSHOT)) {
+ sendCommandToWindowManager(new Intent(INTENT_SCREENSHOT));
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_REGION_SCREENSHOT)) {
+ sendCommandToWindowManager(new Intent(INTENT_REGION_SCREENSHOT));
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_SCREENRECORD)) {
+ sendCommandToWindowManager(new Intent(INTENT_TOGGLE_SCREENRECORD));
+ return;
+ // } else if (action.equals(SYSTEMUI_TASK_AUDIORECORD)) {
+ // takeAudiorecord();
+ } else if (action.equals(SYSTEMUI_TASK_EXPANDED_DESKTOP)) {
+ // toggleExpandedDesktop(context);
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_SCREENOFF)) {
+ screenOff(context);
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_WAKE_DEVICE)) {
+ PowerManager powerManager =
+ (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+ if (!powerManager.isScreenOn()) {
+ powerManager.wakeUp(SystemClock.uptimeMillis());
+ }
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_GOOGLE_ASSISTANT)) {
+ StatusBarHelper.fireGoogleAssistant();
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_POWER_MENU)) {
+ sendCommandToWindowManager(new Intent(INTENT_SHOW_POWER_MENU));
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_TORCH)) {
+ StatusBarHelper.toggleFlashlight();
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_CAMERA)) {
+ launchCamera(context);
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_WIFI)) {
+ toggleWifi(context);
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_WIFIAP)) {
+ toggleWifiAP(context);
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_BT)) {
+ toggleBluetooth();
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_RECENTS)) {
+ toggleRecentApps();
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_LAST_APP)) {
+ switchToLastApp(context);
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_SETTINGS_PANEL)) {
+ StatusBarHelper.expandSettingsPanel();
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_NOTIFICATION_PANEL)) {
+ StatusBarHelper.expandNotificationPanel();
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_APP_SEARCH)) {
+ triggerVirtualKeypress(context, KeyEvent.KEYCODE_SEARCH);
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_MENU)) {
+ triggerVirtualKeypress(context, KeyEvent.KEYCODE_MENU);
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_BACK)) {
+ triggerVirtualKeypress(context, KeyEvent.KEYCODE_BACK);
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_HOME)) {
+ triggerVirtualKeypress(context, KeyEvent.KEYCODE_HOME);
+ return;
+/* } else if (action.equals(SYSTEMUI_TASK_IME_SWITCHER)) {
+ ((InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE))
+ .showInputMethodPicker(true /* showAuxiliarySubtypes);*/
+// return;
+/* } else if (action.equals(SYSTEMUI_TASK_STOP_SCREENPINNING)) {
+ turnOffLockTask();
+ return;
+*/
+ } else if (action.equals(SYSTEMUI_TASK_IME_NAVIGATION_RIGHT)) {
+ triggerVirtualKeypress(context, KeyEvent.KEYCODE_DPAD_RIGHT);
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_IME_NAVIGATION_UP)) {
+ triggerVirtualKeypress(context, KeyEvent.KEYCODE_DPAD_UP);
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_IME_NAVIGATION_DOWN)) {
+ triggerVirtualKeypress(context, KeyEvent.KEYCODE_DPAD_DOWN);
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_IME_NAVIGATION_LEFT)) {
+ triggerVirtualKeypress(context, KeyEvent.KEYCODE_DPAD_LEFT);
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_MEDIA_PREVIOUS)) {
+ dispatchMediaKeyWithWakeLock(KeyEvent.KEYCODE_MEDIA_PREVIOUS, context);
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_MEDIA_NEXT)) {
+ dispatchMediaKeyWithWakeLock(KeyEvent.KEYCODE_MEDIA_NEXT, context);
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_MEDIA_PLAY_PAUSE)) {
+ dispatchMediaKeyWithWakeLock(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, context);
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_SOUNDMODE_VIB)) {
+ AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+ if (am != null && ActivityManagerNative.isSystemReady()) {
+ if (am.getRingerMode() != AudioManager.RINGER_MODE_VIBRATE) {
+ am.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
+ Vibrator vib = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
+ if (vib != null) {
+ vib.vibrate(50);
+ }
+ } else {
+ am.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
+ ToneGenerator tg = new ToneGenerator(
+ AudioManager.STREAM_NOTIFICATION,
+ (int) (ToneGenerator.MAX_VOLUME * 0.85));
+ if (tg != null) {
+ tg.startTone(ToneGenerator.TONE_PROP_BEEP);
+ }
+ }
+ }
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_SOUNDMODE_SILENT)) {
+ AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+ if (am != null && ActivityManagerNative.isSystemReady()) {
+ if (am.getRingerMode() != AudioManager.RINGER_MODE_SILENT) {
+ am.setRingerMode(AudioManager.RINGER_MODE_SILENT);
+ } else {
+ am.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
+ ToneGenerator tg = new ToneGenerator(
+ AudioManager.STREAM_NOTIFICATION,
+ (int) (ToneGenerator.MAX_VOLUME * 0.85));
+ if (tg != null) {
+ tg.startTone(ToneGenerator.TONE_PROP_BEEP);
+ }
+ }
+ }
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_SOUNDMODE_VIB_SILENT)) {
+ AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+ if (am != null && ActivityManagerNative.isSystemReady()) {
+ if (am.getRingerMode() == AudioManager.RINGER_MODE_NORMAL) {
+ am.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
+ Vibrator vib = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
+ if (vib != null) {
+ vib.vibrate(50);
+ }
+ } else if (am.getRingerMode() == AudioManager.RINGER_MODE_VIBRATE) {
+ am.setRingerMode(AudioManager.RINGER_MODE_SILENT);
+ } else {
+ am.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
+ ToneGenerator tg = new ToneGenerator(
+ AudioManager.STREAM_NOTIFICATION,
+ (int) (ToneGenerator.MAX_VOLUME * 0.85));
+ if (tg != null) {
+ tg.startTone(ToneGenerator.TONE_PROP_BEEP);
+ }
+ }
+ }
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_CLEAR_NOTIFICATIONS)) {
+ StatusBarHelper.clearAllNotifications();
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_VOLUME_PANEL)) {
+ volumePanel(context);
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_SPLIT_SCREEN)) {
+ StatusBarHelper.splitScreen();
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_ONE_HANDED_MODE_LEFT)) {
+// toggleOneHandedMode(context, "left");
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_ONE_HANDED_MODE_RIGHT)) {
+// toggleOneHandedMode(context, "right");
+ return;
+ } else if (action.equals(SYSTEMUI_TASK_ASSISTANT_SOUND_SEARCH)) {
+ startAssistantSoundSearch(context);
+ return;
+ }
+ }
+
+ public static boolean isActionKeyEvent(String action) {
+ if (action.equals(SYSTEMUI_TASK_HOME)
+ || action.equals(SYSTEMUI_TASK_BACK)
+// || action.equals(SYSTEMUI_TASK_SEARCH)
+ || action.equals(SYSTEMUI_TASK_MENU)
+// || action.equals(ActionConstants.ACTION_MENU_BIG)
+ || action.equals(SYSTEMUI_TASK_NO_ACTION)) {
+ return true;
+ }
+ return false;
+ }
+
+ private static void launchActivity(Context context, Intent intent) {
+ try {
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ context.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
+ } catch (Exception e) {
+ Log.i(TAG, "Unable to launch activity " + e);
+ }
+ }
+
+ private static void switchToLastApp(Context context) {
+ final ActivityManager am =
+ (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+ ActivityManager.RunningTaskInfo lastTask = getLastTask(context, am);
+
+ if (lastTask != null) {
+ am.moveTaskToFront(lastTask.id, ActivityManager.MOVE_TASK_NO_USER_ACTION,
+ getAnimation(context).toBundle());
+ }
+ }
+
+ private static ActivityOptions getAnimation(Context context) {
+ return ActivityOptions.makeCustomAnimation(context,
+ com.android.internal.R.anim.custom_app_in,
+ com.android.internal.R.anim.custom_app_out);
+ }
+
+ private static ActivityManager.RunningTaskInfo getLastTask(Context context,
+ final ActivityManager am) {
+ final List<String> packageNames = getCurrentLauncherPackages(context);
+ final List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(5);
+ for (int i = 1; i < tasks.size(); i++) {
+ String packageName = tasks.get(i).topActivity.getPackageName();
+ if (!packageName.equals(context.getPackageName())
+ && !packageName.equals(SYSTEMUI)
+ && !packageNames.contains(packageName)) {
+ return tasks.get(i);
+ }
+ }
+ return null;
+ }
+
+ private static List<String> getCurrentLauncherPackages(Context context) {
+ final PackageManager pm = context.getPackageManager();
+ final List<ResolveInfo> homeActivities = new ArrayList<>();
+ pm.getHomeActivities(homeActivities);
+ final List<String> packageNames = new ArrayList<>();
+ for (ResolveInfo info : homeActivities) {
+ final String name = info.activityInfo.packageName;
+ if (!name.equals("com.android.settings")) {
+ packageNames.add(name);
+ }
+ }
+ return packageNames;
+ }
+
+ private static void sendCloseSystemWindows(String reason) {
+ if (ActivityManagerNative.isSystemReady()) {
+ try {
+ ActivityManagerNative.getDefault().closeSystemDialogs(reason);
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
+/*
+ private static void toggleExpandedDesktop(Context context) {
+ ContentResolver cr = context.getContentResolver();
+ String newVal = "";
+ String currentVal = Settings.Global.getString(cr, Settings.Global.POLICY_CONTROL);
+ if (currentVal == null) {
+ currentVal = newVal;
+ }
+ if ("".equals(currentVal)) {
+ newVal = "immersive.full=*";
+ }
+ Settings.Global.putString(cr, Settings.Global.POLICY_CONTROL, newVal);
+ if (newVal.equals("")) {
+ WindowManagerPolicyControl.reloadFromSetting(context);
+ }
+ }
+*/
+
+ private static void dispatchMediaKeyWithWakeLock(int keycode, Context context) {
+ if (ActivityManagerNative.isSystemReady()) {
+ KeyEvent event = new KeyEvent(SystemClock.uptimeMillis(),
+ SystemClock.uptimeMillis(), KeyEvent.ACTION_DOWN, keycode, 0);
+ MediaSessionLegacyHelper.getHelper(context).sendMediaButtonEvent(event, true);
+ event = KeyEvent.changeAction(event, KeyEvent.ACTION_UP);
+ MediaSessionLegacyHelper.getHelper(context).sendMediaButtonEvent(event, true);
+ }
+ }
+
+ private static void triggerVirtualKeypress(Context context, final int keyCode) {
+ final InputManager im = InputManager.getInstance();
+ final long now = SystemClock.uptimeMillis();
+ int downflags = 0;
+
+ if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT
+ || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT
+ || keyCode == KeyEvent.KEYCODE_DPAD_UP
+ || keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
+ downflags = KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE;
+ } else {
+ downflags = KeyEvent.FLAG_FROM_SYSTEM;
+ }
+
+ final KeyEvent downEvent = new KeyEvent(now, now, KeyEvent.ACTION_DOWN,
+ keyCode, 0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
+ downflags, InputDevice.SOURCE_KEYBOARD);
+ final KeyEvent upEvent = KeyEvent.changeAction(downEvent, KeyEvent.ACTION_UP);
+ final Handler handler = new Handler(Looper.getMainLooper());
+
+ final Runnable downRunnable = new Runnable() {
+ @Override
+ public void run() {
+ im.injectInputEvent(downEvent, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
+ }
+ };
+
+ final Runnable upRunnable = new Runnable() {
+ @Override
+ public void run() {
+ im.injectInputEvent(upEvent, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
+ }
+ };
+
+ handler.post(downRunnable);
+ handler.postDelayed(upRunnable, 10);
+ }
+
+ private static void launchCamera(Context context) {
+ Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
+ PackageManager pm = context.getPackageManager();
+ final ResolveInfo mInfo = pm.resolveActivity(i, 0);
+ Intent intent = new Intent().setComponent(new ComponentName(mInfo.activityInfo.packageName,
+ mInfo.activityInfo.name));
+ launchActivity(context, intent);
+ }
+
+ private static void toggleWifi(Context context) {
+ WifiManager wfm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+ wfm.setWifiEnabled(!wfm.isWifiEnabled());
+ }
+
+ private static void toggleBluetooth() {
+ BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ boolean enabled = bluetoothAdapter.isEnabled();
+ if (enabled) {
+ bluetoothAdapter.disable();
+ } else {
+ bluetoothAdapter.enable();
+ }
+ }
+
+ private static void toggleWifiAP(Context context) {
+ final ContentResolver cr = context.getContentResolver();
+ WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+ final ConnectivityManager mConnectivityManager;
+ mConnectivityManager = (ConnectivityManager) context.getSystemService(
+ Context.CONNECTIVITY_SERVICE);
+ int state = wm.getWifiApState();
+ boolean enabled = false;
+ switch (state) {
+ case WifiManager.WIFI_AP_STATE_ENABLING:
+ case WifiManager.WIFI_AP_STATE_ENABLED:
+ enabled = false;
+ break;
+ case WifiManager.WIFI_AP_STATE_DISABLING:
+ case WifiManager.WIFI_AP_STATE_DISABLED:
+ enabled = true;
+ break;
+ }
+
+ // Turn on the Wifi AP
+ if (enabled) {
+ OnStartTetheringCallback callback = new OnStartTetheringCallback();
+ mConnectivityManager.startTethering(
+ ConnectivityManager.TETHERING_WIFI, false, callback);
+ } else {
+ mConnectivityManager.stopTethering(ConnectivityManager.TETHERING_WIFI);
+ }
+ }
+
+ static final class OnStartTetheringCallback extends
+ ConnectivityManager.OnStartTetheringCallback {
+ @Override
+ public void onTetheringStarted() {}
+ @Override
+ public void onTetheringFailed() {
+ // TODO: Show error.
+ }
+ }
+
+ private static void sendCommandToWindowManager(Intent intent) {
+ IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
+ try {
+ wm.sendCustomAction(intent);
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private static boolean killProcess(Context context) {
+ final int mUserId = ActivityManager.getCurrentUser();
+ try {
+ return killForegroundAppInternal(context, mUserId);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Could not kill foreground app");
+ }
+ return false;
+ }
+
+ private static boolean killForegroundAppInternal(Context context, int userId)
+ throws RemoteException {
+ final String packageName = getForegroundTaskPackageName(context, userId);
+ String appName;
+
+ if (packageName == null) {
+ return false;
+ }
+
+ final IActivityManager am = ActivityManagerNative.getDefault();
+
+ try {
+ ApplicationInfo app = context.getPackageManager().getApplicationInfo(packageName, 0);
+ appName = context.getPackageManager().getApplicationLabel(app).toString();
+ } catch (Exception e) {
+ appName = "";
+ }
+ am.forceStopPackage(packageName, UserHandle.USER_CURRENT);
+ Resources systemUIRes = ActionUtils.getResourcesForPackage(context, ActionUtils.PACKAGE_SYSTEMUI);
+ int ident = systemUIRes.getIdentifier("app_killed_message", ActionUtils.STRING, ActionUtils.PACKAGE_SYSTEMUI);
+ String toastMsg = systemUIRes.getString(ident,appName);
+ Context ctx = getPackageContext(context, ActionUtils.PACKAGE_SYSTEMUI);
+ Toast.makeText(ctx != null ? ctx : context, toastMsg, Toast.LENGTH_SHORT).show();
+ return true;
+ }
+
+ private static String getForegroundTaskPackageName(Context context, int userId)
+ throws RemoteException {
+ final String defaultHomePackage = resolveCurrentLauncherPackage(context, userId);
+ final IActivityManager am = ActivityManager.getService();
+ final StackInfo focusedStack = am.getFocusedStackInfo();
+
+ if (focusedStack == null || focusedStack.topActivity == null) {
+ return null;
+ }
+
+ final String packageName = focusedStack.topActivity.getPackageName();
+ if (!packageName.equals(defaultHomePackage)
+ && !packageName.equals(SYSTEMUI)) {
+ return packageName;
+ }
+
+ return null;
+ }
+
+ private static String resolveCurrentLauncherPackage(Context context, int userId) {
+ final Intent launcherIntent = new Intent(Intent.ACTION_MAIN)
+ .addCategory(Intent.CATEGORY_HOME);
+ final PackageManager pm = context.getPackageManager();
+ final ResolveInfo launcherInfo = pm.resolveActivityAsUser(launcherIntent, 0, userId);
+
+ if (launcherInfo.activityInfo != null &&
+ !launcherInfo.activityInfo.packageName.equals("android")) {
+ return launcherInfo.activityInfo.packageName;
+ }
+
+ return null;
+ }
+
+ public static Context getPackageContext(Context context, String packageName) {
+ Context pkgContext = null;
+ if (context.getPackageName().equals(packageName)) {
+ pkgContext = context;
+ } else {
+ try {
+ pkgContext = context.createPackageContext(packageName,
+ Context.CONTEXT_IGNORE_SECURITY
+ | Context.CONTEXT_INCLUDE_CODE);
+ } catch (PackageManager.NameNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+ return pkgContext;
+ }
+
+ private static boolean isPackageLiveWalls(Context ctx, String pkg) {
+ if (ctx == null || pkg == null) {
+ return false;
+ }
+ List<ResolveInfo> liveWallsList = ctx.getPackageManager().queryIntentServices(
+ new Intent(WallpaperService.SERVICE_INTERFACE),
+ PackageManager.GET_META_DATA);
+ if (liveWallsList == null) {
+ return false;
+ }
+ for (ResolveInfo info : liveWallsList) {
+ if (info.serviceInfo != null) {
+ String packageName = info.serviceInfo.packageName;
+ if (TextUtils.equals(pkg, packageName)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private static void screenOff(Context context) {
+ PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+ pm.goToSleep(SystemClock.uptimeMillis());
+ }
+
+/* public static void turnOffLockTask() {
+ try {
+ ActivityManagerNative.getDefault().stopLockTaskMode();
+ } catch (Exception e) {
+ }
+ }
+*/
+
+ public static boolean isLockTaskOn() {
+ try {
+ return ActivityManagerNative.getDefault().isInLockTaskMode();
+ } catch (Exception e) {
+ }
+ return false;
+ }
+
+ public static void volumePanel(Context context) {
+ AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+ am.adjustVolume(AudioManager.ADJUST_SAME, AudioManager.FLAG_SHOW_UI);
+ }
+
+/*
+ private static void toggleOneHandedMode(Context context, String direction) {
+ String str = Settings.Global.getString(context.getContentResolver(), Settings.Global.SINGLE_HAND_MODE);
+
+ if (TextUtils.isEmpty(str))
+ Settings.Global.putString(context.getContentResolver(), Settings.Global.SINGLE_HAND_MODE, direction);
+ else
+ Settings.Global.putString(context.getContentResolver(), Settings.Global.SINGLE_HAND_MODE, "");
+ }
+ */
+
+ public static void startAssistantSoundSearch(Context context) {
+ Intent intent = new Intent(Intent.ACTION_MAIN);
+ intent.setAction("com.google.android.googlequicksearchbox.MUSIC_SEARCH");
+ context.startActivity(intent);
+ }
+}
diff --git a/core/java/com/android/internal/util/hwkeys/ActionHolder.java b/core/java/com/android/internal/util/hwkeys/ActionHolder.java
new file mode 100644
index 0000000..07221ce
--- /dev/null
+++ b/core/java/com/android/internal/util/hwkeys/ActionHolder.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2015 TeamEos project
+ * Author Randall Rushing aka bigrushdog, randall.rushing@gmail.com
+ *
+ * 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.
+ *
+ * Widgets may implement this interface to interact with action configurations
+ *
+ */
+
+package com.android.internal.util.hwkeys;
+
+import com.android.internal.util.hwkeys.ActionConstants.ConfigMap;
+import com.android.internal.util.hwkeys.ActionConstants.Defaults;
+import com.android.internal.util.hwkeys.Config.ActionConfig;
+import com.android.internal.util.hwkeys.Config.ButtonConfig;
+
+public interface ActionHolder {
+ public String getTag();
+ public void setTag(String tag);
+ public Defaults getDefaults();
+ public void setDefaults(Defaults defaults);
+ public ConfigMap getConfigMap();
+ public void setConfigMap(ConfigMap map);
+ public ButtonConfig getButtonConfig();
+ public void setButtonConfig(ButtonConfig button);
+ public ActionConfig getActionConfig();
+ public void setActionConfig(ActionConfig action);
+ public ButtonConfig getDefaultButtonConfig();
+ public void setDefaultButtonConfig(ButtonConfig button);
+ public ActionConfig getDefaultActionConfig();
+ public void setDefaultActionConfig(ActionConfig action);
+}
diff --git a/core/java/com/android/internal/util/hwkeys/ActionUtils.java b/core/java/com/android/internal/util/hwkeys/ActionUtils.java
new file mode 100644
index 0000000..17e1031
--- /dev/null
+++ b/core/java/com/android/internal/util/hwkeys/ActionUtils.java
@@ -0,0 +1,760 @@
+/*
+ * Copyright (C) 2014 The TeamEos 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.
+ *
+ * Helper functions mostly for device configuration and some utilities
+ * including a fun ViewGroup crawler and dpi conversion
+ *
+ */
+
+package com.android.internal.util.hwkeys;
+
+import android.bluetooth.BluetoothAdapter;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Matrix;
+//import android.content.res.ThemeConfig;
+import android.graphics.Color;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.hardware.Sensor;
+import android.hardware.SensorManager;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraManager;
+import android.net.ConnectivityManager;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.ServiceManager;
+import android.os.SystemProperties;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.util.DisplayMetrics;
+import android.util.TypedValue;
+import android.view.Display;
+import android.view.IWindowManager;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.view.WindowManagerGlobal;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+
+import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.util.hwkeys.ActionConstants.Defaults;
+import com.android.internal.util.hwkeys.Config.ActionConfig;
+import com.android.internal.util.hwkeys.Config.ButtonConfig;
+
+public final class ActionUtils {
+ public static final String ANDROIDNS = "http://schemas.android.com/apk/res/android";
+ public static final String PACKAGE_SYSTEMUI = "com.android.systemui";
+ public static final String PACKAGE_ANDROID = "android";
+ public static final String FORMAT_NONE = "none";
+ public static final String FORMAT_FLOAT = "float";
+
+ public static final String ID = "id";
+ public static final String DIMEN = "dimen";
+ public static final String DIMEN_PIXEL = "dimen_pixel";
+ public static final String FLOAT = "float";
+ public static final String INT = "integer";
+ public static final String DRAWABLE = "drawable";
+ public static final String COLOR = "color";
+ public static final String BOOL = "bool";
+ public static final String STRING = "string";
+ public static final String ANIM = "anim";
+
+ // 10 inch tablets
+ public static boolean isXLargeScreen() {
+ int screenLayout = Resources.getSystem().getConfiguration().screenLayout &
+ Configuration.SCREENLAYOUT_SIZE_MASK;
+ return screenLayout == Configuration.SCREENLAYOUT_SIZE_XLARGE;
+ }
+
+ // 7 inch "phablets" i.e. grouper
+ public static boolean isLargeScreen() {
+ int screenLayout = Resources.getSystem().getConfiguration().screenLayout &
+ Configuration.SCREENLAYOUT_SIZE_MASK;
+ return screenLayout == Configuration.SCREENLAYOUT_SIZE_LARGE;
+ }
+
+ // normal phones
+ public static boolean isNormalScreen() {
+ int screenLayout = Resources.getSystem().getConfiguration().screenLayout &
+ Configuration.SCREENLAYOUT_SIZE_MASK;
+ return screenLayout == Configuration.SCREENLAYOUT_SIZE_NORMAL;
+ }
+
+ public static boolean isLandscape(Context context) {
+ return Configuration.ORIENTATION_LANDSCAPE
+ == context.getResources().getConfiguration().orientation;
+ }
+
+ public static boolean navigationBarCanMove() {
+ return Resources.getSystem().getConfiguration().smallestScreenWidthDp < 600;
+ }
+
+ public static boolean hasNavbarByDefault(Context context) {
+ boolean needsNav = (Boolean)getValue(context, "config_showNavigationBar", BOOL, PACKAGE_ANDROID);
+ String navBarOverride = SystemProperties.get("qemu.hw.mainkeys");
+ if ("1".equals(navBarOverride)) {
+ needsNav = false;
+ } else if ("0".equals(navBarOverride)) {
+ needsNav = true;
+ }
+ return needsNav;
+ }
+
+ public static boolean isHWKeysSupported(Context context) {
+ return getInt(context, "config_deviceHardwareKeys", PACKAGE_ANDROID) != 64;
+ }
+
+ public static boolean deviceSupportsLte(Context ctx) {
+ final TelephonyManager tm = (TelephonyManager)
+ ctx.getSystemService(Context.TELEPHONY_SERVICE);
+// return (tm.getLteOnCdmaMode() == PhoneConstants.LTE_ON_CDMA_TRUE)
+// || tm.getLteOnGsmMode() != 0;
+ return tm.getLteOnCdmaModeStatic() == PhoneConstants.LTE_ON_CDMA_TRUE;
+ }
+
+ public static boolean deviceSupportsDdsSupported(Context context) {
+ TelephonyManager tm = (TelephonyManager)
+ context.getSystemService(Context.TELEPHONY_SERVICE);
+ return tm.isMultiSimEnabled()
+ && tm.getMultiSimConfiguration() == TelephonyManager.MultiSimVariants.DSDA;
+ }
+
+ public static boolean deviceSupportsMobileData(Context ctx) {
+ ConnectivityManager cm = (ConnectivityManager) ctx.getSystemService(
+ Context.CONNECTIVITY_SERVICE);
+ return cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
+ }
+
+ public static boolean deviceSupportsBluetooth() {
+ return BluetoothAdapter.getDefaultAdapter() != null;
+ }
+
+ public static boolean deviceSupportsNfc(Context context) {
+ PackageManager packageManager = context.getPackageManager();
+ return packageManager.hasSystemFeature(PackageManager.FEATURE_NFC);
+ }
+
+ public static boolean deviceSupportsFlashLight(Context context) {
+ CameraManager cameraManager = (CameraManager) context.getSystemService(
+ Context.CAMERA_SERVICE);
+ try {
+ String[] ids = cameraManager.getCameraIdList();
+ for (String id : ids) {
+ CameraCharacteristics c = cameraManager.getCameraCharacteristics(id);
+ Boolean flashAvailable = c.get(CameraCharacteristics.FLASH_INFO_AVAILABLE);
+ Integer lensFacing = c.get(CameraCharacteristics.LENS_FACING);
+ if (flashAvailable != null
+ && flashAvailable
+ && lensFacing != null
+ && lensFacing == CameraCharacteristics.LENS_FACING_BACK) {
+ return true;
+ }
+ }
+ } catch (CameraAccessException | AssertionError e) {
+ // Ignore
+ }
+ return false;
+ }
+
+ public static boolean deviceSupportsCompass(Context context) {
+ SensorManager sm = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
+ return sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null
+ && sm.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) != null;
+ }
+
+ public static boolean deviceSupportsDoze(Context context) {
+ String name = (String) getValue(context, "config_dozeComponent",
+ STRING, PACKAGE_ANDROID);
+ return !TextUtils.isEmpty(name);
+ }
+
+ /**
+ * This method converts dp unit to equivalent pixels, depending on device
+ * density.
+ *
+ * @param dp A value in dp (density independent pixels) unit. Which we need
+ * to convert into pixels
+ * @param context Context to get resources and device specific display
+ * metrics
+ * @return A float value to represent px equivalent to dp depending on
+ * device density
+ */
+ public static float convertDpToPixel(float dp, Context context) {
+ Resources resources = context.getResources();
+ DisplayMetrics metrics = resources.getDisplayMetrics();
+ float px = dp * (metrics.densityDpi / 160f);
+ return px;
+ }
+
+ public static int ConvertDpToPixelAsInt(float dp, Context context) {
+ float px = convertDpToPixel(dp, context);
+ if (px < 1)
+ px = 1;
+ return Math.round(px);
+ }
+
+ public static int ConvertDpToPixelAsInt(int dp, Context context) {
+ float px = convertDpToPixel((float) dp, context);
+ if (px < 1)
+ px = 1;
+ return Math.round(px);
+ }
+
+ /**
+ * This method converts device specific pixels to density independent
+ * pixels.
+ *
+ * @param px A value in px (pixels) unit. Which we need to convert into db
+ * @param context Context to get resources and device specific display
+ * metrics
+ * @return A float value to represent dp equivalent to px value
+ */
+ public static float convertPixelsToDp(float px, Context context) {
+ Resources resources = context.getResources();
+ DisplayMetrics metrics = resources.getDisplayMetrics();
+ float dp = px / (metrics.densityDpi / 160f);
+ return dp;
+ }
+
+ public static int dpToPx(Context context, int dp) {
+ return (int) ((dp * context.getResources().getDisplayMetrics().density) + 0.5);
+ }
+
+ public static int pxToDp(Context context, int px) {
+ return (int) ((px / context.getResources().getDisplayMetrics().density) + 0.5);
+ }
+
+ /* utility to iterate a viewgroup and return a list of child views */
+ public static ArrayList<View> getAllChildren(View v) {
+
+ if (!(v instanceof ViewGroup)) {
+ ArrayList<View> viewArrayList = new ArrayList<View>();
+ viewArrayList.add(v);
+ return viewArrayList;
+ }
+
+ ArrayList<View> result = new ArrayList<View>();
+
+ ViewGroup vg = (ViewGroup) v;
+ for (int i = 0; i < vg.getChildCount(); i++) {
+
+ View child = vg.getChildAt(i);
+
+ ArrayList<View> viewArrayList = new ArrayList<View>();
+ viewArrayList.add(v);
+ viewArrayList.addAll(getAllChildren(child));
+
+ result.addAll(viewArrayList);
+ }
+ return result;
+ }
+
+ /* utility to iterate a viewgroup and return a list of child views of type */
+ public static <T extends View> ArrayList<T> getAllChildren(View root, Class<T> returnType) {
+ if (!(root instanceof ViewGroup)) {
+ ArrayList<T> viewArrayList = new ArrayList<T>();
+ try {
+ viewArrayList.add(returnType.cast(root));
+ } catch (Exception e) {
+ // handle all exceptions the same and silently fail
+ }
+ return viewArrayList;
+ }
+ ArrayList<T> result = new ArrayList<T>();
+ ViewGroup vg = (ViewGroup) root;
+ for (int i = 0; i < vg.getChildCount(); i++) {
+ View child = vg.getChildAt(i);
+ ArrayList<T> viewArrayList = new ArrayList<T>();
+ try {
+ viewArrayList.add(returnType.cast(root));
+ } catch (Exception e) {
+ // handle all exceptions the same and silently fail
+ }
+ viewArrayList.addAll(getAllChildren(child, returnType));
+ result.addAll(viewArrayList);
+ }
+ return result;
+ }
+
+ public static void resolveAndUpdateButtonActions(Context ctx, Defaults defaults) {
+ if (ctx == null || defaults == null) {
+ return;
+ }
+ boolean configChanged = false;
+ final PackageManager pm = ctx.getPackageManager();
+ ArrayList<ButtonConfig> configs = Config.getConfig(ctx, defaults);
+ ArrayList<ButtonConfig> buttonsToChange = new ArrayList<ButtonConfig>();
+ buttonsToChange.addAll(configs);
+ for (int h = 0; h < configs.size(); h++) {
+ ButtonConfig button = configs.get(h);
+ for (int i = 0; i < 3; i++) {
+ ActionConfig action = button.getActionConfig(i);
+ final String task = action.getAction();
+ if (task.startsWith(ActionHandler.SYSTEM_PREFIX)) {
+ continue;
+ }
+ String resolvedName = getFriendlyNameForUri(ctx, task);
+ if (resolvedName == null || TextUtils.equals(resolvedName, task)) {
+ // if resolved name is null or the full raw intent string is
+ // returned, we were unable to resolve
+ configChanged = true;
+ ActionConfig newAction = new ActionConfig(ctx,
+ ActionHandler.SYSTEMUI_TASK_NO_ACTION, action.getIconUri());
+ ButtonConfig newButton = buttonsToChange.get(h);
+ newButton.setActionConfig(newAction, i);
+ buttonsToChange.remove(h);
+ buttonsToChange.add(h, newButton);
+ }
+ }
+ }
+ if (configChanged) {
+ Config.setConfig(ctx, defaults, buttonsToChange);
+ }
+ }
+
+ public static Intent getIntent(String uri) {
+ if (uri == null || uri.startsWith(ActionHandler.SYSTEM_PREFIX)) {
+ return null;
+ }
+
+ Intent intent = null;
+ try {
+ intent = Intent.parseUri(uri, 0);
+ } catch (URISyntaxException e) {
+ e.printStackTrace();
+ }
+ return intent;
+ }
+
+ public static Object getValue(Context context, String resName, String resType, String pkg) {
+ return getValue(context, resName, resType, null, pkg);
+ }
+
+ public static Object getValue(Context context, String resName, String resType, String format,
+ String pkg) {
+ Resources res = getResourcesForPackage(context, pkg);
+ String tmp;
+ if (resType.equals(DIMEN_PIXEL)) {
+ tmp = DIMEN;
+ } else {
+ tmp = resType;
+ }
+ int id = res.getIdentifier(resName, tmp, pkg);
+ if (format != null) { // standard res
+ TypedValue typedVal = new TypedValue();
+ res.getValue(id, typedVal, true);
+ if (format.equals(FORMAT_FLOAT)) {
+ return Float.valueOf(typedVal.getFloat());
+ }
+ } else { // typed values
+ if (resType.equals(ID)) {
+ return Integer.valueOf(id);
+ } else if (resType.equals(DIMEN)) {
+ return Float.valueOf(res.getDimension(id));
+ } else if (resType.equals(DIMEN_PIXEL)) {
+ return Integer.valueOf(res.getDimensionPixelSize(id));
+ } else if (resType.equals(FLOAT)) {
+ return Float.valueOf(res.getFloat(id));
+ } else if (resType.equals(INT)) {
+ return Integer.valueOf(res.getInteger(id));
+ } else if (resType.equals(COLOR)) {
+ int rawColor = res.getColor(id);
+ return Integer.valueOf(Color.argb(Color.alpha(rawColor), Color.red(rawColor),
+ Color.green(rawColor), Color.blue(rawColor)));
+ } else if (resType.equals(BOOL)) {
+ return Boolean.valueOf(res.getBoolean(id));
+ } else if (resType.equals(STRING)) {
+ return String.valueOf(res.getString(id));
+ } else if (resType.equals(DRAWABLE)) {
+ return getDrawable(context, resName, pkg);
+ }
+ }
+ return null;
+ }
+
+ public static void putValue(String key, Object val, String type, Bundle b) {
+ if (type.equals(ID) || type.equals(DIMEN_PIXEL) || type.equals(INT) || type.equals(COLOR)) {
+ b.putInt(key, (Integer) val);
+ } else if (type.equals(FLOAT) || type.equals(DIMEN)) {
+ b.putFloat(key, (Float) val);
+ } else if (type.equals(BOOL)) {
+ b.putBoolean(key, (Boolean) val);
+ } else if (type.equals(STRING)) {
+ b.putString(key, (String) val);
+ }
+ }
+
+ public static int getIdentifier(Context context, String resName, String resType, String pkg) {
+ try {
+ Resources res = context.getPackageManager()
+ .getResourcesForApplication(pkg);
+ int ident = res.getIdentifier(resName, resType, pkg);
+ return ident;
+ } catch (Exception e) {
+ return -1;
+ }
+ }
+
+ public static String getString(Context context, String resName, String pkg) {
+ return (String) getValue(context, resName, STRING, null, pkg);
+ }
+
+ public static boolean getBoolean(Context context, String resName, String pkg) {
+ return (Boolean) getValue(context, resName, BOOL, null, pkg);
+ }
+
+ public static int getInt(Context context, String resName, String pkg) {
+ return (Integer) getValue(context, resName, INT, null, pkg);
+ }
+
+ public static int getColor(Context context, String resName, String pkg) {
+ return (Integer) getValue(context, resName, COLOR, null, pkg);
+ }
+
+ public static int getId(Context context, String resName, String pkg) {
+ return (Integer) getValue(context, resName, ID, null, pkg);
+ }
+
+ public static float getDimen(Context context, String resName, String pkg) {
+ return (Float) getValue(context, resName, DIMEN, null, pkg);
+ }
+
+ public static int getDimenPixelSize(Context context, String resName, String pkg) {
+ return (Integer) getValue(context, resName, DIMEN_PIXEL, null, pkg);
+ }
+
+ public static Drawable getDrawable(Context context, String drawableName, String pkg) {
+ return getDrawable(getResourcesForPackage(context, pkg), drawableName, pkg);
+ }
+
+ public static Drawable getDrawable(Context context, Uri uri) {
+ //set inputs here so we can clean up them in the finally
+ InputStream inputStream = null;
+
+ try {
+ //get the inputstream
+ inputStream = context.getContentResolver().openInputStream(uri);
+
+ //get available bitmapfactory options
+ BitmapFactory.Options options = new BitmapFactory.Options();
+ //query the bitmap to decode the stream but don't allocate pixels in memory yet
+ options.inJustDecodeBounds = true;
+ //decode the bitmap with calculated bounds
+ Bitmap b1 = BitmapFactory.decodeStream(inputStream, null, options);
+ //get raw height and width of the bitmap
+ int rawHeight = options.outHeight;
+ int rawWidth = options.outWidth;
+
+ //check if the bitmap is big and we need to scale the quality to take less memory
+ options.inSampleSize = calculateInSampleSize(options, rawHeight, rawWidth);
+
+ //We need to close and load again the inputstream to avoid null
+ try {
+ inputStream.close();
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ }
+ inputStream = context.getContentResolver().openInputStream(uri);
+
+ //decode the stream again, with the calculated SampleSize option,
+ //and allocate the memory. Also add some metrics options to take a proper density
+ options.inJustDecodeBounds = false;
+ DisplayMetrics metrics = context.getResources().getDisplayMetrics();
+ options.inScreenDensity = metrics.densityDpi;
+ options.inTargetDensity = metrics.densityDpi;
+ options.inDensity = DisplayMetrics.DENSITY_DEFAULT;
+ b1 = BitmapFactory.decodeStream(inputStream, null, options);
+ return new BitmapDrawable(context.getResources(), b1);
+
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ return null;
+ //clean up the system resources
+ } finally {
+ if (inputStream != null) {
+ try {
+ inputStream.close();
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ //Automate the quality scaling process
+ public static int calculateInSampleSize(BitmapFactory.Options options, int height, int width) {
+ //set default inSampleSize scale factor (no scaling)
+ int inSampleSize = 1;
+
+ //if img size is in 257-512 range, sample scale factor will be 4x
+ if (height > 256 || width > 256) {
+ inSampleSize = 4;
+ return inSampleSize;
+ //if img size is in 129-256 range, sample scale factor will be 2x
+ } else if (height > 128 || width > 128) {
+ inSampleSize = 2;
+ return inSampleSize;
+ }
+ //if img size is in 0-128 range, no need to scale it
+ return inSampleSize;
+ }
+
+ /**
+ * Screen images based on desired dimensions before fully decoding
+ *
+ *@param ctx Calling context
+ *@param uri Image uri
+ *@param maxWidth maximum allowed image width
+ *@param maxHeight maximum allowed image height
+ */
+ public static boolean isBitmapAllowedSize(Context ctx, Uri uri, int maxWidth, int maxHeight) {
+ InputStream inputStream = null;
+ try {
+ inputStream = ctx.getContentResolver().openInputStream(uri);
+ BitmapFactory.Options options = new BitmapFactory.Options();
+ options.inJustDecodeBounds = true;
+ BitmapFactory.decodeStream(inputStream, null, options);
+ if (options.outWidth <= maxWidth && options.outHeight <= maxHeight) {
+ return true;
+ }
+ } catch (Exception e) {
+ return false;
+ } finally {
+ try {
+ inputStream.close();
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ return false;
+ }
+
+ public static Drawable getDrawableFromComponent(PackageManager pm, String activity) {
+ Drawable d = null;
+ try {
+ Intent intent = Intent.parseUri(activity, 0);
+ ActivityInfo info = intent.resolveActivityInfo(pm,
+ PackageManager.GET_ACTIVITIES);
+ if (info != null) {
+ d = info.loadIcon(pm);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return d;
+ }
+
+ public static String getFriendlyActivityName(PackageManager pm, Intent intent,
+ boolean labelOnly) {
+ ActivityInfo ai = intent.resolveActivityInfo(pm, PackageManager.GET_ACTIVITIES);
+ String friendlyName = null;
+ if (ai != null) {
+ friendlyName = ai.loadLabel(pm).toString();
+ if (friendlyName == null && !labelOnly) {
+ friendlyName = ai.name;
+ }
+ }
+ return friendlyName != null || labelOnly ? friendlyName : intent.toUri(0);
+ }
+
+ public static String getFriendlyShortcutName(PackageManager pm, Intent intent) {
+ String activityName = getFriendlyActivityName(pm, intent, true);
+ String name = intent.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
+
+ if (activityName != null && name != null) {
+ return activityName + ": " + name;
+ }
+ return name != null ? name : intent.toUri(0);
+ }
+
+ public static String getFriendlyNameForUri(Context ctx, String uri) {
+ if (uri == null) {
+ return null;
+ }
+ if (uri.startsWith(ActionHandler.SYSTEM_PREFIX)) {
+ for (int i = 0; i < ActionHandler.systemActions.length; i++) {
+ if (ActionHandler.systemActions[i].mAction.equals(uri)) {
+ return getString(ctx, ActionHandler.systemActions[i].mLabelRes,
+ ActionHandler.systemActions[i].mResPackage);
+ }
+ }
+ } else {
+ try {
+ Intent intent = Intent.parseUri(uri, 0);
+ if (Intent.ACTION_MAIN.equals(intent.getAction())) {
+ return getFriendlyActivityName(ctx.getPackageManager(), intent, false);
+ }
+ return getFriendlyShortcutName(ctx.getPackageManager(), intent);
+ } catch (URISyntaxException e) {
+ }
+ }
+ return uri;
+ }
+
+ /**
+ *
+ * @param Target package resources
+ * @param drawableName
+ * @param Target package name
+ * @return the drawable if found, otherwise fall back to a green android guy
+ */
+ public static Drawable getDrawable(Resources res, String drawableName, String pkg) {
+ try {
+ int resId = res.getIdentifier(drawableName, DRAWABLE, pkg);
+ Drawable icon = ImageHelper.getVector(res, resId, false);
+ if (icon == null) {
+ icon = res.getDrawable(resId);
+ }
+ return icon;
+ } catch (Exception e) {
+ return res.getDrawable(
+ com.android.internal.R.drawable.sym_def_app_icon);
+ }
+ }
+
+ /**
+ *
+ * @param Target package resources
+ * @param drawableName
+ * @param Target package name
+ * @return the drawable if found, null otherwise. Useful for testing if a drawable is found
+ * in a theme overlay
+ */
+ private static Drawable getMaybeNullDrawable(Resources res, String drawableName, String pkg) {
+ try {
+ int resId = res.getIdentifier(drawableName, DRAWABLE, pkg);
+ Drawable icon = ImageHelper.getVector(res, resId, false);
+ if (icon == null) {
+ icon = res.getDrawable(resId);
+ }
+ return icon;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public static Resources getResourcesForPackage(Context ctx, String pkg) {
+ try {
+ Resources res = ctx.getPackageManager()
+ .getResourcesForApplication(pkg);
+ return res;
+ } catch (Exception e) {
+ return ctx.getResources();
+ }
+ }
+
+ /**
+ *
+ * @param Context of the calling package
+ * @param the action we want a drawable for
+ * @return if a system action drawable is requested, we try to get the drawable
+ * from any current navigation overlay. if no overlay is found, get it
+ * from SystemUI. Return a component drawable if not a system action
+ */
+ public static Drawable getDrawableForAction(Context context, String action) {
+ Drawable d = null;
+
+ // this null check is probably no-op but let's be safe anyways
+ if (action == null || context == null) {
+ return d;
+ }
+ if (action.startsWith(ActionHandler.SYSTEM_PREFIX)) {
+ for (int i = 0; i < ActionHandler.systemActions.length; i++) {
+ if (ActionHandler.systemActions[i].mAction.equals(action)) {
+ // should always be SystemUI
+ String packageName = ActionHandler.systemActions[i].mResPackage;
+ Resources res = getResourcesForPackage(context, packageName);
+ String iconName = ActionHandler.systemActions[i].mIconRes;
+ d = getNavbarThemedDrawable(context, res, iconName);
+ if (d == null) {
+ d = getDrawable(res, iconName, packageName);
+ }
+ }
+ }
+ } else {
+ d = getDrawableFromComponent(context.getPackageManager(), action);
+ }
+ return d;
+ }
+
+ /**
+ *
+ * @param calling package context, usually Settings for the custom action list adapter
+ * @param target package resources, usually SystemUI
+ * @param drawableName
+ * @return a navigation bar overlay themed action drawable if available, otherwise
+ * return drawable from SystemUI resources
+ */
+ public static Drawable getNavbarThemedDrawable(Context context, Resources defRes,
+ String drawableName) {
+ if (context == null || defRes == null || drawableName == null)
+ return null;
+
+ // TODO: turn on cmte support when it comes back
+ return getDrawable(defRes, drawableName, PACKAGE_SYSTEMUI);
+/*
+ ThemeConfig themeConfig = context.getResources().getConfiguration().themeConfig;
+
+ Drawable d = null;
+ if (themeConfig != null) {
+ try {
+ final String navbarThemePkgName = themeConfig.getOverlayForNavBar();
+ final String sysuiThemePkgName = themeConfig.getOverlayForStatusBar();
+ // Check if the same theme is applied for systemui, if so we can skip this
+ if (navbarThemePkgName != null && !navbarThemePkgName.equals(sysuiThemePkgName)) {
+ // Navbar theme and SystemUI (statusbar) theme packages are different
+ // But we can't assume navbar package has our drawable, so try navbar theme
+ // package first. If we fail, try the systemui (statusbar) package
+ // if we still fail, fall back to default package resource
+ Resources res = context.getPackageManager().getThemedResourcesForApplication(
+ PACKAGE_SYSTEMUI, navbarThemePkgName);
+ d = getMaybeNullDrawable(res, drawableName, PACKAGE_SYSTEMUI);
+ if (d == null) {
+ // drawable not found in overlay, get from default SystemUI res
+ d = getDrawable(defRes, drawableName, PACKAGE_SYSTEMUI);
+ }
+ } else {
+ // no navbar overlay present, get from default SystemUI res
+ d = getDrawable(defRes, drawableName, PACKAGE_SYSTEMUI);
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ // error thrown (unlikely), get from default SystemUI res
+ d = getDrawable(defRes, drawableName, PACKAGE_SYSTEMUI);
+ }
+ }
+ if (d == null) {
+ // theme config likely null, get from default SystemUI res
+ d = getDrawable(defRes, drawableName, PACKAGE_SYSTEMUI);
+ }
+ return d;
+ */
+ }
+}
diff --git a/core/java/com/android/internal/util/hwkeys/Config.java b/core/java/com/android/internal/util/hwkeys/Config.java
new file mode 100644
index 0000000..f279935
--- /dev/null
+++ b/core/java/com/android/internal/util/hwkeys/Config.java
@@ -0,0 +1,563 @@
+/*
+ * Copyright (C) 2015 TeamEos project
+ * Author Randall Rushing aka bigrushdog, randall.rushing@gmail.com
+ *
+ * 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.
+ *
+ * Config.java: A helper class for loading/setting feature button configurations
+ * to SettingsProvider. We start with defining a "action" in the nested
+ * ActionConfig class. A action holds a raw action string, a label for that action,
+ * and helper functions for loading an associated drawable for that action.
+ *
+ * The nested static class ButtonConfig is a convenience class that holds three
+ * ActionConfig objects. Those ActionConfig objects are labeled as "PRIMARY",
+ * "SECOND", and "THIRD", which will typically refer to a single tap, long press,
+ * and double tap, respectively. However, this is not always the case, thus the
+ * more generalized naming convention.
+ *
+ * ActionConfig and ButtonConfig implement the private Stringable interface to allow
+ * for easy loading and setting
+ *
+ */
+package com.android.internal.util.hwkeys;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import com.android.internal.util.hwkeys.ActionHandler;
+import com.android.internal.util.hwkeys.ActionConstants.ConfigMap;
+import com.android.internal.util.hwkeys.ActionConstants.Defaults;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.text.TextUtils;
+
+public class Config {
+ private interface Stringable {
+ public String toDelimitedString();
+ public void fromList(Context ctx, List<String> items);
+ }
+
+ /**
+ * For use with action/button based features that don't require a defaut configuration
+ */
+ public static ArrayList<ButtonConfig> getConfig(Context ctx, String uri,
+ boolean fromSecureSettings) {
+ if (ctx == null || uri == null) {
+ return null;
+ }
+ String config;
+ if (fromSecureSettings) {
+ config = Settings.Secure.getStringForUser(
+ ctx.getContentResolver(), uri,
+ UserHandle.USER_CURRENT);
+ } else {
+ config = Settings.System.getStringForUser(
+ ctx.getContentResolver(), uri,
+ UserHandle.USER_CURRENT);
+ }
+ if (TextUtils.isEmpty(config)) {
+ return null;
+ }
+ ArrayList<String> items = new ArrayList<String>();
+ items.addAll(Arrays.asList(config.split("\\|"))); // split string into array elements
+ int numConfigs = Integer.parseInt(items.get(0)); // first element is always the number of
+ // ButtonConfigs to parse
+ items.remove(0); // remove button count for a clean list of buttons
+
+ ArrayList<ButtonConfig> buttonList = new ArrayList<ButtonConfig>();
+ ButtonConfig buttonConfig;
+
+ for (int i = 0; i < numConfigs; i++) {
+ int from = i * ButtonConfig.NUM_ELEMENTS; // (0, 10), (10, 20)...
+ int to = from + ButtonConfig.NUM_ELEMENTS;
+ buttonConfig = new ButtonConfig(ctx);
+ buttonConfig.fromList(ctx, items.subList(from, to)); // initialize button from list
+ // elements
+ buttonList.add(buttonConfig);
+ }
+ return buttonList;
+ }
+
+ public static ArrayList<ButtonConfig> getConfig(Context ctx, Defaults defaults) {
+ if (ctx == null || defaults == null) {
+ return null;
+ }
+ String config = Settings.Secure.getStringForUser(
+ ctx.getContentResolver(), defaults.getUri(),
+ UserHandle.USER_CURRENT);
+ if (TextUtils.isEmpty(config)) {
+ config = defaults.getDefaultConfig();
+ }
+
+ ArrayList<String> items = new ArrayList<String>();
+ items.addAll(Arrays.asList(config.split("\\|"))); // split string into array elements
+ int numConfigs = Integer.parseInt(items.get(0)); // first element is always the number of ButtonConfigs to parse
+ items.remove(0); // remove button count for a clean list of buttons
+
+ ArrayList<ButtonConfig> buttonList = new ArrayList<ButtonConfig>();
+ ButtonConfig buttonConfig;
+
+ for (int i = 0; i < numConfigs; i++) {
+ int from = i * ButtonConfig.NUM_ELEMENTS; // (0, 10), (10, 20)...
+ int to = from + ButtonConfig.NUM_ELEMENTS;
+ buttonConfig = new ButtonConfig(ctx);
+ buttonConfig.fromList(ctx, items.subList(from, to)); // initialize button from list elements
+ buttonList.add(buttonConfig);
+ }
+ return buttonList;
+ }
+
+ public static ArrayList<ButtonConfig> getDefaultConfig(Context ctx, Defaults defaults) {
+ if (ctx == null || defaults == null) {
+ return null;
+ }
+ String config = defaults.getDefaultConfig();
+ ArrayList<String> items = new ArrayList<String>();
+ items.addAll(Arrays.asList(config.split("\\|")));
+ int numConfigs = Integer.parseInt(items.get(0));
+ items.remove(0);
+ ArrayList<ButtonConfig> buttonList = new ArrayList<ButtonConfig>();
+ ButtonConfig buttonConfig;
+
+ for (int i = 0; i < numConfigs; i++) {
+ int from = i * ButtonConfig.NUM_ELEMENTS;
+ int to = from + ButtonConfig.NUM_ELEMENTS;
+ buttonConfig = new ButtonConfig(ctx);
+ buttonConfig.fromList(ctx, items.subList(from, to));
+ buttonList.add(buttonConfig);
+ }
+ return buttonList;
+ }
+
+ public static void setConfig(Context ctx, Defaults defaults, ArrayList<ButtonConfig> config) {
+ if (ctx == null || defaults == null || config == null) {
+ return;
+ }
+ int numConfigs = config.size();
+ if (numConfigs <= 0) {
+ return;
+ }
+ StringBuilder b = new StringBuilder();
+ b.append(String.valueOf(numConfigs));
+ b.append(ActionConstants.ACTION_DELIMITER); // size of list is always first element
+ for (ButtonConfig button : config) {
+ b.append(button.toDelimitedString()); // this is just beautiful ;D
+ }
+ String s = b.toString();
+ if (s.endsWith(ActionConstants.ACTION_DELIMITER)) {
+ s = removeLastChar(s); // trim final delimiter if need be
+ }
+ Settings.Secure.putStringForUser(ctx.getContentResolver(), defaults.getUri(), s,
+ UserHandle.USER_CURRENT);
+ }
+
+ public static ButtonConfig getButtonConfigFromTag(ArrayList<ButtonConfig> configs, String tag) {
+ if (configs == null || tag == null) {
+ return null;
+ }
+ ButtonConfig config = null;
+ for (ButtonConfig b : configs) {
+ if (TextUtils.equals(b.getTag(), tag)) {
+ config = b;
+ break;
+ }
+ }
+ return config;
+ }
+
+ public static ArrayList<ButtonConfig> replaceButtonAtPosition(ArrayList<ButtonConfig> configs,
+ ButtonConfig button, ConfigMap map) {
+ if (configs == null || button == null || map == null) {
+ return null;
+ }
+ configs.remove(map.button);
+ configs.add(map.button, button);
+ return configs;
+ }
+
+ public static String removeLastChar(String s) {
+ if (s == null || s.length() == 0) {
+ return s;
+ }
+ return s.substring(0, s.length() - 1);
+ }
+
+ public static class ButtonConfig implements Stringable, Parcelable {
+ public static final int NUM_ELEMENTS = 10;
+ protected ActionConfig[] configs = new ActionConfig[3];
+ private String tag = ActionConstants.EMPTY;
+
+ // internal use only
+ private ButtonConfig() {
+ }
+
+ public ButtonConfig(Context ctx) {
+ configs[ActionConfig.PRIMARY] = new ActionConfig(ctx);
+ configs[ActionConfig.SECOND] = new ActionConfig(ctx);
+ configs[ActionConfig.THIRD] = new ActionConfig(ctx);
+ }
+
+ public String getTag() {
+ return tag;
+ }
+
+ public void setTag(String tag) {
+ this.tag = tag;
+ }
+
+ public boolean hasCustomIcon() {
+ return configs[ActionConfig.PRIMARY].hasCustomIcon();
+ }
+
+ public void clearCustomIconIconUri() {
+ configs[ActionConfig.PRIMARY].clearCustomIconIconUri();
+ }
+
+ public void setCustomIconUri(String type, String packageName, String iconName) {
+ configs[ActionConfig.PRIMARY].setCustomIconUri(type, packageName, iconName);
+ }
+
+ public void setCustomImageUri(Uri uri) {
+ configs[ActionConfig.PRIMARY].setCustomImageUri(uri);
+ }
+
+ public Drawable getDefaultIcon(Context ctx) {
+ return configs[ActionConfig.PRIMARY].getDefaultIcon(ctx);
+ }
+
+ public Drawable getCurrentIcon(Context ctx) {
+ return configs[ActionConfig.PRIMARY].getCurrentIcon(ctx);
+ }
+
+ public boolean isSystemAction() {
+ return configs[ActionConfig.PRIMARY].isSystemAction();
+ }
+
+ public String getSystemActionIconName() {
+ return configs[ActionConfig.PRIMARY].getSystemActionIconName();
+ }
+
+ public ActionConfig getActionConfig(int which) {
+ if (which < ActionConfig.PRIMARY || which > ActionConfig.THIRD) {
+ return null;
+ }
+ return configs[which];
+ }
+
+ public void setActionConfig(ActionConfig config, int which) {
+ if (which < ActionConfig.PRIMARY || which > ActionConfig.THIRD || config == null) {
+ return;
+ }
+ configs[which] = config;
+ }
+
+ public static void setButton(Context ctx, ButtonConfig button, String uri, boolean isSecure) {
+ StringBuilder b = new StringBuilder();
+ b.append(button.toDelimitedString()); // this is just beautiful ;D
+ String s = b.toString();
+ if (s.endsWith(ActionConstants.ACTION_DELIMITER)) {
+ s = removeLastChar(s); // trim final delimiter if need be
+ }
+
+ if (isSecure) {
+ Settings.Secure.putStringForUser(ctx.getContentResolver(), uri, s,
+ UserHandle.USER_CURRENT);
+ } else {
+ Settings.System.putStringForUser(ctx.getContentResolver(), uri, s,
+ UserHandle.USER_CURRENT);
+ }
+ }
+
+ public static ButtonConfig getButton(Context ctx, String uri, boolean isSecure) {
+ if (ctx == null || TextUtils.isEmpty(uri)) {
+ return null;
+ }
+ String config;
+ if (isSecure) {
+ config = Settings.Secure.getStringForUser(
+ ctx.getContentResolver(), uri,
+ UserHandle.USER_CURRENT);
+ } else {
+ config = Settings.System.getStringForUser(
+ ctx.getContentResolver(), uri,
+ UserHandle.USER_CURRENT);
+ }
+ if (TextUtils.isEmpty(config)) {
+ return new ButtonConfig(ctx);
+ }
+ ArrayList<String> items = new ArrayList<String>();
+ items.addAll(Arrays.asList(config.split("\\|")));
+ ButtonConfig buttonConfig = new ButtonConfig(ctx);
+ buttonConfig.fromList(ctx, items.subList(0, NUM_ELEMENTS)); // initialize button from
+ // list elements
+ return buttonConfig;
+ }
+
+ @Override
+ public String toDelimitedString() {
+ return tag + ActionConstants.ACTION_DELIMITER
+ + configs[ActionConfig.PRIMARY].toDelimitedString()
+ + configs[ActionConfig.SECOND].toDelimitedString()
+ + configs[ActionConfig.THIRD].toDelimitedString();
+ }
+
+ @Override
+ public void fromList(Context ctx, List<String> items) {
+ ArrayList<String> buttons = new ArrayList<String>();
+ buttons.addAll(items);
+ tag = buttons.get(0);
+
+ ActionConfig config = new ActionConfig();
+ config.fromList(ctx, buttons.subList(1, 4));
+ configs[ActionConfig.PRIMARY] = config;
+
+ config = new ActionConfig();
+ config.fromList(ctx, buttons.subList(4, 7));
+ configs[ActionConfig.SECOND] = config;
+
+ config = new ActionConfig();
+ config.fromList(ctx, buttons.subList(7, 10));
+ configs[ActionConfig.THIRD] = config;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(tag);
+ dest.writeParcelable(configs[ActionConfig.PRIMARY], flags);
+ dest.writeParcelable(configs[ActionConfig.SECOND], flags);
+ dest.writeParcelable(configs[ActionConfig.THIRD], flags);
+ }
+
+ public static final Parcelable.Creator<ButtonConfig> CREATOR = new Parcelable.Creator<ButtonConfig>() {
+ public ButtonConfig createFromParcel(Parcel in) {
+ return new ButtonConfig(in);
+ }
+
+ public ButtonConfig[] newArray(int size) {
+ return new ButtonConfig[size];
+ }
+ };
+
+ private ButtonConfig(Parcel in) {
+ tag = in.readString();
+ configs[ActionConfig.PRIMARY] = (ActionConfig) in.readParcelable(Config.ActionConfig.class
+ .getClassLoader());
+ configs[ActionConfig.SECOND] = (ActionConfig) in.readParcelable(Config.ActionConfig.class
+ .getClassLoader());
+ configs[ActionConfig.THIRD] = (ActionConfig) in.readParcelable(Config.ActionConfig.class
+ .getClassLoader());
+ }
+ }
+
+ public static class ActionConfig implements Stringable, Comparable<ActionConfig>, Parcelable {
+ public static final int PRIMARY = 0;
+ public static final int SECOND = 1;
+ public static final int THIRD = 2;
+
+ private String action = ActionHandler.SYSTEMUI_TASK_NO_ACTION;
+ private String label = ActionConstants.EMPTY;
+ private String iconUri = ActionConstants.EMPTY;
+
+ // internal use only
+ private ActionConfig() {
+ }
+
+ public static ActionConfig create(Context ctx) {
+ return new ActionConfig(ctx);
+ }
+
+ public static ActionConfig create(Context ctx, String action) {
+ return new ActionConfig(ctx, action);
+ }
+
+ public static ActionConfig create(Context ctx, String action, String iconUri) {
+ return new ActionConfig(ctx, action, iconUri);
+ }
+
+ public ActionConfig(Context ctx) {
+ label = ActionUtils.getFriendlyNameForUri(ctx, action);
+ }
+
+ public ActionConfig(Context ctx, String action) {
+ this.action = action;
+ label = ActionUtils.getFriendlyNameForUri(ctx, action);
+ }
+
+ public ActionConfig(Context ctx, String action, String iconUri) {
+ this(ctx, action);
+ this.iconUri = iconUri;
+ }
+
+ public String getAction() {
+ return action;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public String getIconUri() {
+ if (!hasCustomIcon()) {
+ return action;
+ } else {
+ return iconUri;
+ }
+ }
+
+ public boolean hasCustomIcon() {
+ return !TextUtils.equals(ActionConstants.EMPTY, iconUri);
+ }
+
+ public void clearCustomIconIconUri() {
+ iconUri = ActionConstants.EMPTY;
+ }
+
+ public boolean isSystemAction() {
+ return action.startsWith(ActionHandler.SYSTEM_PREFIX);
+ }
+
+ public String getSystemActionIconName() {
+ if (action.startsWith(ActionHandler.SYSTEM_PREFIX)) {
+ for (int i = 0; i < ActionHandler.systemActions.length; i++) {
+ if (ActionHandler.systemActions[i].mAction.equals(action)) {
+ return ActionHandler.systemActions[i].mIconRes;
+ }
+ }
+ }
+ return null;
+ }
+
+ public void setCustomImageUri(Uri uri) {
+ iconUri = "image$" + uri.toString();
+ }
+
+ public void setCustomIconUri(String type, String packageName, String iconName) {
+ StringBuilder b = new StringBuilder()
+ .append(type)
+ .append("$")
+ .append(packageName)
+ .append("$")
+ .append(iconName);
+ iconUri = b.toString();
+ }
+
+ public Drawable getDefaultIcon(Context ctx) {
+ return ActionUtils.getDrawableForAction(ctx, action);
+ }
+
+ /**
+ * Returns custom icon (if exists)
+ * @param ctx app's context
+ * @return drawable when custom icon exists, null otherwise
+ */
+ public Drawable getCurrentCustomIcon(Context ctx) {
+ if (hasCustomIcon()) {
+ List<String> items = Arrays.asList(iconUri.split("\\$"));
+ String type = items.get(0);
+ if (type.equals("iconpack") && items.size() == 3) {
+ String packageName = items.get(1);
+ String iconName = items.get(2);
+ return ActionUtils.getDrawable(ctx, iconName, packageName);
+ } else if (type.equals("image") && items.size() == 2) {
+ String uri = items.get(1);
+ return ActionUtils.getDrawable(ctx, Uri.parse(uri));
+ }
+ }
+ return null;
+ }
+
+ public Drawable getCurrentIcon(Context ctx) {
+
+ Drawable drawable = getCurrentCustomIcon(ctx);
+
+ //If icon doesn't exist (or is not set) fallback to action one
+ if (drawable == null) {
+ drawable = ActionUtils.getDrawableForAction(ctx, action);
+ }
+
+ return drawable;
+
+ }
+
+ public boolean hasNoAction() {
+ return TextUtils.equals(action, ActionHandler.SYSTEMUI_TASK_NO_ACTION)
+ || TextUtils.equals(action, ActionConstants.EMPTY);
+ }
+
+ public boolean isActionRecents() {
+ return TextUtils.equals(action, ActionHandler.SYSTEMUI_TASK_RECENTS);
+ }
+
+ @Override
+ public int compareTo(ActionConfig another) {
+ int result = label.toString().compareToIgnoreCase(another.label.toString());
+ return result;
+ }
+
+ @Override
+ public String toDelimitedString() {
+ return action + ActionConstants.ACTION_DELIMITER
+ + label + ActionConstants.ACTION_DELIMITER
+ + iconUri + ActionConstants.ACTION_DELIMITER;
+ }
+
+ @Override
+ public void fromList(Context ctx, List<String> items) {
+ ArrayList<String> actionStrings = new ArrayList<String>();
+ actionStrings.addAll(items);
+ action = items.get(0);
+ label = ActionUtils.getFriendlyNameForUri(ctx, action);
+ iconUri = items.get(2);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(action);
+ dest.writeString(label);
+ dest.writeString(iconUri);
+ }
+
+ public static final Parcelable.Creator<ActionConfig> CREATOR = new Parcelable.Creator<ActionConfig>() {
+ public ActionConfig createFromParcel(Parcel in) {
+ return new ActionConfig(in);
+ }
+
+ public ActionConfig[] newArray(int size) {
+ return new ActionConfig[size];
+ }
+ };
+
+ private ActionConfig(Parcel in) {
+ action = in.readString();
+ label = in.readString();
+ iconUri = in.readString();
+ }
+ }
+}
diff --git a/core/java/com/android/internal/util/hwkeys/ImageHelper.java b/core/java/com/android/internal/util/hwkeys/ImageHelper.java
new file mode 100644
index 0000000..0c802f4
--- /dev/null
+++ b/core/java/com/android/internal/util/hwkeys/ImageHelper.java
@@ -0,0 +1,299 @@
+/*
+* Copyright (C) 2013 SlimRoms Project
+* Copyright (C) 2015 TeamEos Project
+* Copyright (C) 2015-2016 The DirtyUnicorns 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.util.hwkeys;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
+import android.graphics.BitmapFactory;
+import android.graphics.BitmapShader;
+import android.graphics.Canvas;
+import android.graphics.ColorMatrix;
+import android.graphics.ColorMatrixColorFilter;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.PorterDuff.Mode;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.Shader.TileMode;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.VectorDrawable;
+import android.net.Uri;
+import android.os.ParcelFileDescriptor;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.TypedValue;
+import android.util.Xml;
+
+public class ImageHelper {
+ private static final int VECTOR_WIDTH = 512;
+ private static final int VECTOR_HEIGHT = 512;
+
+ public static Drawable getColoredDrawable(Drawable d, int color) {
+ if (d == null) {
+ return null;
+ }
+ if (d instanceof VectorDrawable) {
+ d.setTint(color);
+ return d;
+ }
+ Bitmap colorBitmap = ((BitmapDrawable) d).getBitmap();
+ Bitmap grayscaleBitmap = toGrayscale(colorBitmap);
+ Paint pp = new Paint();
+ pp.setAntiAlias(true);
+ PorterDuffColorFilter frontFilter =
+ new PorterDuffColorFilter(color, Mode.MULTIPLY);
+ pp.setColorFilter(frontFilter);
+ Canvas cc = new Canvas(grayscaleBitmap);
+ final Rect rect = new Rect(0, 0, grayscaleBitmap.getWidth(), grayscaleBitmap.getHeight());
+ cc.drawBitmap(grayscaleBitmap, rect, rect, pp);
+ return new BitmapDrawable(grayscaleBitmap);
+ }
+
+ public static Bitmap drawableToBitmap (Drawable drawable) {
+ if (drawable == null) {
+ return null;
+ } else if (drawable instanceof BitmapDrawable) {
+ return ((BitmapDrawable) drawable).getBitmap();
+ }
+ Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
+ drawable.getIntrinsicHeight(), Config.ARGB_8888);
+ Canvas canvas = new Canvas(bitmap);
+ drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
+ drawable.draw(canvas);
+ return bitmap;
+ }
+
+ public static Bitmap getColoredBitmap(Drawable d, int color) {
+ if (d == null) {
+ return null;
+ }
+ Bitmap colorBitmap = ((BitmapDrawable) d).getBitmap();
+ Bitmap grayscaleBitmap = toGrayscale(colorBitmap);
+ Paint pp = new Paint();
+ pp.setAntiAlias(true);
+ PorterDuffColorFilter frontFilter =
+ new PorterDuffColorFilter(color, Mode.MULTIPLY);
+ pp.setColorFilter(frontFilter);
+ Canvas cc = new Canvas(grayscaleBitmap);
+ final Rect rect = new Rect(0, 0, grayscaleBitmap.getWidth(), grayscaleBitmap.getHeight());
+ cc.drawBitmap(grayscaleBitmap, rect, rect, pp);
+ return grayscaleBitmap;
+ }
+
+ private static Bitmap toGrayscale(Bitmap bmpOriginal) {
+ int width, height;
+ height = bmpOriginal.getHeight();
+ width = bmpOriginal.getWidth();
+
+ Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+ Canvas c = new Canvas(bmpGrayscale);
+ Paint paint = new Paint();
+ paint.setAntiAlias(true);
+ ColorMatrix cm = new ColorMatrix();
+ final Rect rect = new Rect(0, 0, width, height);
+ cm.setSaturation(0);
+
+ ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
+ paint.setColorFilter(f);
+ c.drawBitmap(bmpOriginal, rect, rect, paint);
+ return bmpGrayscale;
+ }
+
+ public static Drawable resize(Context context, Drawable image, int size) {
+ if (image == null || context == null) {
+ return null;
+ }
+ if (image instanceof VectorDrawable) {
+ return image;
+ } else {
+ int newSize = ActionUtils.dpToPx(context, size);
+ Bitmap bitmap = ((BitmapDrawable) image).getBitmap();
+ Bitmap scaledBitmap = Bitmap.createBitmap(newSize, newSize, Config.ARGB_8888);
+
+ float ratioX = newSize / (float) bitmap.getWidth();
+ float ratioY = newSize / (float) bitmap.getHeight();
+ float middleX = newSize / 2.0f;
+ float middleY = newSize / 2.0f;
+
+ final Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);
+ paint.setAntiAlias(true);
+
+ Matrix scaleMatrix = new Matrix();
+ scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);
+
+ Canvas canvas = new Canvas(scaledBitmap);
+ canvas.setMatrix(scaleMatrix);
+ canvas.drawBitmap(bitmap, middleX - bitmap.getWidth() / 2,
+ middleY - bitmap.getHeight() / 2, paint);
+ return new BitmapDrawable(context.getResources(), scaledBitmap);
+ }
+ }
+
+ public static Bitmap getRoundedCornerBitmap(Bitmap bitmap) {
+ if (bitmap == null) {
+ return null;
+ }
+ Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(),
+ Config.ARGB_8888);
+ Canvas canvas = new Canvas(output);
+
+ final int color = 0xff424242;
+ final Paint paint = new Paint();
+ final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
+ final RectF rectF = new RectF(rect);
+ final float roundPx = 24;
+ paint.setAntiAlias(true);
+ canvas.drawARGB(0, 0, 0, 0);
+ paint.setColor(color);
+ canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
+ paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
+ canvas.drawBitmap(bitmap, rect, rect, paint);
+ return output;
+ }
+
+ public static Bitmap getCircleBitmap(Bitmap bitmap) {
+ if (bitmap == null) {
+ return null;
+ }
+ int width = bitmap.getWidth();
+ int height = bitmap.getHeight();
+
+ Bitmap output = Bitmap.createBitmap(width, height,
+ Config.ARGB_8888);
+ Canvas canvas = new Canvas(output);
+
+ BitmapShader shader = new BitmapShader(bitmap, TileMode.CLAMP, TileMode.CLAMP);
+ final Paint paint = new Paint();
+ paint.setAntiAlias(true);
+ paint.setShader(shader);
+
+ canvas.drawCircle(width/2, height/2, width/2, paint);
+
+ return output;
+ }
+
+ public static Drawable getVector(Resources res, int resId) {
+ return getVector(res, resId, 0, 0, false);
+ }
+
+ public static Drawable getVector(Resources res, int resId, int width, int height) {
+ return getVector(res, resId, width, height, false);
+ }
+
+ public static Drawable getVector(Resources res, int resId, boolean toBitmapDrawable) {
+ return getVector(res, resId, 0, 0, toBitmapDrawable);
+ }
+
+ public static Drawable getVector(Resources res, int resId, int width, int height,
+ boolean toBitmapDrawable) {
+ if (width <= 0) {
+ width = VECTOR_WIDTH;
+ }
+ if (height <= 0) {
+ width = VECTOR_HEIGHT;
+ }
+
+ VectorDrawable vectorDrawable = new VectorDrawable();
+ vectorDrawable.setBounds(0, 0, width, height);
+ try {
+ XmlPullParser parser = res.getXml(resId);
+ AttributeSet attrs = Xml.asAttributeSet(parser);
+
+ int type;
+ while ((type = parser.next()) != XmlPullParser.START_TAG &&
+ type != XmlPullParser.END_DOCUMENT) {
+ // Empty loop
+ }
+
+ if (type != XmlPullParser.START_TAG) {
+// Log.e("ImageHelper VectorLoader", "No start tag found");
+ }
+
+ vectorDrawable.inflate(res, parser, attrs);
+
+ if (!toBitmapDrawable) {
+ return vectorDrawable;
+ }
+
+ return new BitmapDrawable(res, drawableToBitmap(vectorDrawable));
+ } catch (Exception e) {
+// Log.e("ImageHelper VectorLoader", "Error loading resource ID " + String.valueOf(resId) + " Try loading as a non vector");
+ return null;
+ }
+ }
+
+ /**
+ * @param context callers context
+ * @param uri Uri to handle
+ * @return A bitmap from the requested uri
+ * @throws IOException
+ *
+ * @Credit: StackOverflow
+ * http://stackoverflow.com/questions/35909008/pick-image
+ * -from-gallery-or-google-photos-failing
+ */
+ public static Bitmap getBitmapFromUri(Context context, Uri uri) throws IOException {
+ if (context == null || uri == null) {
+ return null;
+ }
+ ParcelFileDescriptor parcelFileDescriptor =
+ context.getContentResolver().openFileDescriptor(uri, "r");
+ FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
+ Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
+ parcelFileDescriptor.close();
+ return image;
+ }
+
+ /**
+ * @param storageDir Desired location in storage as a File
+ * @param fileName Name of bitmap file to store
+ * @param bitmap the bitmap to store
+ * @return the Uri of the bitmap
+ */
+ public static Uri addBitmapToStorage(File storageDir, String fileName, Bitmap bitmap) {
+ if (storageDir == null || fileName == null || bitmap == null) {
+ return null;
+ }
+ File imageFile = new File(storageDir, fileName);
+ try {
+ FileOutputStream fos = new FileOutputStream(imageFile);
+ bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
+ fos.flush();
+ fos.close();
+ } catch (Exception e) {
+ return null;
+ }
+ return Uri.fromFile(imageFile);
+ }
+}
diff --git a/core/java/com/android/internal/util/hwkeys/PackageMonitor.java b/core/java/com/android/internal/util/hwkeys/PackageMonitor.java
new file mode 100644
index 0000000..8b1c688
--- /dev/null
+++ b/core/java/com/android/internal/util/hwkeys/PackageMonitor.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2015-2016 The TeamEos Project
+ *
+ * Author: Randall Rushing <bigrushdog@teameos.org>
+ *
+ * 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.
+ *
+ * A simplified package monitor class with easy-to-use callbacks when a
+ * state changes. We register the receiver on background thread but post events
+ * to the UI thread
+ */
+
+package com.android.internal.util.hwkeys;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.Message;
+
+import java.util.ArrayList;
+
+public class PackageMonitor extends com.android.internal.content.PackageMonitor {
+ private static final int MSG_PACKAGE_ADDED = 1;
+ private static final int MSG_PACKAGE_REMOVED = 2;
+ private static final int MSG_PACKAGE_CHANGED = 3;
+
+ public static enum PackageState {
+ PACKAGE_REMOVED,
+ PACKAGE_ADDED,
+ PACKAGE_CHANGED
+ }
+
+ public interface PackageChangedListener {
+ public void onPackageChanged(String pkg, PackageState state);
+ }
+
+ private Handler mHandler;
+
+ private ArrayList<PackageChangedListener> mListeners = new ArrayList<PackageChangedListener>();
+
+ public void register(Context context, Handler foreground) {
+ register(context, null, null, true);
+
+ mHandler = new Handler(foreground.getLooper()) {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_PACKAGE_ADDED:
+ for (PackageChangedListener listener : mListeners) {
+ listener.onPackageChanged((String) msg.obj, PackageState.PACKAGE_ADDED);
+ }
+ break;
+ case MSG_PACKAGE_REMOVED:
+ for (PackageChangedListener listener : mListeners) {
+ listener.onPackageChanged((String) msg.obj,
+ PackageState.PACKAGE_REMOVED);
+ }
+ break;
+ case MSG_PACKAGE_CHANGED:
+ for (PackageChangedListener listener : mListeners) {
+ listener.onPackageChanged((String) msg.obj,
+ PackageState.PACKAGE_CHANGED);
+ }
+ break;
+ }
+ }
+ };
+ }
+
+ public void addListener(PackageChangedListener listener) {
+ if (listener != null) {
+ mListeners.add(listener);
+ }
+ }
+
+ public void removeListener(PackageChangedListener listener) {
+ if (listener != null) {
+ mListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Called when a package is really added (and not replaced).
+ */
+ public void onPackageAdded(String packageName, int uid) {
+ Message msg = mHandler.obtainMessage(MSG_PACKAGE_ADDED, packageName);
+ mHandler.sendMessage(msg);
+ }
+
+ /**
+ * Called when a package is really removed (and not replaced).
+ */
+ public void onPackageRemoved(String packageName, int uid) {
+ Message msg = mHandler.obtainMessage(MSG_PACKAGE_REMOVED, packageName);
+ mHandler.sendMessage(msg);
+ }
+
+ /**
+ * Direct reflection of {@link Intent#ACTION_PACKAGE_CHANGED Intent.ACTION_PACKAGE_CHANGED}
+ * being received, informing you of changes to the enabled/disabled state of components in a
+ * package and/or of the overall package.
+ *
+ * @param packageName The name of the package that is changing.
+ * @param uid The user ID the package runs under.
+ * @param components Any components in the package that are changing. If the overall package is
+ * changing, this will contain an entry of the package name itself.
+ * @return Return true to indicate you care about this change, which will result in
+ * {@link #onSomePackagesChanged()} being called later. If you return false, no further
+ * callbacks will happen about this change. The default implementation returns true if
+ * this is a change to the entire package.
+ */
+ public boolean onPackageChanged(String packageName, int uid, String[] components) {
+ Message msg = mHandler.obtainMessage(MSG_PACKAGE_CHANGED, packageName);
+ mHandler.sendMessage(msg);
+ return super.onPackageChanged(packageName, uid, components);
+ }
+}
diff --git a/core/java/com/android/internal/util/hwkeys/SystemReceiver.java b/core/java/com/android/internal/util/hwkeys/SystemReceiver.java
new file mode 100644
index 0000000..f817563
--- /dev/null
+++ b/core/java/com/android/internal/util/hwkeys/SystemReceiver.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2015-2016 The TeamEos Project
+ *
+ * Author: Randall Rushing <bigrushdog@teameos.org>
+ *
+ * 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.
+ *
+ * A BroadcastReceiver that filters out broadcasts from non-system
+ * related processes. Subclasses can allow additional broadcasting
+ * packages by overriding onExemptBroadcast(Context context, String packageName)
+ */
+
+package com.android.internal.util.hwkeys;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+public abstract class SystemReceiver extends BroadcastReceiver {
+
+ protected abstract void onSecureReceive(Context context, Intent intent);
+
+ protected boolean onExemptBroadcast(Context context, String packageName) {
+ return false;
+ }
+
+ @Override
+ public final void onReceive(Context context, Intent intent) {
+ if (context == null || intent == null) {
+ return;
+ }
+ if (isBroadcastFromSystem(context)) {
+ onSecureReceive(context, intent);
+ }
+ }
+
+ private boolean isBroadcastFromSystem(Context context) {
+ String packageName = context.getPackageName();
+ if (packageName == null
+ && android.os.Process.SYSTEM_UID == context.getApplicationInfo().uid) {
+ packageName = "android";
+ }
+ if (packageName == null) {
+ return false;
+ }
+ if (packageName.equals("com.android.systemui")
+ || packageName.equals("com.android.keyguard")
+ || packageName.equals("com.android.settings")
+ || packageName.equals("android")
+ || context.getApplicationInfo().uid == android.os.Process.SYSTEM_UID) {
+ return true;
+ }
+ if (onExemptBroadcast(context, packageName)) {
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl
index e35fda1..11657dd 100644
--- a/core/java/com/android/internal/widget/ILockSettings.aidl
+++ b/core/java/com/android/internal/widget/ILockSettings.aidl
@@ -93,4 +93,6 @@
boolean hasSecureLockScreen();
boolean tryUnlockWithCachedUnifiedChallenge(int userId);
void removeCachedUnifiedChallenge(int userId);
+ void sanitizePassword();
+ String getPassword();
}
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 93690cd..453bdc3 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -383,7 +383,6 @@
*/
public byte[] verifyCredential(@NonNull LockscreenCredential credential, long challenge,
int userId) throws RequestThrottledException {
- throwIfCalledOnMainThread();
try {
VerifyCredentialResponse response = getLockSettings().verifyCredential(
credential, challenge, userId);
@@ -414,7 +413,6 @@
public boolean checkCredential(@NonNull LockscreenCredential credential, int userId,
@Nullable CheckCredentialProgressCallback progressCallback)
throws RequestThrottledException {
- throwIfCalledOnMainThread();
try {
VerifyCredentialResponse response = getLockSettings().checkCredential(
credential, userId, wrapCallback(progressCallback));
@@ -448,7 +446,6 @@
*/
public byte[] verifyTiedProfileChallenge(@NonNull LockscreenCredential credential,
long challenge, int userId) throws RequestThrottledException {
- throwIfCalledOnMainThread();
try {
VerifyCredentialResponse response =
getLockSettings().verifyTiedProfileChallenge(credential, challenge, userId);
@@ -672,6 +669,17 @@
reportEnabledTrustAgentsChanged(userHandle);
}
+ /**
+ * clears stored password.
+ */
+ public void sanitizePassword() {
+ try {
+ getLockSettings().sanitizePassword();
+ } catch (RemoteException re) {
+ Log.e(TAG, "Couldn't sanitize password" + re);
+ }
+ }
+
private void updateCryptoUserInfo(int userId) {
if (userId != UserHandle.USER_SYSTEM) {
return;
@@ -1208,7 +1216,8 @@
return deadline;
}
- private boolean getBoolean(String secureSettingKey, boolean defaultValue, int userId) {
+ /** @hide */
+ protected boolean getBoolean(String secureSettingKey, boolean defaultValue, int userId) {
try {
return getLockSettings().getBoolean(secureSettingKey, defaultValue, userId);
} catch (RemoteException re) {
@@ -1216,7 +1225,8 @@
}
}
- private void setBoolean(String secureSettingKey, boolean enabled, int userId) {
+ /** @hide */
+ protected void setBoolean(String secureSettingKey, boolean enabled, int userId) {
try {
getLockSettings().setBoolean(secureSettingKey, enabled, userId);
} catch (RemoteException re) {
@@ -1225,7 +1235,8 @@
}
}
- private long getLong(String secureSettingKey, long defaultValue, int userHandle) {
+ /** @hide */
+ protected long getLong(String secureSettingKey, long defaultValue, int userHandle) {
try {
return getLockSettings().getLong(secureSettingKey, defaultValue, userHandle);
} catch (RemoteException re) {
@@ -1233,8 +1244,9 @@
}
}
+ /** @hide */
@UnsupportedAppUsage
- private void setLong(String secureSettingKey, long value, int userHandle) {
+ protected void setLong(String secureSettingKey, long value, int userHandle) {
try {
getLockSettings().setLong(secureSettingKey, value, userHandle);
} catch (RemoteException re) {
@@ -1243,8 +1255,9 @@
}
}
+ /** @hide */
@UnsupportedAppUsage
- private String getString(String secureSettingKey, int userHandle) {
+ protected String getString(String secureSettingKey, int userHandle) {
try {
return getLockSettings().getString(secureSettingKey, null, userHandle);
} catch (RemoteException re) {
@@ -1252,8 +1265,9 @@
}
}
+ /** @hide */
@UnsupportedAppUsage
- private void setString(String secureSettingKey, String value, int userHandle) {
+ protected void setString(String secureSettingKey, String value, int userHandle) {
try {
getLockSettings().setString(secureSettingKey, value, userHandle);
} catch (RemoteException re) {
@@ -1361,12 +1375,6 @@
return isCredentialRequiredToDecrypt(defaultValue) && !isDoNotAskCredentialsOnBootSet();
}
- private void throwIfCalledOnMainThread() {
- if (Looper.getMainLooper().isCurrentThread()) {
- throw new IllegalStateException("should not be called from the main thread.");
- }
- }
-
public void registerStrongAuthTracker(final StrongAuthTracker strongAuthTracker) {
try {
getLockSettings().registerStrongAuthTracker(strongAuthTracker.getStub());
diff --git a/core/java/com/android/internal/widget/PointerLocationView.java b/core/java/com/android/internal/widget/PointerLocationView.java
index dc8d57a..a2de0af 100644
--- a/core/java/com/android/internal/widget/PointerLocationView.java
+++ b/core/java/com/android/internal/widget/PointerLocationView.java
@@ -371,7 +371,7 @@
}
if (haveLast) {
canvas.drawLine(lastX, lastY, x, y, mPathPaint);
- final Paint paint = ps.mTraceCurrent[i] ? mCurrentPointPaint : mPaint;
+ final Paint paint = ps.mTraceCurrent[i - 1] ? mCurrentPointPaint : mPaint;
canvas.drawPoint(lastX, lastY, paint);
drawn = true;
}
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index bc69735..d394f5d 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -470,6 +470,56 @@
}
}
+static void android_hardware_Camera_setLongshot(JNIEnv *env, jobject thiz, jboolean enable)
+{
+ ALOGV("setLongshot");
+ JNICameraContext* context;
+ status_t rc;
+ sp<Camera> camera = get_native_camera(env, thiz, &context);
+ if (camera == 0) return;
+
+ if ( enable ) {
+ rc = camera->sendCommand(CAMERA_CMD_LONGSHOT_ON, 0, 0);
+ } else {
+ rc = camera->sendCommand(CAMERA_CMD_LONGSHOT_OFF, 0, 0);
+ }
+
+ if (rc != NO_ERROR) {
+ jniThrowException(env, "java/lang/RuntimeException", "enabling longshot mode failed");
+ }
+}
+
+static void android_hardware_Camera_sendHistogramData(JNIEnv *env, jobject thiz)
+ {
+ ALOGV("sendHistogramData" );
+ JNICameraContext* context;
+ status_t rc;
+ sp<Camera> camera = get_native_camera(env, thiz, &context);
+ if (camera == 0) return;
+
+ rc = camera->sendCommand(CAMERA_CMD_HISTOGRAM_SEND_DATA, 0, 0);
+
+ if (rc != NO_ERROR) {
+ jniThrowException(env, "java/lang/RuntimeException", "send histogram data failed");
+ }
+ }
+ static void android_hardware_Camera_setHistogramMode(JNIEnv *env, jobject thiz, jboolean mode)
+ {
+ ALOGV("setHistogramMode: mode:%d", (int)mode);
+ JNICameraContext* context;
+ status_t rc;
+ sp<Camera> camera = get_native_camera(env, thiz, &context);
+ if (camera == 0) return;
+
+ if(mode == true)
+ rc = camera->sendCommand(CAMERA_CMD_HISTOGRAM_ON, 0, 0);
+ else
+ rc = camera->sendCommand(CAMERA_CMD_HISTOGRAM_OFF, 0, 0);
+
+ if (rc != NO_ERROR) {
+ jniThrowException(env, "java/lang/RuntimeException", "set histogram mode failed");
+ }
+ }
void JNICameraContext::addCallbackBuffer(
JNIEnv *env, jbyteArray cbb, int msgType)
{
@@ -793,7 +843,25 @@
context->setCallbackMode(env, installed, manualBuffer);
}
-static void android_hardware_Camera_addCallbackBuffer(JNIEnv *env, jobject thiz, jbyteArray bytes, jint msgType) {
+static void android_hardware_Camera_setMetadataCb(JNIEnv *env, jobject thiz, jboolean mode)
+{
+ ALOGV("setMetadataCb: mode:%d", (int)mode);
+ JNICameraContext* context;
+ status_t rc;
+ sp<Camera> camera = get_native_camera(env, thiz, &context);
+ if (camera == 0) return;
+
+ if(mode == true)
+ rc = camera->sendCommand(CAMERA_CMD_METADATA_ON, 0, 0);
+ else
+ rc = camera->sendCommand(CAMERA_CMD_METADATA_OFF, 0, 0);
+
+ if (rc != NO_ERROR) {
+ jniThrowException(env, "java/lang/RuntimeException", "set metadata mode failed");
+ }
+}
+
+static void android_hardware_Camera_addCallbackBuffer(JNIEnv *env, jobject thiz, jbyteArray bytes, int msgType) {
ALOGV("addCallbackBuffer: 0x%x", msgType);
JNICameraContext* context = reinterpret_cast<JNICameraContext*>(env->GetLongField(thiz, fields.context));
@@ -1061,7 +1129,7 @@
//-------------------------------------------------
static const JNINativeMethod camMethods[] = {
- { "getNumberOfCameras",
+ { "_getNumberOfCameras",
"()I",
(void *)android_hardware_Camera_getNumberOfCameras },
{ "_getCameraInfo",
@@ -1106,6 +1174,18 @@
{ "native_takePicture",
"(I)V",
(void *)android_hardware_Camera_takePicture },
+ { "native_setHistogramMode",
+ "(Z)V",
+ (void *)android_hardware_Camera_setHistogramMode },
+ { "native_setMetadataCb",
+ "(Z)V",
+ (void *)android_hardware_Camera_setMetadataCb },
+ { "native_sendHistogramData",
+ "()V",
+ (void *)android_hardware_Camera_sendHistogramData },
+ { "native_setLongshot",
+ "(Z)V",
+ (void *)android_hardware_Camera_setLongshot },
{ "native_setParameters",
"(Ljava/lang/String;)V",
(void *)android_hardware_Camera_setParameters },
diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto
index cfd428c..0e1f16c 100644
--- a/core/proto/android/providers/settings/secure.proto
+++ b/core/proto/android/providers/settings/secure.proto
@@ -570,7 +570,7 @@
option (android.msg_privacy).dest = DEST_EXPLICIT;
// What behavior should be invoked when the volume hush gesture is triggered
- // One of VOLUME_HUSH_OFF, VOLUME_HUSH_VIBRATE, VOLUME_HUSH_MUTE.
+ // One of VOLUME_HUSH_OFF, VOLUME_HUSH_VIBRATE, VOLUME_HUSH_MUTE, VOLUME_HUSH_MUTE_NO_MEDIA.
optional SettingProto hush_gesture = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
// Persisted playback time after a user confirmation of an unsafe volume level.
optional SettingProto unsafe_volume_music_active_ms = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 0992379..0c9fa95 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -162,6 +162,7 @@
<protected-broadcast android:name="android.bluetooth.device.action.BATTERY_LEVEL_CHANGED" />
<protected-broadcast android:name="android.bluetooth.devicepicker.action.LAUNCH" />
<protected-broadcast android:name="android.bluetooth.devicepicker.action.DEVICE_SELECTED" />
+ <protected-broadcast android:name="org.codeaurora.intent.bluetooth.action.REMOTE_ISSUE_OCCURRED" />
<protected-broadcast
android:name="android.bluetooth.headset.profile.action.CONNECTION_STATE_CHANGED" />
<protected-broadcast
@@ -173,6 +174,8 @@
<protected-broadcast
android:name="android.bluetooth.headset.profile.action.ACTIVE_DEVICE_CHANGED" />
<protected-broadcast
+ android:name="android.bluetooth.headset.action.HF_TWSP_BATTERY_STATE_CHANGED" />
+ <protected-broadcast
android:name="android.bluetooth.headsetclient.profile.action.CONNECTION_STATE_CHANGED" />
<protected-broadcast
android:name="android.bluetooth.headsetclient.profile.action.AUDIO_STATE_CHANGED" />
@@ -996,7 +999,6 @@
<permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"
android:permissionGroup="android.permission-group.UNDEFINED"
android:label="@string/permlab_accessBackgroundLocation"
- android:permissionFlags="hardRestricted"
android:description="@string/permdesc_accessBackgroundLocation"
android:protectionLevel="dangerous|instant" />
@@ -4181,6 +4183,11 @@
<permission android:name="android.permission.REGISTER_STATS_PULL_ATOM"
android:protectionLevel="signature|privileged" />
+ <!-- @hide Allows an application to reset the device battery statistics -->
+ <permission android:name="android.permission.RESET_BATTERY_STATS"
+ android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
+ android:protectionLevel="signature|system|development" />
+
<!-- @SystemApi Allows an application to control the backup and restore process.
<p>Not for use by third-party applications.
@hide pending API council -->
@@ -5055,6 +5062,14 @@
<!-- Feature Id for Twilight service. -->
<attribution android:tag="TwilightService" android:label="@string/twilight_service"/>
+ <!-- LineageOS additions -->
+
+ <!-- Allows an application to override the power key action
+ @hide <p>Not for use by third-party applications.
+ -->
+ <permission android:name="android.permission.PREVENT_POWER_KEY"
+ android:protectionLevel="signature|privileged" />
+
<application android:process="system"
android:persistent="true"
android:hasCode="false"
diff --git a/core/res/res/anim/activity_close_exit.xml b/core/res/res/anim/activity_close_exit.xml
index 1599ae8..514560f 100644
--- a/core/res/res/anim/activity_close_exit.xml
+++ b/core/res/res/anim/activity_close_exit.xml
@@ -18,6 +18,7 @@
-->
<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:hasRoundedCorners="true"
android:shareInterpolator="false"
android:zAdjustment="top">
<alpha
diff --git a/core/res/res/anim/activity_open_enter.xml b/core/res/res/anim/activity_open_enter.xml
index 38d3e8ed..68c0221 100644
--- a/core/res/res/anim/activity_open_enter.xml
+++ b/core/res/res/anim/activity_open_enter.xml
@@ -17,6 +17,7 @@
-->
<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:hasRoundedCorners="true"
android:shareInterpolator="false">
<alpha
android:fromAlpha="0"
diff --git a/core/res/res/anim/custom_app_in.xml b/core/res/res/anim/custom_app_in.xml
new file mode 100644
index 0000000..fb7c22f
--- /dev/null
+++ b/core/res/res/anim/custom_app_in.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ >
+
+ <translate android:fromXDelta="0%" android:toXDelta="-35%"
+ android:zAdjustment="bottom"
+ android:duration="@android:integer/config_shortAnimTime"
+ android:interpolator="@android:interpolator/fast_out_linear_in"
+ />
+ <scale android:fromXScale="0.80" android:toXScale="1.0"
+ android:fromYScale="0.80" android:toYScale="1.0"
+ android:pivotX="50%" android:pivotY="50%"
+ android:duration="@android:integer/config_shortAnimTime"
+ android:interpolator="@android:interpolator/linear"
+ />
+ <translate android:fromXDelta="-35%" android:toXDelta="35%"
+ android:zAdjustment="top"
+ android:startOffset="@android:integer/config_shortAnimTime"
+ android:duration="@android:integer/config_shortAnimTime"
+ android:interpolator="@android:interpolator/linear_out_slow_in"
+ />
+ <alpha android:fromAlpha="0.6" android:toAlpha="1.0"
+ android:duration="@android:integer/config_shortAnimTime"
+ android:interpolator="@android:interpolator/linear"
+ />
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/custom_app_out.xml b/core/res/res/anim/custom_app_out.xml
new file mode 100644
index 0000000..ef04252
--- /dev/null
+++ b/core/res/res/anim/custom_app_out.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ >
+
+ <translate android:fromXDelta="-35%" android:toXDelta="35%"
+ android:zAdjustment="top"
+ android:duration="@android:integer/config_shortAnimTime"
+ android:interpolator="@android:interpolator/fast_out_linear_in"
+ />
+ <scale android:fromXScale="1.0" android:toXScale="0.80"
+ android:fromYScale="1.0" android:toYScale="0.80"
+ android:pivotX="50%" android:pivotY="50%"
+ android:duration="@android:integer/config_shortAnimTime"
+ android:interpolator="@android:interpolator/linear"
+ />
+ <translate android:fromXDelta="35%" android:toXDelta="-35%"
+ android:zAdjustment="bottom"
+ android:startOffset="@android:integer/config_shortAnimTime"
+ android:duration="@android:integer/config_shortAnimTime"
+ android:interpolator="@android:interpolator/linear_out_slow_in"
+ />
+ <alpha android:fromAlpha="1.0" android:toAlpha="0.6"
+ android:duration="@android:integer/config_shortAnimTime"
+ android:interpolator="@android:interpolator/linear"
+ />
+</set>
\ No newline at end of file
diff --git a/core/res/res/drawable-hdpi/numberpicker_selection_divider.9.png b/core/res/res/drawable-hdpi/numberpicker_selection_divider.9.png
index c9c72ba..4e7eb8a 100644
--- a/core/res/res/drawable-hdpi/numberpicker_selection_divider.9.png
+++ b/core/res/res/drawable-hdpi/numberpicker_selection_divider.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_usb.png b/core/res/res/drawable-hdpi/stat_sys_data_usb.png
deleted file mode 100644
index f14f908..0000000
--- a/core/res/res/drawable-hdpi/stat_sys_data_usb.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_upload_anim1.png b/core/res/res/drawable-hdpi/stat_sys_upload_anim1.png
index 3a9031e..c27f30b 100644
--- a/core/res/res/drawable-hdpi/stat_sys_upload_anim1.png
+++ b/core/res/res/drawable-hdpi/stat_sys_upload_anim1.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_upload_anim2.png b/core/res/res/drawable-hdpi/stat_sys_upload_anim2.png
index 39d2c95f..65cfe84 100644
--- a/core/res/res/drawable-hdpi/stat_sys_upload_anim2.png
+++ b/core/res/res/drawable-hdpi/stat_sys_upload_anim2.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_data_usb.png b/core/res/res/drawable-ldpi/stat_sys_data_usb.png
deleted file mode 100644
index ffaccbd..0000000
--- a/core/res/res/drawable-ldpi/stat_sys_data_usb.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_selection_divider.9.png b/core/res/res/drawable-mdpi/numberpicker_selection_divider.9.png
index 076fc16..97d250f 100644
--- a/core/res/res/drawable-mdpi/numberpicker_selection_divider.9.png
+++ b/core/res/res/drawable-mdpi/numberpicker_selection_divider.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_data_usb.png b/core/res/res/drawable-mdpi/stat_sys_data_usb.png
deleted file mode 100644
index 40d77f0..0000000
--- a/core/res/res/drawable-mdpi/stat_sys_data_usb.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_upload_anim1.png b/core/res/res/drawable-mdpi/stat_sys_upload_anim1.png
index 217ea4e..09982a9 100644
--- a/core/res/res/drawable-mdpi/stat_sys_upload_anim1.png
+++ b/core/res/res/drawable-mdpi/stat_sys_upload_anim1.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_upload_anim2.png b/core/res/res/drawable-mdpi/stat_sys_upload_anim2.png
index b9c364c..ed9033f 100644
--- a/core/res/res/drawable-mdpi/stat_sys_upload_anim2.png
+++ b/core/res/res/drawable-mdpi/stat_sys_upload_anim2.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/numberpicker_selection_divider.9.png b/core/res/res/drawable-xhdpi/numberpicker_selection_divider.9.png
index 97eb5fe..a893b57 100644
--- a/core/res/res/drawable-xhdpi/numberpicker_selection_divider.9.png
+++ b/core/res/res/drawable-xhdpi/numberpicker_selection_divider.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_sys_data_usb.png b/core/res/res/drawable-xhdpi/stat_sys_data_usb.png
deleted file mode 100644
index 57c1099..0000000
--- a/core/res/res/drawable-xhdpi/stat_sys_data_usb.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_sys_upload_anim1.png b/core/res/res/drawable-xhdpi/stat_sys_upload_anim1.png
index e443f45..b4782e9 100644
--- a/core/res/res/drawable-xhdpi/stat_sys_upload_anim1.png
+++ b/core/res/res/drawable-xhdpi/stat_sys_upload_anim1.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_sys_upload_anim2.png b/core/res/res/drawable-xhdpi/stat_sys_upload_anim2.png
index cd0ca73..677d429 100644
--- a/core/res/res/drawable-xhdpi/stat_sys_upload_anim2.png
+++ b/core/res/res/drawable-xhdpi/stat_sys_upload_anim2.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/numberpicker_selection_divider.9.png b/core/res/res/drawable-xxhdpi/numberpicker_selection_divider.9.png
index b7a9940..3b6fa1a 100644
--- a/core/res/res/drawable-xxhdpi/numberpicker_selection_divider.9.png
+++ b/core/res/res/drawable-xxhdpi/numberpicker_selection_divider.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_data_usb.png b/core/res/res/drawable-xxhdpi/stat_sys_data_usb.png
deleted file mode 100644
index 7fcf5cd..0000000
--- a/core/res/res/drawable-xxhdpi/stat_sys_data_usb.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_upload_anim1.png b/core/res/res/drawable-xxhdpi/stat_sys_upload_anim1.png
index b828430..7a7c63f 100644
--- a/core/res/res/drawable-xxhdpi/stat_sys_upload_anim1.png
+++ b/core/res/res/drawable-xxhdpi/stat_sys_upload_anim1.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_upload_anim2.png b/core/res/res/drawable-xxhdpi/stat_sys_upload_anim2.png
index 39dd3b8..9b46812 100644
--- a/core/res/res/drawable-xxhdpi/stat_sys_upload_anim2.png
+++ b/core/res/res/drawable-xxhdpi/stat_sys_upload_anim2.png
Binary files differ
diff --git a/core/res/res/drawable/ic_link.xml b/core/res/res/drawable/ic_link.xml
new file mode 100644
index 0000000..97322a4
--- /dev/null
+++ b/core/res/res/drawable/ic_link.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24.0dp"
+ android:height="24.0dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"/>
+</vector>
diff --git a/core/res/res/drawable/progress_large.xml b/core/res/res/drawable/progress_large.xml
index 4f016bc..44b4103 100644
--- a/core/res/res/drawable/progress_large.xml
+++ b/core/res/res/drawable/progress_large.xml
@@ -21,5 +21,5 @@
android:drawable="@drawable/spinner_black_76"
android:pivotX="50%"
android:pivotY="50%"
- android:framesCount="12"
- android:frameDuration="100" />
+ android:framesCount="48"
+ android:frameDuration="25" />
diff --git a/core/res/res/drawable/progress_large_white.xml b/core/res/res/drawable/progress_large_white.xml
index c690ed4..6c2388c 100644
--- a/core/res/res/drawable/progress_large_white.xml
+++ b/core/res/res/drawable/progress_large_white.xml
@@ -21,5 +21,5 @@
android:drawable="@drawable/spinner_white_76"
android:pivotX="50%"
android:pivotY="50%"
- android:framesCount="12"
- android:frameDuration="100" />
+ android:framesCount="48"
+ android:frameDuration="25" />
diff --git a/core/res/res/drawable/progress_medium.xml b/core/res/res/drawable/progress_medium.xml
index eb1bd50..82ad686 100644
--- a/core/res/res/drawable/progress_medium.xml
+++ b/core/res/res/drawable/progress_medium.xml
@@ -21,5 +21,5 @@
android:drawable="@drawable/spinner_black_48"
android:pivotX="50%"
android:pivotY="50%"
- android:framesCount="12"
- android:frameDuration="100" />
+ android:framesCount="48"
+ android:frameDuration="25" />
diff --git a/core/res/res/drawable/progress_medium_white.xml b/core/res/res/drawable/progress_medium_white.xml
index b4f9b31..886ee05 100644
--- a/core/res/res/drawable/progress_medium_white.xml
+++ b/core/res/res/drawable/progress_medium_white.xml
@@ -21,5 +21,5 @@
android:drawable="@drawable/spinner_white_48"
android:pivotX="50%"
android:pivotY="50%"
- android:framesCount="12"
- android:frameDuration="100" />
+ android:framesCount="48"
+ android:frameDuration="25" />
diff --git a/core/res/res/drawable/progress_small.xml b/core/res/res/drawable/progress_small.xml
index e0ee5e4..1881da38 100644
--- a/core/res/res/drawable/progress_small.xml
+++ b/core/res/res/drawable/progress_small.xml
@@ -21,5 +21,5 @@
android:drawable="@drawable/spinner_black_16"
android:pivotX="50%"
android:pivotY="50%"
- android:framesCount="12"
- android:frameDuration="100" />
+ android:framesCount="48"
+ android:frameDuration="25" />
diff --git a/core/res/res/drawable/progress_small_titlebar.xml b/core/res/res/drawable/progress_small_titlebar.xml
index 8cfba86..5bb5cf8 100644
--- a/core/res/res/drawable/progress_small_titlebar.xml
+++ b/core/res/res/drawable/progress_small_titlebar.xml
@@ -21,5 +21,5 @@
android:drawable="@drawable/spinner_white_16"
android:pivotX="50%"
android:pivotY="50%"
- android:framesCount="12"
- android:frameDuration="100" />
+ android:framesCount="48"
+ android:frameDuration="25" />
diff --git a/core/res/res/drawable/progress_small_white.xml b/core/res/res/drawable/progress_small_white.xml
index 8cfba86..5bb5cf8 100644
--- a/core/res/res/drawable/progress_small_white.xml
+++ b/core/res/res/drawable/progress_small_white.xml
@@ -21,5 +21,5 @@
android:drawable="@drawable/spinner_white_16"
android:pivotX="50%"
android:pivotY="50%"
- android:framesCount="12"
- android:frameDuration="100" />
+ android:framesCount="48"
+ android:frameDuration="25" />
diff --git a/core/res/res/drawable/search_spinner.xml b/core/res/res/drawable/search_spinner.xml
index 31a77c3..b8c8b09 100644
--- a/core/res/res/drawable/search_spinner.xml
+++ b/core/res/res/drawable/search_spinner.xml
@@ -21,5 +21,5 @@
android:drawable="@drawable/spinner_black_20"
android:pivotX="50%"
android:pivotY="50%"
- android:framesCount="12"
- android:frameDuration="100" />
+ android:framesCount="48"
+ android:frameDuration="25" />
diff --git a/core/res/res/drawable/stat_sys_data_usb.xml b/core/res/res/drawable/stat_sys_data_usb.xml
new file mode 100644
index 0000000..fb1ad2a
--- /dev/null
+++ b/core/res/res/drawable/stat_sys_data_usb.xml
@@ -0,0 +1,24 @@
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="48.0"
+ android:viewportHeight="48.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M30 14v8h2v4h-6V10h4l-6,-8,-6 8h4v16h-6v-4.14c1.41,-.73 2.4,-2.16 2.4,-3.86 0,-2.43,-1.97,-4.4,-4.4,-4.4,-2.43 0,-4.4 1.97,-4.4 4.4 0 1.7.99 3.13 2.4 3.86V26c0 2.21 1.79 4 4 4h6v6.1c-1.42.73,-2.4 2.19,-2.4 3.9 0 2.43 1.97 4.4 4.4 4.4 2.43 0 4.4,-1.97 4.4,-4.4 0,-1.71,-.98,-3.17,-2.4,-3.9V30h6c2.21 0 4,-1.79 4,-4v-4h2v-8h-8z"/>
+</vector>
diff --git a/core/res/res/drawable/sym_def_app_icon.xml b/core/res/res/drawable/sym_def_app_icon.xml
index 129d38a..38d9147 100644
--- a/core/res/res/drawable/sym_def_app_icon.xml
+++ b/core/res/res/drawable/sym_def_app_icon.xml
@@ -1,7 +1,19 @@
<?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.
+-->
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/sym_def_app_icon_background" />
- <foreground>
- <bitmap android:src="@mipmap/sym_def_app_icon_foreground"/>
- </foreground>
+ <foreground android:drawable="@drawable/sym_def_app_icon_foreground" />
</adaptive-icon>
diff --git a/core/res/res/drawable/sym_def_app_icon_foreground.xml b/core/res/res/drawable/sym_def_app_icon_foreground.xml
new file mode 100644
index 0000000..0a5a334
--- /dev/null
+++ b/core/res/res/drawable/sym_def_app_icon_foreground.xml
@@ -0,0 +1,46 @@
+<?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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt"
+ android:width="108dp"
+ android:height="108dp"
+ android:viewportWidth="108"
+ android:viewportHeight="108">
+ <path
+ android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
+ <aapt:attr name="android:fillColor">
+ <gradient
+ android:startY="49.59793"
+ android:startX="42.9492"
+ android:endY="92.4963"
+ android:endX="85.84757"
+ android:type="linear">
+ <item
+ android:color="#44000000"
+ android:offset="0.0" />
+ <item
+ android:color="#00000000"
+ android:offset="1.0" />
+ </gradient>
+ </aapt:attr>
+ </path>
+ <path
+ android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
+ android:fillColor="#FFFFFF"
+ android:fillType="nonZero"
+ android:strokeWidth="1"
+ android:strokeColor="#00000000"/>
+</vector>
diff --git a/core/res/res/drawable/toast_frame.xml b/core/res/res/drawable/toast_frame.xml
index d57bd6a..a8814a1 100644
--- a/core/res/res/drawable/toast_frame.xml
+++ b/core/res/res/drawable/toast_frame.xml
@@ -18,7 +18,7 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- background is material_grey_200 with .9 alpha -->
- <solid android:color="#E6EEEEEE" />
+ <solid android:color="#E621272b" />
<corners android:radius="22dp" />
</shape>
diff --git a/core/res/res/layout/alert_dialog_material.xml b/core/res/res/layout/alert_dialog_material.xml
index 178505c..b1510fd 100644
--- a/core/res/res/layout/alert_dialog_material.xml
+++ b/core/res/res/layout/alert_dialog_material.xml
@@ -54,7 +54,7 @@
android:layout_height="wrap_content"
android:paddingEnd="?attr/dialogPreferredPadding"
android:paddingStart="?attr/dialogPreferredPadding"
- style="@style/TextAppearance.Material.Subhead" />
+ style="@style/TextAppearance.DeviceDefault.Subhead" />
<Space
android:id="@+id/textSpacerNoButtons"
diff --git a/core/res/res/layout/app_error_dialog.xml b/core/res/res/layout/app_error_dialog.xml
index c3b149a..4da9619 100644
--- a/core/res/res/layout/app_error_dialog.xml
+++ b/core/res/res/layout/app_error_dialog.xml
@@ -57,6 +57,14 @@
style="@style/aerr_list_item" />
<Button
+ android:id="@+id/aerr_copy"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/aerr_copy"
+ android:drawableStart="@drawable/ic_link"
+ style="@style/aerr_list_item" />
+
+ <Button
android:id="@+id/aerr_mute"
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/core/res/res/layout/notification_material_media_seekbar.xml b/core/res/res/layout/notification_material_media_seekbar.xml
index 4aa8acc..31f1f5b 100644
--- a/core/res/res/layout/notification_material_media_seekbar.xml
+++ b/core/res/res/layout/notification_material_media_seekbar.xml
@@ -15,51 +15,47 @@
~ limitations under the License
-->
+<!-- Layout for the seekbar in media notification -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/notification_media_progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="vertical"
android:layout_alignParentBottom="true"
- >
- <SeekBar android:id="@+id/notification_media_progress_bar"
- style="@style/Widget.ProgressBar.Horizontal"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:maxHeight="3dp"
- android:paddingTop="24dp"
- android:paddingBottom="24dp"
- android:clickable="true"
- android:layout_marginBottom="-24dp"
- android:layout_marginTop="-12dp"
- android:splitTrack="false"
- />
- <FrameLayout
+ android:orientation="vertical">
+ <RelativeLayout
android:id="@+id/notification_media_progress_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
- android:layout_marginBottom="11dp"
- >
-
- <!-- width is set to "match_parent" to avoid extra layout calls -->
- <TextView android:id="@+id/notification_media_elapsed_time"
- style="@style/Widget.DeviceDefault.Notification.Text"
- android:layout_width="match_parent"
+ android:layout_marginBottom="18dp">
+ <TextView
+ android:id="@+id/notification_media_elapsed_time"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginStart="@dimen/notification_content_margin_start"
android:gravity="start"
- />
-
- <TextView android:id="@+id/notification_media_total_time"
- style="@style/Widget.DeviceDefault.Notification.Text"
+ style="@style/Widget.Material.Notification.Text" />
+ <SeekBar
+ android:id="@+id/notification_media_progress_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_toLeftOf="@id/notification_media_total_time"
+ android:layout_toRightOf="@id/notification_media_elapsed_time"
+ android:layout_alignTop="@id/notification_media_elapsed_time"
+ android:layout_alignBottom="@id/notification_media_total_time"
+ android:clickable="true"
+ android:maxHeight="3dp"
+ android:splitTrack="false"
+ style="@style/Widget.ProgressBar.Horizontal" />
+ <TextView
+ android:id="@+id/notification_media_total_time"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginEnd="@dimen/notification_content_margin_end"
android:gravity="end"
- />
- </FrameLayout>
-</LinearLayout>
\ No newline at end of file
+ style="@style/Widget.Material.Notification.Text" />
+ </RelativeLayout>
+</LinearLayout>
diff --git a/core/res/res/layout/transient_notification.xml b/core/res/res/layout/transient_notification.xml
index db586ec..cdea61f 100644
--- a/core/res/res/layout/transient_notification.xml
+++ b/core/res/res/layout/transient_notification.xml
@@ -18,24 +18,35 @@
*/
-->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
- android:background="?android:attr/toastFrameBackground">
+ android:clipChildren="false">
<TextView
android:id="@android:id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_weight="1"
- android:layout_marginHorizontal="24dp"
- android:layout_marginVertical="15dp"
+ android:paddingHorizontal="24dp"
+ android:paddingVertical="15dp"
android:layout_gravity="center_horizontal"
+ android:layout_marginTop="-16dp"
+ android:layout_marginStart="-16dp"
+ android:layout_toRightOf="@android:id/icon"
+ android:layout_below="@android:id/icon"
android:textAppearance="@style/TextAppearance.Toast"
- android:textColor="@color/primary_text_default_material_light"
+ android:textColor="@color/primary_text_default_material_dark"
+ android:background="?android:attr/toastFrameBackground"
/>
-</LinearLayout>
+ <ImageView
+ android:id="@android:id/icon"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentStart="true"/>
+
+</RelativeLayout>
diff --git a/core/res/res/mipmap-hdpi/sym_def_app_icon_foreground.png b/core/res/res/mipmap-hdpi/sym_def_app_icon_foreground.png
deleted file mode 100644
index 4e526c9..0000000
--- a/core/res/res/mipmap-hdpi/sym_def_app_icon_foreground.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/mipmap-mdpi/sym_def_app_icon_foreground.png b/core/res/res/mipmap-mdpi/sym_def_app_icon_foreground.png
deleted file mode 100644
index 2c38c71..0000000
--- a/core/res/res/mipmap-mdpi/sym_def_app_icon_foreground.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/mipmap-xhdpi/sym_def_app_icon_foreground.png b/core/res/res/mipmap-xhdpi/sym_def_app_icon_foreground.png
deleted file mode 100644
index 072467e..0000000
--- a/core/res/res/mipmap-xhdpi/sym_def_app_icon_foreground.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/mipmap-xxhdpi/sym_def_app_icon_foreground.png b/core/res/res/mipmap-xxhdpi/sym_def_app_icon_foreground.png
deleted file mode 100644
index 78a6b7a..0000000
--- a/core/res/res/mipmap-xxhdpi/sym_def_app_icon_foreground.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/mipmap-xxxhdpi/sym_def_app_icon_foreground.png b/core/res/res/mipmap-xxxhdpi/sym_def_app_icon_foreground.png
deleted file mode 100644
index 68ebe33..0000000
--- a/core/res/res/mipmap-xxxhdpi/sym_def_app_icon_foreground.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/values/bliss_arrays.xml b/core/res/res/values/bliss_arrays.xml
new file mode 100644
index 0000000..c99c520
--- /dev/null
+++ b/core/res/res/values/bliss_arrays.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 BlissRoms 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.
+-->
+<resources>
+
+ <!-- Description for the screen zoom level that makes interface elements smaller. [CHAR LIMIT=24] -->
+ <string name="screen_zoom_summary_smaller">Smaller</string>
+ <!-- Description for the screen zoom level that makes interface elements smallest. [CHAR LIMIT=24] -->
+ <string name="screen_zoom_summary_smallest">Smallest</string>
+</resources>
diff --git a/core/res/res/values/bliss_attrs.xml b/core/res/res/values/bliss_attrs.xml
new file mode 100644
index 0000000..492e0a0
--- /dev/null
+++ b/core/res/res/values/bliss_attrs.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 BlissRoms 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.
+-->
+<resources>
+
+</resources>
diff --git a/core/res/res/values/bliss_bools.xml b/core/res/res/values/bliss_bools.xml
new file mode 100644
index 0000000..61cff84
--- /dev/null
+++ b/core/res/res/values/bliss_bools.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2014-2021, BlissRoms 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.
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- Whether to allow process with media UID to access CameraServiceProxy -->
+ <bool name="config_allowMediaUidForCameraServiceProxy">false</bool>
+
+</resources>
diff --git a/core/res/res/values/bliss_colors.xml b/core/res/res/values/bliss_colors.xml
new file mode 100644
index 0000000..492e0a0
--- /dev/null
+++ b/core/res/res/values/bliss_colors.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 BlissRoms 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.
+-->
+<resources>
+
+</resources>
diff --git a/core/res/res/values/bliss_config.xml b/core/res/res/values/bliss_config.xml
new file mode 100644
index 0000000..5340318
--- /dev/null
+++ b/core/res/res/values/bliss_config.xml
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 BlissRoms 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.
+-->
+<resources>
+
+ <!-- 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>
+
+ <!-- Vendor platform signatures -->
+ <string-array name="config_vendorPlatformSignatures">
+ </string-array>
+
+ <string-array translatable="false" name="config_customPermissionsList">
+ <item>com.android.wallpaper.livepicker</item>
+ </string-array>
+
+ <!-- Older rotation sensors are not setting event.timestamp correctly. Setting to
+ true will use SystemClock.elapsedRealtimeNanos() to set timestamp. -->
+ <bool name="config_useSystemClockforRotationSensor">false</bool>
+
+ <!-- The list of components which should be automatically disabled. -->
+ <string-array name="config_disabledComponents" translatable="false">
+ </string-array>
+
+ <!-- The list of components which should be forced to be enabled. -->
+ <string-array name="config_forceEnabledComponents" translatable="false">
+ </string-array>
+
+ <!-- Whether to persist the notification for when a usb drive device is plugged in -->
+ <bool name="config_persistUsbDriveNotification">false</bool>
+
+ <!-- Certain sensor firmwares break with having a batch
+ size set. By setting this to false, devices can opt
+ out of setting a batch size, which fixes rotation. -->
+ <bool name="config_useDefaultBatchingForAccel">true</bool>
+
+ <!-- Whether to show a custom view for FOD -->
+ <bool name="config_needCustomFODView">false</bool>
+
+ <!-- Whether notify fingerprint client of successful cancelled authentication -->
+ <bool name="config_notifyClientOnFingerprintCancelSuccess">false</bool>
+
+ <!-- Whether to cleanup fingerprints upon connection to the daemon and when user switches -->
+ <bool name="config_cleanupUnusedFingerprints">true</bool>
+
+ <!-- Whether to post reset runnable for all clients. Needed for some older
+ vendor fingerprint HAL implementations. -->
+ <bool name="config_fingerprintPostResetRunnableForAllClients">false</bool>
+
+ <string-array translatable="false" name="custom_config_globalActionsList">
+ <item>emergency</item>
+ <item>lockdown</item>
+ <item>power</item>
+ <item>restart</item>
+ <item>screenshot</item> <!--2 buttons nav-->
+ </string-array>
+
+ <bool name="config_has_Soli">false</bool>
+
+ <bool name="config_has_weird_dt_sensor">false</bool>
+
+ <bool name="config_has_elmyra">false</bool>
+
+ <!-- Whether device has dash charging support -->
+ <bool name="config_hasDashCharger">false</bool>
+
+ <!-- Whether device has warp charging support -->
+ <bool name="config_hasWarpCharger">false</bool>
+
+ <!-- Whether device has VOOC charging support -->
+ <bool name="config_hasVoocCharger">false</bool>
+
+ <!-- Whether device has physical tri state switch -->
+ <bool name="config_hasAlertSlider">false</bool>
+
+ <!-- The location of the devices physical tri state switch
+ 0: Left side
+ 1: Right side -->
+ <integer name="config_alertSliderLocation">0</integer>
+
+ <!-- Whether key handler sends intent when changing slider position -->
+ <string name="config_alertSliderIntent"></string>
+
+ <!-- Hardware keys present on the device, stored as a bit field.
+ This integer should equal the sum of the corresponding value for each
+ of the following keys present:
+ 1 - Home
+ 2 - Back
+ 4 - Menu
+ 8 - Assistant (search)
+ 16 - App switch
+ 32 - Camera
+ 64 - Volume rocker
+ For example, a device with Home, Back and Menu keys would set this
+ config to 7. -->
+ <integer name="config_deviceHardwareKeys">64</integer>
+
+ <!-- Full screen aspect ratio -->
+ <bool name="config_haveHigherAspectRatioScreen">false</bool>
+ <item name="config_screenAspectRatio" format="float" type="dimen">2.1</item>
+
+ <bool name="config_button_brightness_support">false</bool>
+ <integer name="config_button_brightness_default">128</integer>
+
+ <!-- True if the home button has the ability to wake up phone from lockscreen-->
+ <bool name="config_HomeWakeButton">false</bool>
+
+</resources>
diff --git a/core/res/res/values/bliss_dimens.xml b/core/res/res/values/bliss_dimens.xml
new file mode 100644
index 0000000..492e0a0
--- /dev/null
+++ b/core/res/res/values/bliss_dimens.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 BlissRoms 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.
+-->
+<resources>
+
+</resources>
diff --git a/core/res/res/values/bliss_strings.xml b/core/res/res/values/bliss_strings.xml
new file mode 100644
index 0000000..ec42fa5
--- /dev/null
+++ b/core/res/res/values/bliss_strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 BlissRoms 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.
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Button that copies the url to the log of a crashed application -->
+ <string name="aerr_copy">Copy crash log URL</string>
+ <string name="url_copy_success">URL copied successfully</string>
+ <string name="url_copy_failed">An error occured while uploading the log to dogbin</string>
+
+ <!-- Power Menu -->
+ <string name="reboot_to_recovery_title" translatable="false">Recovery</string>
+ <string name="reboot_to_recovery_message" translatable="false">Rebooting to recovery</string>
+ <string name="reboot_to_bootloader_title" translatable="false">Bootloader</string>
+ <string name="reboot_to_bootloader_message" translatable="false">Rebooting to bootloader</string>
+ <string name="reboot_title">Reboot</string>
+ <string name="reboot_message">Rebooting system</string>
+
+ <!-- Alert slider proc nodes paths. -->
+ <string name="alert_slider_state_path"></string>
+ <string name="alert_slider_uevent_match_path"></string>
+</resources>
diff --git a/core/res/res/values/bliss_styles.xml b/core/res/res/values/bliss_styles.xml
new file mode 100644
index 0000000..492e0a0
--- /dev/null
+++ b/core/res/res/values/bliss_styles.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 BlissRoms 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.
+-->
+<resources>
+
+</resources>
diff --git a/core/res/res/values/bliss_symbols.xml b/core/res/res/values/bliss_symbols.xml
new file mode 100644
index 0000000..fc3c8cf
--- /dev/null
+++ b/core/res/res/values/bliss_symbols.xml
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 BlissRoms 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.
+-->
+<resources>
+
+ <!-- Device keyhandlers -->
+ <java-symbol type="array" name="config_deviceKeyHandlerLibs" />
+ <java-symbol type="array" name="config_deviceKeyHandlerClasses" />
+
+ <!-- Vendor platform signatures -->
+ <java-symbol type="array" name="config_vendorPlatformSignatures" />
+
+ <!-- Private symbols that we need to reference from framework code. See
+ frameworks/base/core/res/MakeJavaSymbols.sed for how to easily generate
+ this.
+ Can be referenced in java code as: com.android.internal.R.<type>.<name>
+ and in layout xml as: "@*android:<type>/<name>"
+ -->
+ <java-symbol type="array" name="config_customPermissionsList" />
+
+ <!-- App error dialog -->
+ <java-symbol type="id" name="aerr_copy" />
+ <java-symbol type="string" name="url_copy_success" />
+ <java-symbol type="string" name="url_copy_failed" />
+
+ <java-symbol type="bool" name="config_useSystemClockforRotationSensor" />
+
+ <!-- Package Manager -->
+ <java-symbol type="array" name="config_disabledComponents" />
+ <java-symbol type="array" name="config_forceEnabledComponents" />
+
+ <!-- Usb drive persistent notification -->
+ <java-symbol type="bool" name="config_persistUsbDriveNotification" />
+
+ <java-symbol type="bool" name="config_useDefaultBatchingForAccel" />
+
+ <!-- Whether to allow process with media UID to access CameraServiceProxy -->
+ <java-symbol type="bool" name="config_allowMediaUidForCameraServiceProxy" />
+
+ <!-- Whether to show a custom view for FOD -->
+ <java-symbol type="bool" name="config_needCustomFODView" />
+
+ <!-- Whether notify fingerprint client of successful cancelled authentication -->
+ <java-symbol type="bool" name="config_notifyClientOnFingerprintCancelSuccess" />
+
+ <!-- Whether to cleanup fingerprints upon connection to the daemon and when user switches -->
+ <java-symbol type="bool" name="config_cleanupUnusedFingerprints" />
+
+ <!-- Post reset runnable for all clients -->
+ <java-symbol type="bool" name="config_fingerprintPostResetRunnableForAllClients" />
+
+ <!-- Power Menu -->
+ <java-symbol type="string" name="reboot_to_recovery_title" />
+ <java-symbol type="string" name="reboot_to_recovery_message" />
+ <java-symbol type="string" name="reboot_to_bootloader_title" />
+ <java-symbol type="string" name="reboot_to_bootloader_message" />
+ <java-symbol type="string" name="reboot_title" />
+ <java-symbol type="string" name="reboot_message" />
+
+ <java-symbol type="array" name="custom_config_globalActionsList" />
+ <java-symbol type="bool" name="config_has_Soli" />
+ <java-symbol type="bool" name="config_has_weird_dt_sensor" />
+
+ <java-symbol type="bool" name="config_has_elmyra" />
+
+ <!-- Whether device has dash charging support -->
+ <java-symbol type="bool" name="config_hasDashCharger" />
+
+ <!-- Whether device has warp charging support -->
+ <java-symbol type="bool" name="config_hasWarpCharger" />
+
+ <!-- Whether device has VOOC charging support -->
+ <java-symbol type="bool" name="config_hasVoocCharger" />
+
+ <!-- Alert slider. -->
+ <java-symbol type="string" name="alert_slider_state_path" />
+ <java-symbol type="string" name="alert_slider_uevent_match_path" />
+ <java-symbol type="bool" name="config_hasAlertSlider" />
+
+ <java-symbol type="integer" name="config_alertSliderLocation" />
+
+ <!-- Whether key handler sends intent when changing slider position -->
+ <java-symbol type="string" name="config_alertSliderIntent" />
+
+ <!-- HW keys binding -->
+ <java-symbol type="anim" name="custom_app_in" />
+ <java-symbol type="anim" name="custom_app_out" />
+ <java-symbol type="integer" name="config_deviceHardwareKeys" />
+
+ <!-- Full screen aspect ratio -->
+ <java-symbol type="bool" name="config_haveHigherAspectRatioScreen" />
+ <java-symbol type="dimen" name="config_screenAspectRatio" />
+
+ <!-- Button brightness -->
+ <java-symbol type="bool" name="config_button_brightness_support" />
+ <java-symbol type="integer" name="config_button_brightness_default" />
+
+ <!-- Home button wake -->
+ <java-symbol type="bool" name="config_HomeWakeButton" />
+
+</resources>
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 1242c6d..8a1a01d 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -60,10 +60,10 @@
<color name="dim_foreground_light_inverse">#bebebe</color>
<color name="dim_foreground_light_inverse_disabled">#80bebebe</color>
<color name="hint_foreground_light">#808080</color>
- <color name="highlighted_text_dark">#9983CC39</color>
- <color name="highlighted_text_light">#9983CC39</color>
- <color name="link_text_dark">#5c5cff</color>
- <color name="link_text_light">#0000ee</color>
+ <color name="highlighted_text_dark">@color/material_pixel_blue_bright</color>
+ <color name="highlighted_text_light">@color/material_pixel_blue_bright</color>
+ <color name="link_text_dark">@color/material_pixel_blue_bright</color>
+ <color name="link_text_light">@color/material_pixel_blue_bright</color>
<color name="suggestion_highlight_text">#177bbd</color>
<drawable name="stat_notify_sync_noanim">@drawable/stat_notify_sync_anim0</drawable>
@@ -164,17 +164,17 @@
<color name="accessibility_focus_highlight">#bf39b500</color>
<color name="autofilled_highlight">#4dffeb3b</color>
- <color name="system_notification_accent_color">#ff607D8B</color>
+ <color name="system_notification_accent_color">@color/material_pixel_blue_bright</color>
<!-- Default user icon colors -->
- <color name="user_icon_1">#ff00bcd4</color><!-- cyan 500 -->
- <color name="user_icon_2">#ff3f51b5</color><!-- indigo 500 -->
- <color name="user_icon_3">#ff4285f4</color><!-- blue 500 -->
- <color name="user_icon_4">#ffe91e63</color><!-- pink 500 -->
- <color name="user_icon_5">#ff0f9d58</color><!-- green 500 -->
- <color name="user_icon_6">#ff8bc34a</color><!-- light green 500 -->
- <color name="user_icon_7">#ffff9800</color><!-- orange 500 -->
- <color name="user_icon_8">#ffff5722</color><!-- deep orange 500 -->
+ <color name="user_icon_1">@android:color/accent_device_default_light</color>
+ <color name="user_icon_2">#ff5c6bc0</color>
+ <color name="user_icon_3">#ff26a69a</color>
+ <color name="user_icon_4">#ffec407a</color>
+ <color name="user_icon_5">#ff33ac71</color>
+ <color name="user_icon_6">#ff8bc34a</color>
+ <color name="user_icon_7">#ffff9800</color>
+ <color name="user_icon_8">#ffff7043</color>
<color name="user_icon_default_gray">#ff9e9e9e</color><!-- gray 500 -->
<color name="user_icon_default_white">#ffffffff</color><!-- white -->
@@ -191,18 +191,18 @@
<color name="instant_app_badge">#ff757575</color><!-- Grey -->
<!-- Multi-sim sim colors -->
- <color name="Teal_700">#ff00796b</color>
- <color name="Teal_800">#ff00695c</color>
- <color name="Blue_700">#ff3367d6</color>
- <color name="Blue_800">#ff2a56c6</color>
- <color name="Indigo_700">#ff303f9f</color>
- <color name="Indigo_800">#ff283593</color>
- <color name="Purple_700">#ff7b1fa2</color>
- <color name="Purple_800">#ff6a1b9a</color>
- <color name="Pink_700">#ffc2185b</color>
- <color name="Pink_800">#ffad1457</color>
- <color name="Red_700">#ffc53929</color>
- <color name="Red_800">#ffb93221</color>
+ <color name="Teal_700">@color/material_pixel_blue_light</color>
+ <color name="Teal_800">@color/material_pixel_blue_dark</color>
+ <color name="Blue_700">@color/material_pixel_blue_light</color>
+ <color name="Blue_800">@color/material_pixel_blue_dark</color>
+ <color name="Indigo_700">@color/material_pixel_blue_light</color>
+ <color name="Indigo_800">@color/material_pixel_blue_dark</color>
+ <color name="Purple_700">@color/material_pixel_blue_light</color>
+ <color name="Purple_800">@color/material_pixel_blue_dark</color>
+ <color name="Pink_700">@color/material_pixel_blue_light</color>
+ <color name="Pink_800">@color/material_pixel_blue_dark</color>
+ <color name="Red_700">@color/material_pixel_blue_light</color>
+ <color name="Red_800">@color/material_pixel_blue_dark</color>
<!-- Status bar color for semi transparent mode. -->
<color name="system_bar_background_semi_transparent">#66000000</color> <!-- 40% black -->
diff --git a/core/res/res/values/colors_device_defaults.xml b/core/res/res/values/colors_device_defaults.xml
index 7a8f411..0c281b2 100644
--- a/core/res/res/values/colors_device_defaults.xml
+++ b/core/res/res/values/colors_device_defaults.xml
@@ -17,34 +17,34 @@
<!-- Colors specific to DeviceDefault themes. These are mostly pass-throughs to enable
overlaying new theme colors. -->
<resources>
- <color name="primary_device_default_dark">@color/primary_material_dark</color>
+ <color name="primary_device_default_dark">#ff2d2d2d</color>
<color name="primary_device_default_light">@color/primary_material_light</color>
- <color name="primary_device_default_settings">@color/primary_material_settings</color>
- <color name="primary_device_default_settings_light">@color/primary_material_settings_light</color>
- <color name="primary_dark_device_default_dark">@color/primary_dark_material_dark</color>
+ <color name="primary_device_default_settings">#ff2d2d2d</color>
+ <color name="primary_device_default_settings_light">#ffffffff</color>
+ <color name="primary_dark_device_default_dark">#ff242424</color>
<color name="primary_dark_device_default_light">@color/primary_dark_material_light</color>
- <color name="primary_dark_device_default_settings">@color/primary_dark_material_settings</color>
- <color name="primary_dark_device_default_settings_light">@color/primary_dark_material_settings_light</color>
+ <color name="primary_dark_device_default_settings">#ff000000</color>
+ <color name="primary_dark_device_default_settings_light">#ffffffff</color>
<color name="navigation_bar_divider_device_default_settings">#1f000000</color>
- <color name="secondary_device_default_settings">@color/secondary_material_settings</color>
+ <color name="secondary_device_default_settings">#ff3a3a3a</color>
<color name="secondary_device_default_settings_light">@color/secondary_material_settings_light</color>
- <color name="tertiary_device_default_settings">@color/tertiary_material_settings</color>
- <color name="quaternary_device_default_settings">@color/quaternary_material_settings</color>
+ <color name="tertiary_device_default_settings">#ff616161</color>
+ <color name="quaternary_device_default_settings">#ff9e9e9e</color>
- <color name="accent_device_default_light">@color/accent_material_light</color>
- <color name="accent_device_default_dark">@color/accent_material_dark</color>
+ <color name="accent_device_default_light">#ff1a73e8</color>
+ <color name="accent_device_default_dark">#ff8ab4f8</color>
<color name="accent_device_default">@color/accent_device_default_light</color>
<color name="background_device_default_dark">@color/background_material_dark</color>
- <color name="background_device_default_light">@color/background_material_light</color>
- <color name="background_floating_device_default_dark">@color/background_floating_material_dark</color>
+ <color name="background_device_default_light">#ffffffff</color>
+ <color name="background_floating_device_default_dark">#ff3c4043</color>
<color name="background_floating_device_default_light">@color/background_floating_material_light</color>
<!-- Error color -->
- <color name="error_color_device_default_dark">@color/error_color_material_dark</color>
- <color name="error_color_device_default_light">@color/error_color_material_light</color>
+ <color name="error_color_device_default_dark">#fff28b82</color>
+ <color name="error_color_device_default_light">#ffd93025</color>
<color name="list_divider_color_light">#ffdadce0</color>
<color name="list_divider_color_dark">#85ffffff</color>
diff --git a/core/res/res/values/colors_material.xml b/core/res/res/values/colors_material.xml
index d357f01..8d03b0f 100644
--- a/core/res/res/values/colors_material.xml
+++ b/core/res/res/values/colors_material.xml
@@ -39,8 +39,8 @@
<color name="tertiary_material_settings">@color/material_blue_grey_700</color>
<color name="quaternary_material_settings">@color/material_blue_grey_200</color>
- <color name="accent_material_light">@color/material_deep_teal_500</color>
- <color name="accent_material_dark">@color/material_deep_teal_200</color>
+ <color name="accent_material_light">@color/material_pixel_blue_bright</color>
+ <color name="accent_material_dark">@color/material_pixel_blue_bright</color>
<color name="button_material_dark">#ff5a595b</color>
<color name="button_material_light">#ffd6d7d7</color>
@@ -108,14 +108,18 @@
<color name="material_red_A100">#ff8a80</color>
<color name="material_red_A700">#d50000</color>
+ <color name="material_pixel_blue_light">#ff3e4147</color>
+ <color name="material_pixel_blue_dark">#ff2a2c31</color>
+ <color name="material_pixel_blue_bright">#ff4285f4</color>
+
<!-- Time picker defaults when no theme is set -->
<eat-comment />
<color name="timepicker_default_background_material">@color/primary_text_default_material_light</color>
<color name="timepicker_default_text_color_material">@color/black</color>
- <color name="timepicker_default_ampm_selected_background_color_material">@color/material_deep_teal_200</color>
+ <color name="timepicker_default_ampm_selected_background_color_material">@color/material_pixel_blue_bright</color>
<color name="timepicker_default_ampm_unselected_background_color_material">@color/transparent</color>
- <color name="timepicker_default_selector_color_material">@color/material_deep_teal_200</color>
+ <color name="timepicker_default_selector_color_material">@color/material_pixel_blue_bright</color>
<color name="timepicker_default_numbers_background_color_material">@color/transparent</color>
<!-- DatePicker colors -->
@@ -139,8 +143,8 @@
<color name="datepicker_default_pressed_text_color_material_light">#ff0099cc</color>
<color name="datepicker_default_pressed_text_color_material_dark">#ff0099cc</color>
- <color name="datepicker_default_circle_background_color_material_light">@color/material_deep_teal_500</color>
- <color name="datepicker_default_circle_background_color_material_dark">@color/material_deep_teal_200</color>
+ <color name="datepicker_default_circle_background_color_material_light">@color/material_pixel_blue_bright</color>
+ <color name="datepicker_default_circle_background_color_material_dark">@color/material_pixel_blue_bright</color>
<color name="datepicker_default_view_animator_color_material_light">#fff2f2f2</color>
<color name="datepicker_default_view_animator_color_material_dark">#ff303030</color>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 550601a..8a76097 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -60,6 +60,8 @@
<item><xliff:g id="id">@string/status_bar_airplane</xliff:g></item>
<item><xliff:g id="id">@string/status_bar_battery</xliff:g></item>
<item><xliff:g id="id">@string/status_bar_sensors_off</xliff:g></item>
+ <item><xliff:g id="id">@string/status_bar_center_clock</xliff:g></item>
+ <item><xliff:g id="id">@string/status_bar_right_clock</xliff:g></item>
</string-array>
<string translatable="false" name="status_bar_rotate">rotate</string>
@@ -96,6 +98,8 @@
<string translatable="false" name="status_bar_airplane">airplane</string>
<string translatable="false" name="status_bar_sensors_off">sensors_off</string>
<string translatable="false" name="status_bar_screen_record">screen_record</string>
+ <string translatable="false" name="status_bar_center_clock">center_clock</string>
+ <string translatable="false" name="status_bar_right_clock">right_clock</string>
<!-- Flag indicating whether the surface flinger has limited
alpha compositing functionality in hardware. If set, the window
@@ -789,11 +793,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>
@@ -1832,7 +1836,7 @@
<bool name="config_bluetooth_default_profiles">true</bool>
<!-- IP address of the dns server to use if nobody else suggests one -->
- <string name="config_default_dns_server" translatable="false">8.8.8.8</string>
+ <string name="config_default_dns_server" translatable="false">1.0.0.1</string>
<!-- The default mobile provisioning apn. Empty by default, maybe overridden by
an mcc/mnc specific config.xml -->
@@ -2667,7 +2671,7 @@
<string name="config_defaultNetworkScorerPackageName"></string>
<!-- The amount to scale fullscreen snapshots for Overview and snapshot starting windows. -->
- <item name="config_highResTaskSnapshotScale" format="float" type="dimen">1.0</item>
+ <item name="config_highResTaskSnapshotScale" format="float" type="dimen">0.8</item>
<!-- The amount to scale reduced scale snapshots for Overview and snapshot starting windows.
Reduced scale snapshots are loaded before full screen snapshots to improve load times and
@@ -3780,7 +3784,7 @@
<!-- Corner radius of system progress bars -->
<dimen name="config_progressBarCornerRadius">@dimen/progress_bar_corner_material</dimen>
<!-- Controls whether system buttons use all caps for text -->
- <bool name="config_buttonTextAllCaps">true</bool>
+ <bool name="config_buttonTextAllCaps">false</bool>
<!-- Name of the font family used for system surfaces where the font should use medium weight -->
<string name="config_headlineFontFamilyMedium" translateable="false">@string/font_family_button_material</string>
<!-- Name of a font family to use for body text. -->
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index d6ee28b..366b50b 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -5303,6 +5303,7 @@
<string name="volume_dialog_ringer_guidance_vibrate">Calls and notifications will vibrate</string>
<string name="volume_dialog_ringer_guidance_silent">Calls and notifications will be muted</string>
+ <string name="volume_dialog_ringer_guidance_silent_no_media">Calls, notifications and media will be muted</string>
<!-- Title for the notification channel notifying user of settings system changes. [CHAR LIMIT=NONE] -->
<string name="notification_channel_system_changes">System changes</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index ee4c694..5354d7c 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1038,6 +1038,7 @@
<java-symbol type="string" name="volume_icon_description_ringer" />
<java-symbol type="string" name="volume_dialog_ringer_guidance_vibrate" />
<java-symbol type="string" name="volume_dialog_ringer_guidance_silent" />
+ <java-symbol type="string" name="volume_dialog_ringer_guidance_silent_no_media" />
<java-symbol type="string" name="wait" />
<java-symbol type="string" name="webpage_unresponsive" />
<java-symbol type="string" name="whichApplication" />
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index 1afaf4f..c6dccf2 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -711,6 +711,7 @@
<!-- Text styles -->
<item name="textAppearanceButton">@style/TextAppearance.DeviceDefault.Widget.Button</item>
+ <item name="textAppearanceMedium">@style/TextAppearance.DeviceDefault.Medium</item>
<!-- Button styles -->
<item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
@@ -1381,6 +1382,7 @@
<!-- Text styles -->
<item name="textAppearanceButton">@style/TextAppearance.DeviceDefault.Widget.Button</item>
+ <item name="textAppearanceMedium">@style/TextAppearance.DeviceDefault.Medium</item>
<!-- Button styles -->
<item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
diff --git a/core/res/res/xml/config_webview_packages.xml b/core/res/res/xml/config_webview_packages.xml
index f062b59..5b5039f 100644
--- a/core/res/res/xml/config_webview_packages.xml
+++ b/core/res/res/xml/config_webview_packages.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2015 The Android Open Source Project
+<!-- Copyright (C) 2016 The CyanogenMod Project
+ (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.
@@ -15,7 +16,21 @@
-->
<webviewproviders>
- <!-- The default WebView implementation -->
- <webviewprovider description="Android WebView" packageName="com.android.webview" availableByDefault="true">
+
+ <webviewprovider description="Google WebView" packageName="com.google.android.webview" availableByDefault="true">
+ <signature>MIIDuzCCAqOgAwIBAgIJANi6DgBQG4ZTMA0GCSqGSIb3DQEBBQUAMHQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKDAtHb29nbGUgSW5jLjEQMA4GA1UECwwHQW5kcm9pZDEQMA4GA1UEAwwHd2VidmlldzAeFw0xNDA4MDgyMzIwMjBaFw00MTEyMjQyMzIwMjBaMHQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKDAtHb29nbGUgSW5jLjEQMA4GA1UECwwHQW5kcm9pZDEQMA4GA1UEAwwHd2VidmlldzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbtaFX0r5aZJMAbPVMAgK1ZZ29dTn91VsGxXv2hqrQo7IpqEy2JmPvPnoMsSiuTAe+UcQy8oKDQ2aYVSAd1DGIy+nSRyFTt3LSIAdwSBkB1qT4a+OqkpsR6bSNXQXQ18lCQu9gREY3h3QlYBQAyzRxw4hRGlrXAzuSz1Ec4W+6x4nLG5DG61MAMR8ClF9XSqbmGB3kyZ70A0X9OPYYxiMWP1ExaYvpaVqjyZZcrPwr+vtW8oCuGBUtHpBUH3OoG+9s2YMcgLG7vCK9awKDqlPcJSpIAAj6uGs4gORmkqxZRMskLSTWbhP4p+3Ap8jYzTVB6Y1/DMVmYTWRMcPW0macCAwEAAaNQME4wHQYDVR0OBBYEFJ6bAR6/QVm4w9LRSGQiaR5Rhp3TMB8GA1UdIwQYMBaAFJ6bAR6/QVm4w9LRSGQiaR5Rhp3TMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAEQu8QiVxax7/diEiJrgKE1LwdXsIygJK/KnaKdnYEkAQpeu/QmrLiycm+OFbL1qHJIB7OuI/PQBUtcaNSiJSCVgtwtEbZWWIdsynqG/Nf4aGOndXegSQNRH54M05sRHLoeRycPrY7xQlEwGikNFR76+5UdwFBQI3Gn22g6puJnVukQm/wXQ+ajoiS4QclrNlixoDQsZ4STLH4+Wju2wIWKFFArIhVEIlbamq+p6BghuzH3aIz/Fy0YTQKi7SA+0fuNeCaqlSm5pYSt6p5CH89y1Fr+wFc5r3iLRnUwRcy08ESC7bZJnxV3d/YQ5valTxBbzku/dQbXVj/xg69H8l8M</signature>
</webviewprovider>
+ <webviewprovider description="Google WebView Beta" packageName="com.google.android.webview.beta" availableByDefault="true">
+ <signature>MIIFxzCCA6+gAwIBAgIVAO+zzx6JOZx3HWDG+fzlC1m53BsqMA0GCSqGSIb3DQEBCwUAMHQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtHb29nbGUgSW5jLjEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDAeFw0xOTA0MDUxNzIxNTRaFw00OTA0MDUxNzIxNTRaMHQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtHb29nbGUgSW5jLjEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAIbFePU+vsq6CEYIREsFFhwzXDoCwO6aK9ic9WJubui5VV7OqPCZmoZ/LY3852JK1A1OrWU643Ra7Z/wcvBXHHy5g08bF35gfelz9l53rIiG/1ubAApmxMNqASmQ5bMseetUIrBVqFnWspOWyrNuD0UsF4YkLgm+T1X5Hz1RNZwIV7WcVlL5qC2tm6kEy50bcAhbo5dDDud+ft8oc9g7vAiUpV0yqtNjZ+tsdJI4DrW5Nf2UhB8E+91se2IzQyWT6Vs/wB67HwroGr8qwPQYLQvzcyxZo2yA+qU2+k1IgJGTG5/0K/LheNxjqOKj6Zuhceff0JlbmrGKKqbXlz1F/E582MfqjeETB1gjw9Y0tHWEofEGdL4+ub8ZBJmveH9iz4BVKplzmYACLYWCGICiHBvmkkvx9dhmf5SsUsL9o4axPtAOKtjcKIDXBVqOtYCZssoVe9FFlZDHxRhQlbGY6ip0CK/lYlcx8iLfvI8Hf2AlwZa4j7HpFityaAWgYvo9x7bMJbBHiN/HW/NuhCF1B54KnQUmzQoyEnr5Qb4NjiDiXNzR8gYWYa9a/6Zg9iggr4jIbbEVanvCw9FAAZKRR8rk0ToJuFk2fRJdi2NhKo1GbVWOjj1Cd/Xbahd/uZhZGf1Uc61bG4rn9NU4GqliO2Wl2L78EkxuLDKXdovdHFjzAgMBAAGjUDBOMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFCAIx3WLD1UQ3YUE9ZBt36vfdQ6eMB8GA1UdIwQYMBaAFCAIx3WLD1UQ3YUE9ZBt36vfdQ6eMA0GCSqGSIb3DQEBCwUAA4ICAQBdHaxW69Hx4WPMXAVC5+S419L7/+AgxTyCn7YsD77aiKlIU20BMhvGln1d/Og6y1mf/z/x+GAm1ZfQniOih21Gxq3h4C3FvJ7gHgrjtZ6r0ymz7a1YOYc6LG1DNrTK7gKs5syifUd68PxUwNm5U5R9ixj0iglZDAC0apehGH/nfyJ4btS39N+oSQkUz3FpLoD5wYRlfdzhL2rMVDcv4WcEVDO8X8Md5Bk3hYtkh5MHzbVlu2yQ1qcNeXLUxUVeTjGebMu7B54Fgf+tHSBFBiyDdocpgF0B7RjF5579MXLpxdf9hoQImgzmp6xe0oHwqS1nQZR0pYfwP1Y8vxMSUWTPbY0YB9jQaElXznE/eQBuXe4kRkjEO6QvhziiQFxBlbfGSEFVySeqgWR91tJ0OiEWkMraQaI2bz941Qbt12PhS7r0KIkAsC5LpVRDOEgmo2e6+evst7DXpIAUvzNNSHrnmwmMGZ4QP4AUi7uIsclDJUT9sXDhwutx2Edic0X8+ZZ8D4e+HEupXI30z72En0U6ZyPqb6Ll9SOgK6pN6dbhdakucvRHCpmSfIlO8XXmPN5x3RsSteZl20Mc+ZSQuninApdirEs/9CfRoSSYXlNabxklBZd5jeb0py09FjjE+Nqf4EdZFYvzpYFSGJz1RUrsaDWOmx4gF3YeXo8iUbGtPA==</signature>
+ </webviewprovider>
+ <webviewprovider description="Google WebView Dev" packageName="com.google.android.webview.dev" availableByDefault="true">
+ <signature>MIIFxzCCA6+gAwIBAgIVAMQCAZgONsTyki5gq7E1h9s6KFvaMA0GCSqGSIb3DQEBCwUAMHQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtHb29nbGUgSW5jLjEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDAeFw0xOTA0MDUxNzE3MDJaFw00OTA0MDUxNzE3MDJaMHQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtHb29nbGUgSW5jLjEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAJjFQ4Jm1Tf5BESiSnU1w5H5//IbLr6wNIfVbws8mbPb3fq9vs3LAHbtfzgWJ3eG2eNx7GH6ge+XjaNiZzQ8223Fqu9AxBinve4KSm6Mrkq7gk7lMCbUUIap6m0ftDa+7lrxbhjWHrFzFq8Muq43CM7i8CxLdKTGSx098dcvY6giOQstAKQyPmlbH6zjwnS8KNYakDKv0Fv4VdKi14T6ANXAblicfTaclA1HLWhFqv5DaKL8YobQu8FN2Egk9nlimwExbRs1twrmuyX2tNtgX7vMvt3+HHTrkYweARVvvqVoEXkNGfZPlIkExBZSHpJgqSIb6vcBzgntneo9X+iB7K0VRovkK20PDuxKvrt07dZ15qACGC364O1NKSK0+1tiRU6tPI8P1VI3JR2c8C5cnCg9zGCHinZR3iyY+ISA5G+bVEU8WWhwMuSuM2Vo5hmpDnX+p1K2XiuNdV2VblXPKZIfV3xahCZTvemVBt6WhrxeshhTBG2+Z2Qz0TSZSFkeX4ruo0WffOy7A2ybwhmCWryltgDe04Z+kkF+kmwZ6N/cQWWBqYPTILYfs/t9XWz3VyrFEJK+Uf6T+/JO3T0nGZZm4+kr5wH6YMbffrF5S8t0/DpIZfxExcyPnwxYAkI8TohMR4BPX4FPJL5j5ulZbnEbAqoVC6nphlVSulRLM5LFAgMBAAGjUDBOMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFBDgxJQIS7rzqWgJ5oSIuvg3hos6MB8GA1UdIwQYMBaAFBDgxJQIS7rzqWgJ5oSIuvg3hos6MA0GCSqGSIb3DQEBCwUAA4ICAQAiEpFVrLKCY99LxFmIqUvE/pL2ULzhBtZ0YQvWT4QgMABrC2ZKsG0Ttx2OyGXjI3Hl9sEDGdCTA2D0lN3gS44RYSxCK0RANF2wamY5vGgEA4uqQ6o/JIH9VLTEk7A7g+Lu4fl4lnIX3+kw2Thfk4CQ15cWI9tISUPfC4rO2vG9Ct9G3kkXvEj1r7cRH7wmGJcOWKoiMVsLNVIfCYPO4qZOnj+ZpVkxLxRTTjJzqXPYNsHlfywM3zoqtexDdwXFVGP8M/cW7pIp46UE0bvU9jHurF+ECwUykLn/GHG36DYyKAFeIsgpGsLZXW9jHLspSaVF3kR77qPpvlhuF29rfY4E2Bd2d24HHWR3mHMosdzKomatOZbeh6Dj0wdrq+GmRpC70knWrXxmNshYSJri41jvAUEnXVAkbQznxeCct6ST2JhYzuNP8OGVxO0xqs/Hpu9x1aSN0BUotO7ZJPqVR5qCpgEWE1BuWljutrhpI5/d0Oz/DKs14TDrPjlrYJgmR766MnqxQAzYAcM1nC6QcxAkc+N1BLGujI+WQbz9sAlUC0fOf3KuVqemt9XoIh5Z33kJ1QI/VKflCQtlvgSBnJX9zge/iAEImud+Z3MyPT6FxVtkEM9KwBWytT1TvJTyPeOK9SV+2w7xbCoLC8apPlamx13yDngxg0c3eJAd9+p2OA==</signature>
+ </webviewprovider>
+ <webviewprovider description="Google WebView Canary" packageName="com.google.android.webview.canary" availableByDefault="true">
+ <signature>MIIFxzCCA6+gAwIBAgIVAMtzFe17x7TJnswywhkvEJa+6EIQMA0GCSqGSIb3DQEBCwUAMHQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtHb29nbGUgSW5jLjEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDAeFw0xOTA0MDUxNzIzMDZaFw00OTA0MDUxNzIzMDZaMHQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtHb29nbGUgSW5jLjEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAJbi91Ehi2xTxKCzeC6XO+COhaJp4dv6LqA8EfTBZEKoLQZ6FQQcDE4dirK78tBIbF4SQLkWt+Lxh3LnV6yfOt3hNmK3Rc9IhFAi0A56dGWazNo0pY8DiCftmPwnkPNT2aTZzmvWuDQHjLoMju2y7nDOliZThOybF9KMKSVsAr2Ahcmx4cRdyxCZKAutzsYOoBk77dFIO0kSaEPof9/Zlan4mAEnQ6GWgbK5wyIYN7DuaCDkJ5FYxUJxyp53/c5jKF/zZRPoGzXlt5e22yymD8MPSj716OolmKPFLUtzCVUnrm4xmmtgheWS1X43tRWit0rPl92bBHFiSECyIQriNS5ZlLuh712G6D7A3uaQqIIRmKVRE6DT3xRWI3l78cDquWIgU+x99qS9bb/txv/oaT1SIlM/rJij11iOISJCJ++vcyuR4j3pydkfl5ePH8YKAmUOCFlDJM3vOt7aqYpx3Ql5GFLeHOoSw4vOzwvMSROV/i6mXBv1d5O1o5XzDUWuIsFFroC1yz11/s547eV091BGuB60pyv7pXZY2EFOjjFcqWfsKrmcxzqCwel9bDd1WvsUY2Dt6Xl13hFMZ9ab2XiZCqA+OF+PrZKJYhTcpcdEjTYbVYEofst5Zg6WWL28WfQlDq0QwVDWFAsBdnegp40dNKwdkjp0LTXYdykzu8otAgMBAAGjUDBOMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFI0WYMtA13YCvaXP3y7SD7+BUoGGMB8GA1UdIwQYMBaAFI0WYMtA13YCvaXP3y7SD7+BUoGGMA0GCSqGSIb3DQEBCwUAA4ICAQAmJmDx+9Bfshs9PtNPb+2PEckvwheOurS15JAV10OTvmcpu0AON56RpItaMm29Uea5wYxaPcPwUQDum0vahHt7FIYxnPIxQ0FxsBDSVDn5veWMVXf5oSVDzsR61+x7i67Qk3dsMgRrY0PS/HZv+cFl0fb87b54mrtFIl8P9KjV5g5PUNJI2BIwLOKgnlU2kDrE1emm7lIKvoJqwb9JjlWl0lB+xXmntNQ+ZNvCzULnr1o0QblVK1Iowe++17GzOtrUlkATTmGx2exaeEEsZcQ23J6u8XycAk9+80aspTjZHC9aneQVcIdbCEBdWkF3xQ0TSnytT/0jLnLBnk2/kIV2ynw2zu/nMczgW2eUnfiIjqzBuP0uRMJ8NFPv/4Agmdqex+A233K9wYc92iflm/aVT3qw7wQntsmSesSBfZgLVVQ++dVD0bd5qYtyELCA2DNCaORU62bfNnPNTkQQo/FeyFDBLNzfWxiDINk6SxNxrZLgQFj9gil+CBgltrJ90Qv8Ats1ES66A0o+2T/j0GA9nOkfznID0VU1SlmOub/0SMwZL98WpkYqYTu/9AOqwzZBO/uT4ADANnMrMd4dtzZ1n0AdSvr1QyqO9XJRmW0k1PlmBM6iPU9p3JMVEqeQ7/zYnYq0tCK+k1mvA5BQ20NVSfea27X7/9EgGanchrFdCQ==</signature>
+ </webviewprovider>
+
+ <!-- The default WebView implementation -->
+ <webviewprovider description="AOSP WebView" packageName="com.android.webview" availableByDefault="true" />
+
</webviewproviders>
diff --git a/data/etc/com.android.launcher3.xml b/data/etc/com.android.launcher3.xml
index 17d614e..aac980f 100644
--- a/data/etc/com.android.launcher3.xml
+++ b/data/etc/com.android.launcher3.xml
@@ -20,5 +20,7 @@
<permission name="android.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS"/>
<permission name="android.permission.GET_ACCOUNTS_PRIVILEGED"/>
<permission name="android.permission.WRITE_SECURE_SETTINGS"/>
+ <permission name="android.permission.PACKAGE_USAGE_STATS"/>
+ <permission name="android.permission.STATUS_BAR"/>
</privapp-permissions>
</permissions>
diff --git a/data/etc/com.android.systemui.xml b/data/etc/com.android.systemui.xml
index 06f1dae..ec4548c 100644
--- a/data/etc/com.android.systemui.xml
+++ b/data/etc/com.android.systemui.xml
@@ -30,6 +30,7 @@
<permission name="android.permission.GET_APP_OPS_STATS"/>
<permission name="android.permission.INTERACT_ACROSS_USERS"/>
<permission name="android.permission.MANAGE_DEBUGGING"/>
+ <permission name="android.permission.MANAGE_SOUND_TRIGGER" />
<permission name="android.permission.MANAGE_SENSOR_PRIVACY"/>
<permission name="android.permission.MANAGE_USB"/>
<permission name="android.permission.MANAGE_USERS"/>
@@ -59,6 +60,7 @@
<permission name="android.permission.TETHER_PRIVILEGED"/>
<permission name="android.permission.UPDATE_APP_OPS_STATS"/>
<permission name="android.permission.USE_RESERVED_DISK"/>
+ <permission name="android.permission.USER_ACTIVITY" />
<permission name="android.permission.WATCH_APPOPS"/>
<permission name="android.permission.WRITE_DREAM_STATE"/>
<permission name="android.permission.WRITE_MEDIA_STORAGE"/>
@@ -67,5 +69,10 @@
<permission name="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"/>
<permission name="android.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS" />
<permission name="android.permission.CAMERA_OPEN_CLOSE_LISTENER" />
+ <permission name="android.permission.FORCE_STOP_PACKAGES" />
+ <permission name="android.permission.WRITE_APN_SETTINGS" />
+ <permission name="android.permission.REBOOT" />
+ <permission name="android.permission.RECOVERY" />
+ <permission name="android.permission.CHANGE_CONFIGURATION" />
</privapp-permissions>
</permissions>
diff --git a/data/etc/framework-sysconfig.xml b/data/etc/framework-sysconfig.xml
old mode 100644
new mode 100755
index 2162ec4..9ed0171
--- a/data/etc/framework-sysconfig.xml
+++ b/data/etc/framework-sysconfig.xml
@@ -56,4 +56,8 @@
<!-- Whitelist of bundled applications which all handle URLs to their websites by default -->
<app-link package="com.android.carrierdefaultapp" />
+
+ <!-- Whitelist of what components are permitted to run in the background -->
+ <allow-in-power-save package="com.android.deskclock" />
+
</config>
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index cf31216..f2ff7cf 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -267,4 +267,6 @@
<!-- These are the packages that shouldn't run as system user -->
<system-user-blacklisted-app package="com.android.wallpaper.livepicker" />
+
+ <allow-in-power-save package="com.google.android.gms"/>
</permissions>
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 3b6abd5..1f1551b 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -186,6 +186,7 @@
<permission name="android.permission.SHUTDOWN"/>
<permission name="android.permission.START_ACTIVITIES_FROM_BACKGROUND"/>
<permission name="android.permission.STATUS_BAR"/>
+ <permission name="android.permission.START_ACTIVITIES_FROM_BACKGROUND"/>
<permission name="android.permission.STOP_APP_SWITCHES"/>
<permission name="android.permission.SUGGEST_TELEPHONY_TIME_AND_ZONE"/>
<permission name="android.permission.UPDATE_APP_OPS_STATS"/>
@@ -298,6 +299,10 @@
<permission name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME"/>
</privapp-permissions>
+ <privapp-permissions package="com.android.settings">
+ <permission name="android.permission.RESET_BATTERY_STATS"/>
+ </privapp-permissions>
+
<privapp-permissions package="com.android.sharedstoragebackup">
<permission name="android.permission.WRITE_MEDIA_STORAGE"/>
<permission name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
diff --git a/data/fonts/Android.mk b/data/fonts/Android.mk
index 4226e08..07d4523 100644
--- a/data/fonts/Android.mk
+++ b/data/fonts/Android.mk
@@ -47,9 +47,9 @@
DroidSans-Bold.ttf
################################
-# Use DroidSansMono to hang extra_font_files on
+# Use AndroidClock to hang extra_font_files on
include $(CLEAR_VARS)
-LOCAL_MODULE := DroidSansMono.ttf
+LOCAL_MODULE := AndroidClock.ttf
LOCAL_SRC_FILES := $(LOCAL_MODULE)
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_TAGS := optional
@@ -73,8 +73,7 @@
$(eval include $(BUILD_PREBUILT))
endef
-font_src_files := \
- AndroidClock.ttf
+font_src_files :=
$(foreach f, $(font_src_files), $(call build-one-font-module, $(f)))
diff --git a/data/fonts/fonts.xml b/data/fonts/fonts.xml
index 4c214b5..489dad4 100644
--- a/data/fonts/fonts.xml
+++ b/data/fonts/fonts.xml
@@ -65,7 +65,6 @@
<font weight="400" style="italic">NotoSerif-Italic.ttf</font>
<font weight="700" style="italic">NotoSerif-BoldItalic.ttf</font>
</family>
- <alias name="serif-bold" to="serif" weight="700" />
<alias name="times" to="serif" />
<alias name="times new roman" to="serif" />
<alias name="palatino" to="serif" />
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 88b614d..0f766ef 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -1124,6 +1124,11 @@
public int attestKey(
String alias, KeymasterArguments params, KeymasterCertificateChain outChain) {
+ // Prevent Google Play Services from using key attestation for SafetyNet
+ if (mContext.getPackageName().equals("com.google.android.gms")) {
+ return KeymasterDefs.KM_ERROR_UNIMPLEMENTED;
+ }
+
CertificateChainPromise promise = new CertificateChainPromise();
try {
mBinder.asBinder().linkToDeath(promise, 0);
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index 4d7e5df..c88ff8c 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -4277,7 +4277,7 @@
if (p < 0) {
if (Res_GETPACKAGE(resID)+1 == 0) {
- ALOGW("No package identifier when getting name for resource number 0x%08x", resID);
+ ALOGV("No package identifier when getting name for resource number 0x%08x", resID);
} else {
#ifndef STATIC_ANDROIDFW_FOR_TOOLS
ALOGW("No known package when getting name for resource number 0x%08x", resID);
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index aa842ff..74628af 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -4,7 +4,7 @@
"hwui_static_deps",
"skia_deps",
//"hwui_bugreport_font_cache_usage",
- //"hwui_compile_for_perf",
+ "hwui_compile_for_perf",
"hwui_pgo",
"hwui_lto",
],
@@ -115,12 +115,18 @@
cc_defaults {
name: "hwui_compile_for_perf",
- // TODO: Non-arm?
cflags: [
"-fno-omit-frame-pointer",
- "-marm",
- "-mapcs",
],
+
+ arch: {
+ arm: {
+ cflags: ["-marm"],
+ },
+ arm64: {
+ cflags: ["-marm"],
+ },
+ },
}
// Build libhwui with PGO by default.
diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
index 67a040d..d85382a 100644
--- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
+++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
@@ -49,7 +49,7 @@
private static final String TAG = "GpsNetInitiatedHandler";
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+ private static final boolean DEBUG = false;
// NI verify activity for bringing up UI (not used yet)
public static final String ACTION_NI_VERIFY = "android.intent.action.NETWORK_INITIATED_VERIFY";
diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java
index 158482a..c3fdc89 100644
--- a/media/java/android/media/AudioAttributes.java
+++ b/media/java/android/media/AudioAttributes.java
@@ -617,12 +617,6 @@
*/
@CapturePolicy
public int getAllowedCapturePolicy() {
- if ((mFlags & FLAG_NO_SYSTEM_CAPTURE) == FLAG_NO_SYSTEM_CAPTURE) {
- return ALLOW_CAPTURE_BY_NONE;
- }
- if ((mFlags & FLAG_NO_MEDIA_PROJECTION) == FLAG_NO_MEDIA_PROJECTION) {
- return ALLOW_CAPTURE_BY_SYSTEM;
- }
return ALLOW_CAPTURE_BY_ALL;
}
@@ -1435,20 +1429,7 @@
* @hide
*/
public static int capturePolicyToFlags(@CapturePolicy int capturePolicy, int flags) {
- switch (capturePolicy) {
- case ALLOW_CAPTURE_BY_NONE:
- flags |= FLAG_NO_MEDIA_PROJECTION | FLAG_NO_SYSTEM_CAPTURE;
- break;
- case ALLOW_CAPTURE_BY_SYSTEM:
- flags |= FLAG_NO_MEDIA_PROJECTION;
- flags &= ~FLAG_NO_SYSTEM_CAPTURE;
- break;
- case ALLOW_CAPTURE_BY_ALL:
- flags &= ~FLAG_NO_SYSTEM_CAPTURE & ~FLAG_NO_MEDIA_PROJECTION;
- break;
- default:
- throw new IllegalArgumentException("Unknown allow playback capture policy");
- }
+ flags &= ~FLAG_NO_SYSTEM_CAPTURE & ~FLAG_NO_MEDIA_PROJECTION;
return flags;
}
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 3ac71b2..70e0409 100755
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -4855,6 +4855,38 @@
}
}
+ /**
+ * Indicate A2DP source or sink active device change and eventually suppress
+ * the {@link AudioManager.ACTION_AUDIO_BECOMING_NOISY} intent.
+ * This operation is asynchronous but its execution will still be sequentially scheduled
+ * relative to calls to {@link #setBluetoothHearingAidDeviceConnectionState(BluetoothDevice,
+ * int, boolean, int)} and
+ * {@link #handleBluetoothA2dpDeviceConfigChange(BluetoothDevice)}.
+ * @param device Bluetooth device connected/disconnected
+ * @param state new connection state (BluetoothProfile.STATE_xxx)
+ * @param profile profile for the A2DP device
+ * (either {@link android.bluetooth.BluetoothProfile.A2DP} or
+ * {@link android.bluetooth.BluetoothProfile.A2DP_SINK})
+ * @param a2dpVolume New volume for the connecting device. Does nothing if
+ * disconnecting. Pass value -1 in case you want this field to be ignored
+ * @param suppressNoisyIntent if true the
+ * {@link AudioManager.ACTION_AUDIO_BECOMING_NOISY} intent will not be sent.
+ * @return a delay in ms that the caller should wait before broadcasting
+ * BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED intent.
+ * {@hide}
+ */
+ public void handleBluetoothA2dpActiveDeviceChange(
+ BluetoothDevice device, int state, int profile,
+ boolean suppressNoisyIntent, int a2dpVolume) {
+ final IAudioService service = getService();
+ try {
+ service.handleBluetoothA2dpActiveDeviceChange(device,
+ state, profile, suppressNoisyIntent, a2dpVolume);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
/** {@hide} */
public IRingtonePlayer getRingtonePlayer() {
try {
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index da52cfe..842ab7c 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -25,6 +25,7 @@
import android.content.pm.PackageManager;
import android.media.audiofx.AudioEffect;
import android.media.audiopolicy.AudioMix;
+import android.os.SystemProperties;
import android.telephony.TelephonyManager;
import android.util.Log;
@@ -198,6 +199,14 @@
public static final int AUDIO_FORMAT_APTX_HD = 0x21000000;
/** @hide */
public static final int AUDIO_FORMAT_LDAC = 0x23000000;
+ /** @hide */
+ public static final int AUDIO_FORMAT_CELT = 0x26000000;
+ /** @hide */
+ public static final int AUDIO_FORMAT_APTX_ADAPTIVE = 0x27000000;
+ /** @hide */
+ public static final int AUDIO_FORMAT_APTX_TWSP = 0x2A000000;
+ /** @hide */
+ public static final int VX_AUDIO_FORMAT_LC3 = 0x2B000000;
/** @hide */
@IntDef(flag = false, prefix = "AUDIO_FORMAT_", value = {
@@ -212,6 +221,9 @@
@Retention(RetentionPolicy.SOURCE)
public @interface AudioFormatNativeEnumForBtCodec {}
+ private static final boolean IS_QTI_BT =
+ SystemProperties.get("ro.bluetooth.library_name", "").equals("libbluetooth_qti.so");
+
/**
* @hide
* Convert audio format enum values to Bluetooth codec values
@@ -224,6 +236,14 @@
case AUDIO_FORMAT_APTX: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX;
case AUDIO_FORMAT_APTX_HD: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD;
case AUDIO_FORMAT_LDAC: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC;
+ case AUDIO_FORMAT_CELT:
+ if (IS_QTI_BT) return BluetoothCodecConfig.SOURCE_CODEC_TYPE_CELT;
+ case AUDIO_FORMAT_APTX_ADAPTIVE:
+ if (IS_QTI_BT) return BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_ADAPTIVE;
+ case AUDIO_FORMAT_APTX_TWSP:
+ if (IS_QTI_BT) return BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_TWSP;
+ case VX_AUDIO_FORMAT_LC3:
+ if (IS_QTI_BT) return BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3;
default:
Log.e(TAG, "Unknown audio format 0x" + Integer.toHexString(audioFormat)
+ " for conversion to BT codec");
@@ -249,6 +269,14 @@
return AudioSystem.AUDIO_FORMAT_APTX_HD;
case BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC:
return AudioSystem.AUDIO_FORMAT_LDAC;
+ case BluetoothCodecConfig.SOURCE_CODEC_TYPE_CELT:
+ if (IS_QTI_BT) return AudioSystem.AUDIO_FORMAT_CELT;
+ case BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_ADAPTIVE:
+ if (IS_QTI_BT) return AudioSystem.AUDIO_FORMAT_APTX_ADAPTIVE;
+ case BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_TWSP:
+ if (IS_QTI_BT) return AudioSystem.AUDIO_FORMAT_APTX_TWSP;
+ case BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3:
+ if (IS_QTI_BT) return AudioSystem.VX_AUDIO_FORMAT_LC3;
default:
Log.e(TAG, "Unknown BT codec 0x" + Integer.toHexString(btCodec)
+ " for conversion to audio format");
@@ -349,6 +377,8 @@
return "AUDIO_FORMAT_LHDC_LL";
case /* AUDIO_FORMAT_APTX_TWSP */ 0x2A000000:
return "AUDIO_FORMAT_APTX_TWSP";
+ case /* VX_AUDIO_FORMAT_LC3 */ 0x2B000000:
+ return "VX_AUDIO_FORMAT_LC3";
/* Aliases */
case /* AUDIO_FORMAT_PCM_16_BIT */ 0x1:
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 4cf236a..efa32ae5 100755
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -192,6 +192,9 @@
void handleBluetoothA2dpDeviceConfigChange(in BluetoothDevice device);
+ void handleBluetoothA2dpActiveDeviceChange(in BluetoothDevice device,
+ int state, int profile, boolean suppressNoisyIntent, int a2dpVolume);
+
@UnsupportedAppUsage
AudioRoutesInfo startWatchingRoutes(in IAudioRoutesObserver observer);
diff --git a/media/java/android/media/Ringtone.java b/media/java/android/media/Ringtone.java
index d35bc41..2255b9f 100644
--- a/media/java/android/media/Ringtone.java
+++ b/media/java/android/media/Ringtone.java
@@ -46,7 +46,7 @@
*/
public class Ringtone {
private static final String TAG = "Ringtone";
- private static final boolean LOGD = true;
+ private static final boolean LOGD = false;
private static final String[] MEDIA_COLUMNS = new String[] {
MediaStore.Audio.Media._ID,
diff --git a/obex/javax/obex/ClientOperation.java b/obex/javax/obex/ClientOperation.java
index c627dfb..d090bf5 100644
--- a/obex/javax/obex/ClientOperation.java
+++ b/obex/javax/obex/ClientOperation.java
@@ -50,7 +50,7 @@
*/
public final class ClientOperation implements Operation, BaseStream {
- private static final String TAG = "ClientOperation";
+ private static final String TAG = "ObexClientOperation";
private static final boolean V = ObexHelper.VDBG;
diff --git a/obex/javax/obex/ClientSession.java b/obex/javax/obex/ClientSession.java
index 272a920..9aaf7bc 100644
--- a/obex/javax/obex/ClientSession.java
+++ b/obex/javax/obex/ClientSession.java
@@ -47,7 +47,7 @@
*/
public final class ClientSession extends ObexSession {
- private static final String TAG = "ClientSession";
+ private static final String TAG = "ObexClientSession";
private boolean mOpen;
diff --git a/obex/javax/obex/ObexHelper.java b/obex/javax/obex/ObexHelper.java
index 478297f..f09d3d3 100644
--- a/obex/javax/obex/ObexHelper.java
+++ b/obex/javax/obex/ObexHelper.java
@@ -52,7 +52,8 @@
public final class ObexHelper {
private static final String TAG = "ObexHelper";
- public static final boolean VDBG = false;
+ public static final String LOG_TAG = "BluetoothObex";
+ public static final boolean VDBG = Log.isLoggable(LOG_TAG, Log.VERBOSE);
/**
* Defines the basic packet length used by OBEX. Every OBEX packet has the
* same basic format:<BR>
@@ -89,6 +90,8 @@
*/
public static final int MAX_CLIENT_PACKET_SIZE = 0xFC00;
+ public static final int A2DP_SCO_OBEX_MAX_CLIENT_PACKET_SIZE = 0x2000;
+
public static final int OBEX_OPCODE_FINAL_BIT_MASK = 0x80;
public static final int OBEX_OPCODE_CONNECT = 0x80;
@@ -193,6 +196,7 @@
try {
while (index < headerArray.length) {
headerID = 0xFF & headerArray[index];
+ if (VDBG) Log.v(TAG,"updateHeaderSet headerID = " + headerID);
switch (headerID & (0xC0)) {
/*
@@ -211,9 +215,9 @@
length = ((0xFF & headerArray[index]) << 8) +
(0xFF & headerArray[index + 1]);
index += 2;
- if (length <= OBEX_BYTE_SEQ_HEADER_LEN) {
+ if (length < OBEX_BYTE_SEQ_HEADER_LEN) {
Log.e(TAG, "Remote sent an OBEX packet with " +
- "incorrect header length = " + length);
+ "incorrect header length : " + length);
break;
}
length -= OBEX_BYTE_SEQ_HEADER_LEN;
@@ -381,8 +385,9 @@
* Determine if there is a connection ID to send. If there is,
* then it should be the first header in the packet.
*/
+ if (VDBG) Log.v(TAG,"createHeader = " + head);
if ((headImpl.mConnectionID != null) && (headImpl.getHeader(HeaderSet.TARGET) == null)) {
-
+ if (VDBG) Log.v(TAG," Add Header = " + HeaderSet.CONNECTION_ID);
out.write((byte)HeaderSet.CONNECTION_ID);
out.write(headImpl.mConnectionID);
}
@@ -390,6 +395,7 @@
// Count Header
intHeader = (Long)headImpl.getHeader(HeaderSet.COUNT);
if (intHeader != null) {
+ if (VDBG) Log.v(TAG," Add Header = " + HeaderSet.COUNT);
out.write((byte)HeaderSet.COUNT);
value = ObexHelper.convertToByteArray(intHeader.longValue());
out.write(value);
@@ -401,6 +407,7 @@
// Name Header
stringHeader = (String)headImpl.getHeader(HeaderSet.NAME);
if (stringHeader != null) {
+ if (VDBG) Log.v(TAG," Add Header = " + HeaderSet.NAME);
out.write((byte)HeaderSet.NAME);
value = ObexHelper.convertToUnicodeByteArray(stringHeader);
length = value.length + 3;
@@ -421,6 +428,7 @@
// Type Header
stringHeader = (String)headImpl.getHeader(HeaderSet.TYPE);
if (stringHeader != null) {
+ if (VDBG) Log.v(TAG," Add Header = " + HeaderSet.TYPE);
out.write((byte)HeaderSet.TYPE);
try {
value = stringHeader.getBytes("ISO8859_1");
@@ -442,6 +450,7 @@
// Length Header
intHeader = (Long)headImpl.getHeader(HeaderSet.LENGTH);
if (intHeader != null) {
+ if (VDBG) Log.v(TAG," Add Header = " + HeaderSet.LENGTH);
out.write((byte)HeaderSet.LENGTH);
value = ObexHelper.convertToByteArray(intHeader.longValue());
out.write(value);
@@ -453,7 +462,7 @@
// Time ISO Header
dateHeader = (Calendar)headImpl.getHeader(HeaderSet.TIME_ISO_8601);
if (dateHeader != null) {
-
+ if (VDBG) Log.v(TAG," Add dateHeader = " + HeaderSet.TIME_ISO_8601);
/*
* The ISO Header should take the form YYYYMMDDTHHMMSSZ. The
* 'Z' will only be included if it is a UTC time.
@@ -515,6 +524,7 @@
// Time 4 Byte Header
dateHeader = (Calendar)headImpl.getHeader(HeaderSet.TIME_4_BYTE);
if (dateHeader != null) {
+ if (VDBG) Log.v(TAG," Add dateHeader = " + HeaderSet.TIME_4_BYTE);
out.write(HeaderSet.TIME_4_BYTE);
/*
@@ -549,6 +559,7 @@
// Target Header
value = (byte[])headImpl.getHeader(HeaderSet.TARGET);
if (value != null) {
+ if (VDBG) Log.v(TAG," Add Header = " + HeaderSet.TARGET);
out.write((byte)HeaderSet.TARGET);
length = value.length + 3;
lengthArray[0] = (byte)(255 & (length >> 8));
@@ -577,6 +588,7 @@
// Who Header
value = (byte[])headImpl.getHeader(HeaderSet.WHO);
if (value != null) {
+ if (VDBG) Log.v(TAG," Add Header = " + HeaderSet.WHO);
out.write((byte)HeaderSet.WHO);
length = value.length + 3;
lengthArray[0] = (byte)(255 & (length >> 8));
@@ -591,6 +603,7 @@
// Connection ID Header
value = (byte[])headImpl.getHeader(HeaderSet.APPLICATION_PARAMETER);
if (value != null) {
+ if (VDBG) Log.v(TAG," Add APP PARAM Header = " + HeaderSet.APPLICATION_PARAMETER);
out.write((byte)HeaderSet.APPLICATION_PARAMETER);
length = value.length + 3;
lengthArray[0] = (byte)(255 & (length >> 8));
@@ -629,6 +642,7 @@
lengthArray[1] = (byte)(255 & length);
out.write(lengthArray);
out.write(value);
+ if (VDBG) Log.v(TAG," Add Unicode String value = " + value);
if (nullOut) {
headImpl.setHeader(i + 0x30, null);
}
@@ -643,6 +657,7 @@
lengthArray[1] = (byte)(255 & length);
out.write(lengthArray);
out.write(value);
+ if (VDBG) Log.v(TAG," Add ByteSeq value = " + value);
if (nullOut) {
headImpl.setHeader(i + 0x70, null);
}
@@ -653,6 +668,7 @@
if (byteHeader != null) {
out.write((byte)i + 0xB0);
out.write(byteHeader.byteValue());
+ if (VDBG) Log.v(TAG," Add ByteHeader value = " + byteHeader.byteValue());
if (nullOut) {
headImpl.setHeader(i + 0xB0, null);
}
@@ -663,6 +679,7 @@
if (intHeader != null) {
out.write((byte)i + 0xF0);
out.write(ObexHelper.convertToByteArray(intHeader.longValue()));
+ if (VDBG) Log.v(TAG," Add Int value = " + intHeader.longValue());
if (nullOut) {
headImpl.setHeader(i + 0xF0, null);
}
@@ -677,6 +694,7 @@
lengthArray[1] = (byte)(255 & length);
out.write(lengthArray);
out.write(headImpl.mAuthChall);
+ if (VDBG) Log.v(TAG," Add mAuthChall value = " + headImpl.mAuthChall);
if (nullOut) {
headImpl.mAuthChall = null;
}
@@ -690,6 +708,7 @@
lengthArray[1] = (byte)(255 & length);
out.write(lengthArray);
out.write(headImpl.mAuthResp);
+ if (VDBG) Log.v(TAG," Add mAuthChall value = " + headImpl.mAuthResp);
if (nullOut) {
headImpl.mAuthResp = null;
}
@@ -705,8 +724,10 @@
// Add the SRM header
byteHeader = (Byte)headImpl.getHeader(HeaderSet.SINGLE_RESPONSE_MODE);
if (byteHeader != null) {
+ if (VDBG) Log.v(TAG," Add SRM Header = " + HeaderSet.SINGLE_RESPONSE_MODE);
out.write((byte)HeaderSet.SINGLE_RESPONSE_MODE);
out.write(byteHeader.byteValue());
+ if (VDBG) Log.v(TAG," Add SRM value = " + byteHeader.byteValue());
if (nullOut) {
headImpl.setHeader(HeaderSet.SINGLE_RESPONSE_MODE, null);
}
@@ -715,6 +736,7 @@
// Add the SRM parameter header
byteHeader = (Byte)headImpl.getHeader(HeaderSet.SINGLE_RESPONSE_MODE_PARAMETER);
if (byteHeader != null) {
+ if (VDBG) Log.v(TAG," Add Header = " + HeaderSet.SINGLE_RESPONSE_MODE_PARAMETER);
out.write((byte)HeaderSet.SINGLE_RESPONSE_MODE_PARAMETER);
out.write(byteHeader.byteValue());
if (nullOut) {
diff --git a/obex/javax/obex/ServerOperation.java b/obex/javax/obex/ServerOperation.java
index 15ea367..1cc720b 100644
--- a/obex/javax/obex/ServerOperation.java
+++ b/obex/javax/obex/ServerOperation.java
@@ -57,7 +57,7 @@
*/
public final class ServerOperation implements Operation, BaseStream {
- private static final String TAG = "ServerOperation";
+ private static final String TAG = "ObexServerOperation";
private static final boolean V = ObexHelper.VDBG; // Verbose debugging
@@ -124,6 +124,7 @@
*/
public ServerOperation(ServerSession p, InputStream in, int request, int maxSize,
ServerRequestHandler listen) throws IOException {
+ if (V) Log.v(TAG, "ServerOperation");
isAborted = false;
mParent = p;
@@ -340,14 +341,17 @@
*/
public synchronized boolean continueOperation(boolean sendEmpty, boolean inStream)
throws IOException {
+ if (V) Log.v(TAG, "continueOperation");
if (!mGetOperation) {
if (!finalBitSet) {
if (sendEmpty) {
sendReply(ResponseCodes.OBEX_HTTP_CONTINUE);
+ if (V) Log.v(TAG, "continueOperation:ServerSet SRM sendEmpty clause");
return true;
} else {
if ((mResponseSize > 3) || (mPrivateOutput.size() > 0)) {
sendReply(ResponseCodes.OBEX_HTTP_CONTINUE);
+ if (V) Log.v(TAG, "continueOperation: Server setting SRM");
return true;
} else {
return false;
@@ -357,6 +361,7 @@
return false;
}
} else {
+ if (V) Log.v(TAG, "Get continueOperation ");
sendReply(ResponseCodes.OBEX_HTTP_CONTINUE);
return true;
}
@@ -405,6 +410,8 @@
bodyLength = mPrivateOutput.size();
orginalBodyLength = bodyLength;
}
+ if(V) Log.v(TAG, "mMaxPcKLen :" + mMaxPacketLength + " headerArryLen :"
+ + headerArray.length);
if ((ObexHelper.BASE_PACKET_LENGTH + headerArray.length) > mMaxPacketLength) {
diff --git a/obex/javax/obex/ServerSession.java b/obex/javax/obex/ServerSession.java
index dbfeefd..a45687f 100644
--- a/obex/javax/obex/ServerSession.java
+++ b/obex/javax/obex/ServerSession.java
@@ -63,6 +63,12 @@
private boolean mClosed;
+ private boolean setMTU = false;
+
+ private boolean updateMtu = false;
+
+ private int updatedMtuSize = 0;
+
/**
* Creates new ServerSession.
* @param trans the connection to the client
@@ -85,6 +91,25 @@
mProcessThread.start();
}
+ public void setMaxPacketSize(int size) {
+ if (V) Log.v(TAG, "setMaxPacketSize" + size);
+ mMaxPacketLength = size;
+ }
+
+ public int getMaxPacketSize() {
+ return mMaxPacketLength;
+ }
+
+ public void reduceMTU(boolean enable) {
+ setMTU = enable;
+ }
+
+ public void updateMTU(int mtuSize) {
+ updateMtu = true;
+ updatedMtuSize = mtuSize;
+ Log.i(TAG,"updateMTU: " + mtuSize);
+ }
+
/**
* Processes requests made to the server and forwards them to the
* appropriate event listener.
@@ -124,6 +149,7 @@
break;
case -1:
+ Log.d(TAG, "Read request returned -1, exiting from loop");
done = true;
break;
@@ -194,6 +220,7 @@
* @throws IOException if an error occurred at the transport layer
*/
private void handlePutRequest(int type) throws IOException {
+ if (V) Log.v(TAG, "handlePutRequest");
ServerOperation op = new ServerOperation(this, mInput, type, mMaxPacketLength, mListener);
try {
int response = -1;
@@ -205,10 +232,12 @@
response = validateResponseCode(mListener.onPut(op));
}
if (response != ResponseCodes.OBEX_HTTP_OK && !op.isAborted) {
+ if (V) Log.v(TAG, "handlePutRequest pre != HTTP_OK sendReply");
op.sendReply(response);
} else if (!op.isAborted) {
// wait for the final bit
while (!op.finalBitSet) {
+ if (V) Log.v(TAG, "handlePutRequest pre looped sendReply");
op.sendReply(ResponseCodes.OBEX_HTTP_CONTINUE);
}
op.sendReply(response);
@@ -240,6 +269,7 @@
* @throws IOException if an error occurred at the transport layer
*/
private void handleGetRequest(int type) throws IOException {
+ if (V) Log.v(TAG, "handleGetRequest");
ServerOperation op = new ServerOperation(this, mInput, type, mMaxPacketLength, mListener);
try {
int response = validateResponseCode(mListener.onGet(op));
@@ -262,6 +292,7 @@
public void sendResponse(int code, byte[] header) throws IOException {
int totalLength = 3;
byte[] data = null;
+ if (V) Log.v(TAG,"sendResponse code " + code + " header : " + header);
OutputStream op = mOutput;
if (op == null) {
return;
@@ -269,6 +300,7 @@
if (header != null) {
totalLength += header.length;
+ if (V) Log.v(TAG, "header != null totalLength = " + totalLength);
data = new byte[totalLength];
data[0] = (byte)code;
data[1] = (byte)(totalLength >> 8);
@@ -558,9 +590,19 @@
+ " MaxLength: " + mMaxPacketLength + " flags: " + flags);
// should we check it?
- if (mMaxPacketLength > ObexHelper.MAX_PACKET_SIZE_INT) {
+ if (setMTU) {
+ mMaxPacketLength = ObexHelper.A2DP_SCO_OBEX_MAX_CLIENT_PACKET_SIZE;
+ setMTU = false;
+ } else if (updateMtu) {
+ Log.d(TAG, "mMaxPacketLength: " + mMaxPacketLength +
+ ", updatedMtuSize: " + updatedMtuSize);
+ if (mMaxPacketLength > updatedMtuSize)
+ mMaxPacketLength = updatedMtuSize;
+ updateMtu = false;
+ } else if (mMaxPacketLength > ObexHelper.MAX_PACKET_SIZE_INT) {
mMaxPacketLength = ObexHelper.MAX_PACKET_SIZE_INT;
}
+ Log.d(TAG,"handleConnectRequest() - Updated MaxPacketLengh: " + mMaxPacketLength);
if(mMaxPacketLength > ObexHelper.getMaxTxPacketSize(mTransport)) {
Log.w(TAG, "Requested MaxObexPacketSize " + mMaxPacketLength
diff --git a/packages/BackupRestoreConfirmation/AndroidManifest.xml b/packages/BackupRestoreConfirmation/AndroidManifest.xml
index e67b3be..aede459 100644
--- a/packages/BackupRestoreConfirmation/AndroidManifest.xml
+++ b/packages/BackupRestoreConfirmation/AndroidManifest.xml
@@ -21,6 +21,7 @@
<uses-permission android:name="android.permission.BACKUP" />
<uses-permission android:name="android.permission.CRYPT_KEEPER" />
+ <uses-permission android:name="android.permission.STORAGE_INTERNAL"/>
<application android:allowClearUserData="false"
android:allowBackup="false"
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
index 5054281..6fab9e4 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
@@ -106,6 +106,7 @@
webSettings.setSupportZoom(true);
webSettings.setBuiltInZoomControls(true);
webSettings.setDomStorageEnabled(true);
+ webSettings.setAllowFileAccess(false);
mWebViewClient = new MyWebViewClient();
mWebView.setWebViewClient(mWebViewClient);
mWebView.setWebChromeClient(new MyWebChromeClient());
diff --git a/packages/PackageInstaller/res/layout/install_content_view.xml b/packages/PackageInstaller/res/layout/install_content_view.xml
index 5e94a29..bcd5f16 100644
--- a/packages/PackageInstaller/res/layout/install_content_view.xml
+++ b/packages/PackageInstaller/res/layout/install_content_view.xml
@@ -69,29 +69,71 @@
</LinearLayout>
- <TextView
- android:id="@+id/install_confirm_question"
- android:layout_width="wrap_content"
+ <LinearLayout
+ android:id="@+id/updating_app_view"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- style="@android:style/TextAppearance.Material.Subhead"
- android:text="@string/install_confirm_question"
- android:visibility="invisible" />
+ android:orientation="vertical"
+ android:visibility="invisible">
- <TextView
- android:id="@+id/install_confirm_question_update"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- style="@android:style/TextAppearance.Material.Subhead"
- android:text="@string/install_confirm_question_update"
- android:visibility="invisible" />
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:theme="?android:attr/alertDialogTheme"
+ android:paddingTop="4dp"
+ android:paddingLeft="?android:attr/dialogPreferredPadding"
+ android:paddingRight="?android:attr/dialogPreferredPadding">
- <TextView
- android:id="@+id/install_confirm_question_update_system"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- style="@android:style/TextAppearance.Material.Subhead"
- android:text="@string/install_confirm_question_update_system"
- android:visibility="invisible" />
+ <TextView
+ android:id="@+id/install_confirm_question"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ style="@android:style/TextAppearance.Material.Subhead"
+ android:text="@string/install_confirm_question"
+ android:visibility="invisible" />
+
+ <TextView
+ android:id="@+id/install_confirm_question_update"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ style="@android:style/TextAppearance.Material.Subhead"
+ android:text="@string/install_confirm_question_update"
+ android:visibility="invisible" />
+
+ <TextView
+ android:id="@+id/install_confirm_question_update_system"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ style="@android:style/TextAppearance.Material.Subhead"
+ android:text="@string/install_confirm_question_update_system"
+ android:visibility="invisible" />
+ </FrameLayout>
+
+ <LinearLayout
+ android:id="@+id/version_view"
+ android:paddingTop="8dp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingLeft="?android:attr/dialogPreferredPadding"
+ android:paddingRight="?android:attr/dialogPreferredPadding">
+ <TextView
+ android:id="@+id/installed_app_version"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ style="@android:style/TextAppearance.Material.Small"
+ android:text="@string/old_version_number"
+ android:visibility="gone" />
+
+ <TextView
+ android:id="@+id/updating_app_version"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ style="@android:style/TextAppearance.Material.Small"
+ android:text="@string/new_version_number"
+ android:visibility="invisible" />
+ </LinearLayout>
+ </LinearLayout>
<TextView
android:id="@+id/install_success"
diff --git a/packages/PackageInstaller/res/values-it/custom_strings.xml b/packages/PackageInstaller/res/values-it/custom_strings.xml
new file mode 100644
index 0000000..f15dcad
--- /dev/null
+++ b/packages/PackageInstaller/res/values-it/custom_strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 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.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Message for updating an existing app [CHAR LIMIT=NONE] -->
+ <string name="old_version_number">Versione installata: <xliff:g id="old_version">%1$s</xliff:g></string>
+ <!-- Message for updating an existing system app [CHAR LIMIT=NONE] -->
+ <string name="new_version_number">Da installare: <xliff:g id="new_version">%1$s</xliff:g></string>
+</resources>
diff --git a/packages/PackageInstaller/res/values/custom_strings.xml b/packages/PackageInstaller/res/values/custom_strings.xml
new file mode 100644
index 0000000..bb99ab0
--- /dev/null
+++ b/packages/PackageInstaller/res/values/custom_strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 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.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Message for updating an existing app [CHAR LIMIT=NONE] -->
+ <string name="old_version_number">Installed version: <xliff:g id="old_version">%1$s</xliff:g></string>
+ <!-- Message for updating an existing system app [CHAR LIMIT=NONE] -->
+ <string name="new_version_number">To be installed: <xliff:g id="new_version">%1$s</xliff:g></string>
+</resources>
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
index 5675c99..5cd39ff 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
@@ -46,6 +46,7 @@
import android.util.Log;
import android.view.View;
import android.widget.Button;
+import android.widget.TextView;
import com.android.internal.app.AlertActivity;
@@ -117,19 +118,29 @@
// Would the mOk button be enabled if this activity would be resumed
private boolean mEnableOk = false;
- private void startInstallConfirm() {
- View viewToEnable;
+ private void startInstallConfirm(PackageInfo oldInfo) {
+ requireViewById(R.id.updating_app_view).setVisibility(View.VISIBLE); // the main layout
+ View viewToEnable; // which install_confirm view to show
+ View oldVersionView;
+ View newVersionView;
if (mAppInfo != null) {
viewToEnable = (mAppInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0
? requireViewById(R.id.install_confirm_question_update_system)
: requireViewById(R.id.install_confirm_question_update);
+ oldVersionView = requireViewById(R.id.installed_app_version);
+ ((TextView)oldVersionView).setText(
+ getString(R.string.old_version_number, oldInfo.versionName));
+ oldVersionView.setVisibility(View.VISIBLE);
} else {
// This is a new application with no permissions.
viewToEnable = requireViewById(R.id.install_confirm_question);
}
-
+ newVersionView = requireViewById(R.id.updating_app_version);
+ ((TextView)newVersionView).setText(
+ getString(R.string.new_version_number, mPkgInfo.versionName));
viewToEnable.setVisibility(View.VISIBLE);
+ newVersionView.setVisibility(View.VISIBLE);
mEnableOk = true;
mOk.setEnabled(true);
@@ -255,20 +266,22 @@
mPkgInfo.applicationInfo.packageName = pkgName;
}
// Check if package is already installed. display confirmation dialog if replacing pkg
+ PackageInfo oldPackageInfo = null;
try {
// This is a little convoluted because we want to get all uninstalled
// apps, but this may include apps with just data, and if it is just
// data we still want to count it as "installed".
- mAppInfo = mPm.getApplicationInfo(pkgName,
+ oldPackageInfo = mPm.getPackageInfo(pkgName,
PackageManager.MATCH_UNINSTALLED_PACKAGES);
- if ((mAppInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
+ mAppInfo = oldPackageInfo.applicationInfo;
+ if (mAppInfo != null && (mAppInfo.flags & ApplicationInfo.FLAG_INSTALLED) == 0) {
mAppInfo = null;
}
} catch (NameNotFoundException e) {
mAppInfo = null;
}
- startInstallConfirm();
+ startInstallConfirm(oldPackageInfo);
}
void setPmResult(int pmResult) {
diff --git a/packages/SettingsLib/res/values-af/arrays.xml b/packages/SettingsLib/res/values-af/arrays.xml
index 93f00e7..09c41c0 100644
--- a/packages/SettingsLib/res/values-af/arrays.xml
+++ b/packages/SettingsLib/res/values-af/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>-oudio"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>-oudio"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>-oudio"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>-oudio"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Gebruik stelselkeuse (verstek)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>-oudio"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>-oudio"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>-oudio"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>-oudio"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Gebruik stelselkeuse (verstek)"</item>
diff --git a/packages/SettingsLib/res/values-am/arrays.xml b/packages/SettingsLib/res/values-am/arrays.xml
index 18696b1..759e38b 100644
--- a/packages/SettingsLib/res/values-am/arrays.xml
+++ b/packages/SettingsLib/res/values-am/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ኦዲዮ"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> ኦዲዮ"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> ኦዲዮ"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> ኦዲዮ"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"የስርዓቱን ምርጫ (ነባሪ) ተጠቀም"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ኦዲዮ"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> ኦዲዮ"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> ኦዲዮ"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> ኦዲዮ"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"የስርዓቱን ምርጫ (ነባሪ) ተጠቀም"</item>
diff --git a/packages/SettingsLib/res/values-ar/arrays.xml b/packages/SettingsLib/res/values-ar/arrays.xml
index d09b50e..2da634e 100644
--- a/packages/SettingsLib/res/values-ar/arrays.xml
+++ b/packages/SettingsLib/res/values-ar/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"صوت <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="2908219194098827570">"صوت <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"ﺹﻮﺗ <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049225">"ﺹﻮﺗ <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"استخدام اختيار النظام (تلقائي)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"صوت <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="3517061573669307965">"صوت <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"ﺹﻮﺗ <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049481">"ﺹﻮﺗ <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"استخدام اختيار النظام (تلقائي)"</item>
diff --git a/packages/SettingsLib/res/values-as/arrays.xml b/packages/SettingsLib/res/values-as/arrays.xml
index b619d3b..6cd0491 100644
--- a/packages/SettingsLib/res/values-as/arrays.xml
+++ b/packages/SettingsLib/res/values-as/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> অডিঅ\'"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> অডিঅ’"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> অডিঅ\'"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> অডিঅ\'""</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"ছিষ্টেমৰ বাছনি ব্যৱহাৰ কৰক (ডিফ\'ল্ট)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> অডিঅ’"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> অডিঅ’"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> অডিঅ\'"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> অডিঅ\'""</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"ছিষ্টেমৰ বাছনি ব্যৱহাৰ কৰক (ডিফ\'ল্ট)"</item>
diff --git a/packages/SettingsLib/res/values-az/arrays.xml b/packages/SettingsLib/res/values-az/arrays.xml
index 55ec9d8..e0f9f15 100644
--- a/packages/SettingsLib/res/values-az/arrays.xml
+++ b/packages/SettingsLib/res/values-az/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> audio"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> audio"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> audio"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> audio"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Sistem Seçimini istifadə edin (Defolt)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> audio"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> audio"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> audio"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> audio"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Sistem Seçimini istifadə edin (Defolt)"</item>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml b/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
index 2926067..b14e86e 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> audio"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> audio"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> audio"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> audio"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Koristi izbor sistema (podrazumevano)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> audio"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> audio"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> audio"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> audio"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Koristi izbor sistema (podrazumevano)"</item>
diff --git a/packages/SettingsLib/res/values-be/arrays.xml b/packages/SettingsLib/res/values-be/arrays.xml
index af3a161..1a399a5 100644
--- a/packages/SettingsLib/res/values-be/arrays.xml
+++ b/packages/SettingsLib/res/values-be/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"Аўдыя <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="2908219194098827570">"Аўдыя <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"Аўдыя <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049225">"Аўдыя <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Выбар сістэмы (стандартны)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"Аўдыя <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="3517061573669307965">"Аўдыя <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"Аўдыя <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049481">"Аўдыя <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Выбар сістэмы (стандартны)"</item>
diff --git a/packages/SettingsLib/res/values-bg/arrays.xml b/packages/SettingsLib/res/values-bg/arrays.xml
index 1b25bed..96c2c2330 100644
--- a/packages/SettingsLib/res/values-bg/arrays.xml
+++ b/packages/SettingsLib/res/values-bg/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"Аудио: <xliff:g id="APTX">aptX™</xliff:g> от <xliff:g id="QUALCOMM">Qualcomm®</xliff:g>"</item>
<item msgid="2908219194098827570">"Аудио: <xliff:g id="APTX_HD">aptX™ HD</xliff:g> от <xliff:g id="QUALCOMM">Qualcomm®</xliff:g>"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"Аудио: <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049225">"Аудио: <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Използване на сист. избор (стандартно)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"Аудио: <xliff:g id="APTX">aptX™</xliff:g> от <xliff:g id="QUALCOMM">Qualcomm®</xliff:g>"</item>
<item msgid="3517061573669307965">"Аудио: <xliff:g id="APTX_HD">aptX™ HD</xliff:g> от <xliff:g id="QUALCOMM">Qualcomm®</xliff:g>"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"Аудио: <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049481">"Аудио: <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Използване на сист. избор (стандартно)"</item>
diff --git a/packages/SettingsLib/res/values-bn/arrays.xml b/packages/SettingsLib/res/values-bn/arrays.xml
index 34cbc8f..f596194 100644
--- a/packages/SettingsLib/res/values-bn/arrays.xml
+++ b/packages/SettingsLib/res/values-bn/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> অডিও"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> অডিও"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> অডিওa"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> অডিও"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"সিস্টেমের নির্বাচন ব্যবহার করুন (ডিফল্ট)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> অডিও"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> অডিও"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> অডিওa"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> অডিও"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"সিস্টেমের নির্বাচন ব্যবহার করুন (ডিফল্ট)"</item>
diff --git a/packages/SettingsLib/res/values-bs/arrays.xml b/packages/SettingsLib/res/values-bs/arrays.xml
index 6d2f1f3..bf07483 100644
--- a/packages/SettingsLib/res/values-bs/arrays.xml
+++ b/packages/SettingsLib/res/values-bs/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> audio"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> audio"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> audio"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> audio"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Korištenje odabira sistema (zadano)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> audio"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> audio"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> audio"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> audio"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Korištenje odabira sistema (zadano)"</item>
diff --git a/packages/SettingsLib/res/values-ca/arrays.xml b/packages/SettingsLib/res/values-ca/arrays.xml
index 4b24637..059f044 100644
--- a/packages/SettingsLib/res/values-ca/arrays.xml
+++ b/packages/SettingsLib/res/values-ca/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"Àudio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="2908219194098827570">"Àudio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"Àudio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049225">"Àudio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Utilitza selecció del sistema (predeterminada)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"Àudio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="3517061573669307965">"Àudio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"Àudio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049481">"Àudio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Utilitza selecció del sistema (predeterminada)"</item>
diff --git a/packages/SettingsLib/res/values-cs/arrays.xml b/packages/SettingsLib/res/values-cs/arrays.xml
index 27dce16..8d3f29e 100644
--- a/packages/SettingsLib/res/values-cs/arrays.xml
+++ b/packages/SettingsLib/res/values-cs/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"Zvuk <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="2908219194098827570">"Zvuk <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"Zvuk <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049225">"Zvuk <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Použít systémový výběr (výchozí)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"Zvuk <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="3517061573669307965">"Zvuk <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"Zvuk <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049481">"Zvuk <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Použít systémový výběr (výchozí)"</item>
diff --git a/packages/SettingsLib/res/values-da/arrays.xml b/packages/SettingsLib/res/values-da/arrays.xml
index efe4150..c995df7 100644
--- a/packages/SettingsLib/res/values-da/arrays.xml
+++ b/packages/SettingsLib/res/values-da/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>-lyd"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>-lyd"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>-lyd"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>-lyd"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Brug systemvalg (standard)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>-lyd"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>-lyd"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>-lyd"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>-lyd"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Brug systemvalg (standard)"</item>
diff --git a/packages/SettingsLib/res/values-de/arrays.xml b/packages/SettingsLib/res/values-de/arrays.xml
index e7c4887..b31b105 100644
--- a/packages/SettingsLib/res/values-de/arrays.xml
+++ b/packages/SettingsLib/res/values-de/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>-Audio"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>-Audio"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>-Audio"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>-Audio"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Systemauswahl verwenden (Standard)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>-Audio"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>-Audio"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>-Audio"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>-Audio"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Systemauswahl verwenden (Standard)"</item>
diff --git a/packages/SettingsLib/res/values-el/arrays.xml b/packages/SettingsLib/res/values-el/arrays.xml
index 838ca79..bb6af4d 100644
--- a/packages/SettingsLib/res/values-el/arrays.xml
+++ b/packages/SettingsLib/res/values-el/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"Ήχος <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="2908219194098827570">"Ήχος <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"Ήχος <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049225">"Ήχος <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Χρήση επιλογής συστήματος (Προεπιλογή)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"Ήχος <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="3517061573669307965">"Ήχος <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"Ήχος <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049481">"Ήχος <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Χρήση επιλογής συστήματος (Προεπιλογή)"</item>
diff --git a/packages/SettingsLib/res/values-en-rAU/arrays.xml b/packages/SettingsLib/res/values-en-rAU/arrays.xml
index 6569f18..ab38e22 100644
--- a/packages/SettingsLib/res/values-en-rAU/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rAU/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> audio"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> audio"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> audio"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> audio"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Use system selection (default)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> audio"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> audio"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> audio"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> audio"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Use system selection (default)"</item>
diff --git a/packages/SettingsLib/res/values-en-rCA/arrays.xml b/packages/SettingsLib/res/values-en-rCA/arrays.xml
index 6569f18..ab38e22 100644
--- a/packages/SettingsLib/res/values-en-rCA/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rCA/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> audio"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> audio"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> audio"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> audio"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Use system selection (default)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> audio"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> audio"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> audio"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> audio"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Use system selection (default)"</item>
diff --git a/packages/SettingsLib/res/values-en-rIN/arrays.xml b/packages/SettingsLib/res/values-en-rIN/arrays.xml
index 6569f18..ab38e22 100644
--- a/packages/SettingsLib/res/values-en-rIN/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rIN/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> audio"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> audio"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> audio"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> audio"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Use system selection (default)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> audio"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> audio"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> audio"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> audio"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Use system selection (default)"</item>
diff --git a/packages/SettingsLib/res/values-en-rXC/arrays.xml b/packages/SettingsLib/res/values-en-rXC/arrays.xml
index cb702fe..3392c5e 100644
--- a/packages/SettingsLib/res/values-en-rXC/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rXC/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> audio"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> audio"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> audio"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> audio"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Use System Selection (Default)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> audio"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> audio"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> audio"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> audio"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Use System Selection (Default)"</item>
diff --git a/packages/SettingsLib/res/values-es-rUS/arrays.xml b/packages/SettingsLib/res/values-es-rUS/arrays.xml
index cfce9b6..3d9ced2 100644
--- a/packages/SettingsLib/res/values-es-rUS/arrays.xml
+++ b/packages/SettingsLib/res/values-es-rUS/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="2908219194098827570">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049225">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Usar selección del sistema (predeterminado)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="3517061573669307965">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049481">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Usar selección del sistema (predeterminado)"</item>
diff --git a/packages/SettingsLib/res/values-es/arrays.xml b/packages/SettingsLib/res/values-es/arrays.xml
index 5682dd5..c746519 100644
--- a/packages/SettingsLib/res/values-es/arrays.xml
+++ b/packages/SettingsLib/res/values-es/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="2908219194098827570">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049225">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Usar preferencia del sistema (predeterminado)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="3517061573669307965">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049481">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Usar preferencia del sistema (predeterminado)"</item>
diff --git a/packages/SettingsLib/res/values-et/arrays.xml b/packages/SettingsLib/res/values-et/arrays.xml
index 9015cfe..306e7db 100644
--- a/packages/SettingsLib/res/values-et/arrays.xml
+++ b/packages/SettingsLib/res/values-et/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"Heli: <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="2908219194098827570">"Heli: <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"Heli: <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049225">"Heli: <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Süsteemi valiku kasutamine (vaikeseade)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"Heli: <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="3517061573669307965">"Heli: <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"Heli: <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049481">"Heli: <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Süsteemi valiku kasutamine (vaikeseade)"</item>
diff --git a/packages/SettingsLib/res/values-eu/arrays.xml b/packages/SettingsLib/res/values-eu/arrays.xml
index 0e94bba..1be9ebd 100644
--- a/packages/SettingsLib/res/values-eu/arrays.xml
+++ b/packages/SettingsLib/res/values-eu/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> audioa"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> audioa"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> audioa"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> audioa"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Erabili sistema-hautapena (lehenetsia)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> audioa"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> audioa"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> audioa"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> audioa"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Erabili sistema-hautapena (lehenetsia)"</item>
diff --git a/packages/SettingsLib/res/values-fa/arrays.xml b/packages/SettingsLib/res/values-fa/arrays.xml
index 075f7e0..d38642a 100644
--- a/packages/SettingsLib/res/values-fa/arrays.xml
+++ b/packages/SettingsLib/res/values-fa/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"صوت <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="2908219194098827570">"صوت <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"ﺹﻮﺗ <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049225">"ﺹﻮﺗ <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"استفاده از انتخاب سیستم (پیشفرض)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"صوت <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="3517061573669307965">"صوت <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"ﺹﻮﺗ <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049481">"ﺹﻮﺗ <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"استفاده از انتخاب سیستم (پیشفرض)"</item>
diff --git a/packages/SettingsLib/res/values-fi/arrays.xml b/packages/SettingsLib/res/values-fi/arrays.xml
index d233c56..f217d13 100644
--- a/packages/SettingsLib/res/values-fi/arrays.xml
+++ b/packages/SettingsLib/res/values-fi/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ‑ääni"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> ‑ääni"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> ‑ääni"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> ‑ääni"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Käytä järjestelmän valintaa (oletus)."</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ‑ääni"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> ‑ääni"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> ‑ääni"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> ‑ääni"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Käytä järjestelmän valintaa (oletus)."</item>
diff --git a/packages/SettingsLib/res/values-fr-rCA/arrays.xml b/packages/SettingsLib/res/values-fr-rCA/arrays.xml
index 1db6540..4f93fe4 100644
--- a/packages/SettingsLib/res/values-fr-rCA/arrays.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="2908219194098827570">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049225">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Utiliser sélect. du système (par défaut)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="3517061573669307965">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049481">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Utiliser sélect. du système (par défaut)"</item>
diff --git a/packages/SettingsLib/res/values-fr/arrays.xml b/packages/SettingsLib/res/values-fr/arrays.xml
index 7660925..33ed58b 100644
--- a/packages/SettingsLib/res/values-fr/arrays.xml
+++ b/packages/SettingsLib/res/values-fr/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="2908219194098827570">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049225">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Utiliser la sélection du système (par défaut)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="3517061573669307965">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049481">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Utiliser la sélection du système (par défaut)"</item>
diff --git a/packages/SettingsLib/res/values-gl/arrays.xml b/packages/SettingsLib/res/values-gl/arrays.xml
index 98f2072..e821c21 100644
--- a/packages/SettingsLib/res/values-gl/arrays.xml
+++ b/packages/SettingsLib/res/values-gl/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="2908219194098827570">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049225">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Usa a selección do sistema (predeterminado)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="3517061573669307965">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049481">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Usar selección do sistema (predeterminado)"</item>
diff --git a/packages/SettingsLib/res/values-gu/arrays.xml b/packages/SettingsLib/res/values-gu/arrays.xml
index 1a3bf98..b613cd9 100644
--- a/packages/SettingsLib/res/values-gu/arrays.xml
+++ b/packages/SettingsLib/res/values-gu/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ઑડિયો"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> ઑડિયો"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> ઑડિઓ"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> ઑડિઓ"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"સિસ્ટમ પસંદગીનો ઉપયોગ કરો (ડિફૉલ્ટ)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ઑડિયો"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> ઑડિયો"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> ઑડિઓ"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> ઑડિઓ"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"સિસ્ટમ પસંદગીનો ઉપયોગ કરો (ડિફૉલ્ટ)"</item>
diff --git a/packages/SettingsLib/res/values-hi/arrays.xml b/packages/SettingsLib/res/values-hi/arrays.xml
index 36b16e6..06e0353 100644
--- a/packages/SettingsLib/res/values-hi/arrays.xml
+++ b/packages/SettingsLib/res/values-hi/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ऑडियो"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> ऑडियो"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>ऑडियो"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> ऑडियो"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"सिस्टम से चुने जाने का उपयोग करें (डिफ़ॉल्ट)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ऑडियो"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> ऑडियो"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>ऑडियो"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> ऑडियो"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"सिस्टम से चुने जाने का उपयोग करें (डिफ़ॉल्ट)"</item>
diff --git a/packages/SettingsLib/res/values-hr/arrays.xml b/packages/SettingsLib/res/values-hr/arrays.xml
index 82a1e4a..c5bab1a 100644
--- a/packages/SettingsLib/res/values-hr/arrays.xml
+++ b/packages/SettingsLib/res/values-hr/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> audio"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> audio"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> audio"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> audio"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Upotreba odabira sustava (zadano)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> audio"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> audio"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> audio"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> audio"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Upotreba odabira sustava (zadano)"</item>
diff --git a/packages/SettingsLib/res/values-hu/arrays.xml b/packages/SettingsLib/res/values-hu/arrays.xml
index d043af0..1b4befa 100644
--- a/packages/SettingsLib/res/values-hu/arrays.xml
+++ b/packages/SettingsLib/res/values-hu/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"Hang: <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="2908219194098827570">"Hang: <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"Hang: <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049225">"Hang: <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Rendszerérték (alapértelmezett)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"Hang: <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="3517061573669307965">"Hang: <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"Hang: <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049481">"Hang: <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Rendszerérték (alapértelmezett)"</item>
diff --git a/packages/SettingsLib/res/values-hy/arrays.xml b/packages/SettingsLib/res/values-hy/arrays.xml
index a279872..9b55f4e 100644
--- a/packages/SettingsLib/res/values-hy/arrays.xml
+++ b/packages/SettingsLib/res/values-hy/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> աուդիո"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> աուդիո"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> աուդիո"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> աուդիո"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Օգտագործել համակարգի կարգավորումը (կանխադրված)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> աուդիո"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> աուդիո"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> աուդիո"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> աուդիո"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Օգտագործել համակարգի կարգավորումը (կանխադրված)"</item>
diff --git a/packages/SettingsLib/res/values-in/arrays.xml b/packages/SettingsLib/res/values-in/arrays.xml
index 3ab50cc..c14659b 100644
--- a/packages/SettingsLib/res/values-in/arrays.xml
+++ b/packages/SettingsLib/res/values-in/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="2908219194098827570">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049225">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Gunakan Pilihan Sistem (Default)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="3517061573669307965">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049481">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Gunakan Pilihan Sistem (Default)"</item>
diff --git a/packages/SettingsLib/res/values-is/arrays.xml b/packages/SettingsLib/res/values-is/arrays.xml
index 93274e4..ddb4506 100644
--- a/packages/SettingsLib/res/values-is/arrays.xml
+++ b/packages/SettingsLib/res/values-is/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> hljóð"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> hljóð"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> hljóð"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> hljóð"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Nota val kerfisins (sjálfgefið)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> hljóð"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> hljóð"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> hljóð"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> hljóð"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Nota val kerfisins (sjálfgefið)"</item>
diff --git a/packages/SettingsLib/res/values-it/arrays.xml b/packages/SettingsLib/res/values-it/arrays.xml
index 57c0c9b..6f7ea19 100644
--- a/packages/SettingsLib/res/values-it/arrays.xml
+++ b/packages/SettingsLib/res/values-it/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="2908219194098827570">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049225">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Usa selezione di sistema (predefinita)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="3517061573669307965">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049481">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Usa selezione di sistema (predefinita)"</item>
diff --git a/packages/SettingsLib/res/values-iw/arrays.xml b/packages/SettingsLib/res/values-iw/arrays.xml
index fa53ab8..86d8bde 100644
--- a/packages/SettingsLib/res/values-iw/arrays.xml
+++ b/packages/SettingsLib/res/values-iw/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"אודיו <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="2908219194098827570">"אודיו <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"אודיו <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049225">"אודיו <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"השתמש בבחירת המערכת (ברירת המחדל)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"אודיו <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="3517061573669307965">"אודיו <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"אודיו <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049481">"אודיו <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"שימוש בבחירת המערכת (ברירת המחדל)"</item>
diff --git a/packages/SettingsLib/res/values-ja/arrays.xml b/packages/SettingsLib/res/values-ja/arrays.xml
index 7a4e71b..b70fffe 100644
--- a/packages/SettingsLib/res/values-ja/arrays.xml
+++ b/packages/SettingsLib/res/values-ja/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> オーディオ"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> オーディオ"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> オーディオ"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> オーディオ"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"システムの選択(デフォルト)を使用"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> オーディオ"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> オーディオ"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> オーディオ"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> オーディオ"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"システムの選択(デフォルト)を使用"</item>
diff --git a/packages/SettingsLib/res/values-ka/arrays.xml b/packages/SettingsLib/res/values-ka/arrays.xml
index 935cc46..4b44d52 100644
--- a/packages/SettingsLib/res/values-ka/arrays.xml
+++ b/packages/SettingsLib/res/values-ka/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> აუდიო"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> აუდიო"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> აუდიო"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> აუდიო"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"სისტემის არჩეულის გამოყენება (ნაგულისხმევი)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> აუდიო"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> აუდიო"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> აუდიო"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> აუდიო"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"სისტემის არჩეულის გამოყენება (ნაგულისხმევი)"</item>
diff --git a/packages/SettingsLib/res/values-kk/arrays.xml b/packages/SettingsLib/res/values-kk/arrays.xml
index faa8af8..a848507 100644
--- a/packages/SettingsLib/res/values-kk/arrays.xml
+++ b/packages/SettingsLib/res/values-kk/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> аудиокодегі"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> аудиокодегі"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> аудиокодегі"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> аудиокодегі"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Жүйенің таңдағанын алу (әдепкі)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> аудиокодегі"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> аудиокодегі"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> аудиокодегі"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> аудиокодегі"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Жүйенің таңдағанын алу (әдепкі)"</item>
diff --git a/packages/SettingsLib/res/values-km/arrays.xml b/packages/SettingsLib/res/values-km/arrays.xml
index 6f4589e..8965ff1 100644
--- a/packages/SettingsLib/res/values-km/arrays.xml
+++ b/packages/SettingsLib/res/values-km/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g>សំឡេង <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g>សំឡេង <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"ប្រើការជ្រើសរើសប្រព័ន្ធ (លំនាំដើម)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g>សំឡេង <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g>សំឡេង <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"ប្រើការជ្រើសរើសប្រព័ន្ធ (លំនាំដើម)"</item>
diff --git a/packages/SettingsLib/res/values-kn/arrays.xml b/packages/SettingsLib/res/values-kn/arrays.xml
index 7e543dd..3a49e0c 100644
--- a/packages/SettingsLib/res/values-kn/arrays.xml
+++ b/packages/SettingsLib/res/values-kn/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ಆಡಿಯೋ"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> ಆಡಿಯೋ"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> ಆಡಿಯೋ"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> ಆಡಿಯೋ"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"ಸಿಸ್ಟಂ ಆಯ್ಕೆಯನ್ನು ಬಳಸಿ (ಡಿಫಾಲ್ಟ್)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ಆಡಿಯೋ"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> ಆಡಿಯೋ"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> ಆಡಿಯೋ"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> ಆಡಿಯೋ"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"ಸಿಸ್ಟಂ ಆಯ್ಕೆಯನ್ನು ಬಳಸಿ (ಡಿಫಾಲ್ಟ್)"</item>
diff --git a/packages/SettingsLib/res/values-ko/arrays.xml b/packages/SettingsLib/res/values-ko/arrays.xml
index 9a18c16..547030d 100644
--- a/packages/SettingsLib/res/values-ko/arrays.xml
+++ b/packages/SettingsLib/res/values-ko/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> 오디오"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> 오디오"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> 오디오"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> 오디오"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"시스템 설정 사용(기본)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> 오디오"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> 오디오"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> 오디오"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> 오디오"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"시스템 설정 사용(기본)"</item>
diff --git a/packages/SettingsLib/res/values-ky/arrays.xml b/packages/SettingsLib/res/values-ky/arrays.xml
index f5e812d..fe0f9e6 100644
--- a/packages/SettingsLib/res/values-ky/arrays.xml
+++ b/packages/SettingsLib/res/values-ky/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> аудио"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> аудио"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> аудио"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> аудио"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Тутум тандаганды колдонуу (демейки)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> аудио"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> аудио"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> аудио"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> аудио"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Тутум тандаганды колдонуу (демейки)"</item>
diff --git a/packages/SettingsLib/res/values-lo/arrays.xml b/packages/SettingsLib/res/values-lo/arrays.xml
index a0fb2b8..ab258c1 100644
--- a/packages/SettingsLib/res/values-lo/arrays.xml
+++ b/packages/SettingsLib/res/values-lo/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"ສຽງ <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="2908219194098827570">"ສຽງ <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"ສຽງ <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049225">"ສຽງ <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"ໃຊ້ການເລືອກຂອງລະບົບ (ຄ່າເລີ່ມຕົ້ນ)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"ສຽງ <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="3517061573669307965">"ສຽງ <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"ສຽງ <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049481">"ສຽງ <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"ໃຊ້ການເລືອກຂອງລະບົບ (ຄ່າເລີ່ມຕົ້ນ)"</item>
diff --git a/packages/SettingsLib/res/values-lt/arrays.xml b/packages/SettingsLib/res/values-lt/arrays.xml
index 90a77bf..da8cea0 100644
--- a/packages/SettingsLib/res/values-lt/arrays.xml
+++ b/packages/SettingsLib/res/values-lt/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> garsas"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> garsas"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> garsas"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> garsas"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Naudoti sistemos pasirink. (numatytasis)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> garsas"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> garsas"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> garsas"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> garsas"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Naudoti sistemos pasirink. (numatytasis)"</item>
diff --git a/packages/SettingsLib/res/values-lv/arrays.xml b/packages/SettingsLib/res/values-lv/arrays.xml
index 5891727..8d3dce9 100644
--- a/packages/SettingsLib/res/values-lv/arrays.xml
+++ b/packages/SettingsLib/res/values-lv/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> audio"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> audio"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> audio"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> audio"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Sistēmas atlases izmantošana (nokl.)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> audio"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> audio"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> audio"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> audio"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Sistēmas atlases izmantošana (nokl.)"</item>
diff --git a/packages/SettingsLib/res/values-mk/arrays.xml b/packages/SettingsLib/res/values-mk/arrays.xml
index 388e280..497611d 100644
--- a/packages/SettingsLib/res/values-mk/arrays.xml
+++ b/packages/SettingsLib/res/values-mk/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> аудио"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> аудио"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> аудио"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> аудио"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Користи избор на системот (стандардно)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> аудио"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> аудио"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> аудио"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> аудио"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Користи избор на системот (стандардно)"</item>
diff --git a/packages/SettingsLib/res/values-ml/arrays.xml b/packages/SettingsLib/res/values-ml/arrays.xml
index cb31d22..c54dfad 100644
--- a/packages/SettingsLib/res/values-ml/arrays.xml
+++ b/packages/SettingsLib/res/values-ml/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ഓഡിയോ"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> ഓഡിയോ"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> ഓഡിയോ"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> ഓഡിയോ"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"സിസ്റ്റം സെലക്ഷൻ ഉപയോഗിക്കൂ (ഡിഫോൾട്ട്)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ഓഡിയോ"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> ഓഡിയോ"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> ഓഡിയോ"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> ഓഡിയോ"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"സിസ്റ്റം സെലക്ഷൻ ഉപയോഗിക്കൂ (ഡിഫോൾട്ട്)"</item>
diff --git a/packages/SettingsLib/res/values-mn/arrays.xml b/packages/SettingsLib/res/values-mn/arrays.xml
index 6a33b48..510d701 100644
--- a/packages/SettingsLib/res/values-mn/arrays.xml
+++ b/packages/SettingsLib/res/values-mn/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> аудио"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> аудио"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> аудио"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> аудио"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Системийн сонголтыг ашиглах (Өгөгдмөл)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> аудио"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> аудио"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> аудио"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> аудио"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Системийн сонголтыг ашиглах (Өгөгдмөл)"</item>
diff --git a/packages/SettingsLib/res/values-mr/arrays.xml b/packages/SettingsLib/res/values-mr/arrays.xml
index 8abf290..8ca4071 100644
--- a/packages/SettingsLib/res/values-mr/arrays.xml
+++ b/packages/SettingsLib/res/values-mr/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ऑडिओ"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> ऑडिओ"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> ऑडिओ"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> ऑडिओ"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"सिस्टम निवड वापरा (डीफॉल्ट)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ऑडिओ"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> ऑडिओ"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> ऑडिओ"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> ऑडिओ"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"सिस्टम निवड वापरा (डीफॉल्ट)"</item>
diff --git a/packages/SettingsLib/res/values-ms/arrays.xml b/packages/SettingsLib/res/values-ms/arrays.xml
index 15fad67..d2c91b9 100644
--- a/packages/SettingsLib/res/values-ms/arrays.xml
+++ b/packages/SettingsLib/res/values-ms/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="2908219194098827570">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049225">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Gunakan Pilihan Sistem (Lalai)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="3517061573669307965">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049481">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Gunakan Pilihan Sistem (Lalai)"</item>
diff --git a/packages/SettingsLib/res/values-my/arrays.xml b/packages/SettingsLib/res/values-my/arrays.xml
index 90bac81..c301e9c 100644
--- a/packages/SettingsLib/res/values-my/arrays.xml
+++ b/packages/SettingsLib/res/values-my/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> အသံ"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> အသံ"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> အသံ"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> အသံ"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"စနစ်ရွေးချယ်မှုကို အသုံးပြုပါ (မူရင်း)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> အသံ"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> အသံ"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> အသံ"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> အသံ"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"စနစ်ရွေးချယ်မှုကို အသုံးပြုပါ (မူရင်း)"</item>
diff --git a/packages/SettingsLib/res/values-nb/arrays.xml b/packages/SettingsLib/res/values-nb/arrays.xml
index 275018b..bdb5549 100644
--- a/packages/SettingsLib/res/values-nb/arrays.xml
+++ b/packages/SettingsLib/res/values-nb/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>-lyd"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>-lyd"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>-lyd"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>-lyd"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Bruk systemvalg (standard)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>-lyd"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>-lyd"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>-lyd"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>-lyd"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Bruk systemvalg (standard)"</item>
diff --git a/packages/SettingsLib/res/values-ne/arrays.xml b/packages/SettingsLib/res/values-ne/arrays.xml
index 5ee6353..cbb0270 100644
--- a/packages/SettingsLib/res/values-ne/arrays.xml
+++ b/packages/SettingsLib/res/values-ne/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> अडियो"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> अडियो"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> अडियो"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> अडियो"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"प्रणालीको चयन प्रयोग गर्नुहोस् (पूर्वनिर्धारित)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> अडियो"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> अडियो"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> अडियो"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> अडियो"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"प्रणालीको चयन प्रयोग गर्नुहोस् (पूर्वनिर्धारित)"</item>
diff --git a/packages/SettingsLib/res/values-nl/arrays.xml b/packages/SettingsLib/res/values-nl/arrays.xml
index bfbbae0..a48e506 100644
--- a/packages/SettingsLib/res/values-nl/arrays.xml
+++ b/packages/SettingsLib/res/values-nl/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> audio"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> audio"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> audio"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> audio"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Systeemselectie gebruiken (standaard)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> audio"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> audio"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> audio"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> audio"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Systeemselectie gebruiken (standaard)"</item>
diff --git a/packages/SettingsLib/res/values-or/arrays.xml b/packages/SettingsLib/res/values-or/arrays.xml
index 4a3d5d7..23e8ab7 100644
--- a/packages/SettingsLib/res/values-or/arrays.xml
+++ b/packages/SettingsLib/res/values-or/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ଅଡିଓ"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> ଅଡିଓ"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> ଅଡିଓ"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> ଅଡିଓ"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"ସିଷ୍ଟମ୍ର ଚୟନ (ଡିଫଲ୍ଟ୍) ବ୍ୟବହାର କରନ୍ତୁ"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ଅଡିଓ"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> ଅଡିଓ"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> ଅଡିଓ"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> ଅଡିଓ"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"ସିଷ୍ଟମ୍ର ଚୟନ (ଡିଫଲ୍ଟ୍) ବ୍ୟବହାର କରନ୍ତୁ"</item>
diff --git a/packages/SettingsLib/res/values-pa/arrays.xml b/packages/SettingsLib/res/values-pa/arrays.xml
index d594f3b..3950718 100644
--- a/packages/SettingsLib/res/values-pa/arrays.xml
+++ b/packages/SettingsLib/res/values-pa/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ਆਡੀਓ"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> ਆਡੀਓ"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> ਆਡੀਓ"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> ਆਡੀਓ"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"ਸਿਸਟਮ ਚੋਣ ਦੀ ਵਰਤੋਂ ਕਰੋ (ਪੂਰਵ-ਨਿਰਧਾਰਤ)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ਆਡੀਓ"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> ਆਡੀਓ"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> ਆਡੀਓ"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> ਆਡੀਓ"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"ਸਿਸਟਮ ਚੋਣ ਦੀ ਵਰਤੋਂ ਕਰੋ (ਪੂਰਵ-ਨਿਰਧਾਰਤ)"</item>
diff --git a/packages/SettingsLib/res/values-pl/arrays.xml b/packages/SettingsLib/res/values-pl/arrays.xml
index eb33323..5323ce1 100644
--- a/packages/SettingsLib/res/values-pl/arrays.xml
+++ b/packages/SettingsLib/res/values-pl/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="2908219194098827570">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049225">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Użyj wyboru systemu (domyślnie)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="3517061573669307965">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049481">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Użyj wyboru systemu (domyślnie)"</item>
diff --git a/packages/SettingsLib/res/values-pt-rBR/arrays.xml b/packages/SettingsLib/res/values-pt-rBR/arrays.xml
index 81285aa..31b88bb 100644
--- a/packages/SettingsLib/res/values-pt-rBR/arrays.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"Áudio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="2908219194098827570">"Áudio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"Áudio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049225">"Áudio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Usar seleção do sistema (padrão)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"Áudio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="3517061573669307965">"Áudio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"Áudio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049481">"Áudio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Usar seleção do sistema (padrão)"</item>
diff --git a/packages/SettingsLib/res/values-pt-rPT/arrays.xml b/packages/SettingsLib/res/values-pt-rPT/arrays.xml
index 019a5f6..fa65e98 100644
--- a/packages/SettingsLib/res/values-pt-rPT/arrays.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"Áudio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="2908219194098827570">"Áudio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"Áudio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049225">"Áudio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Utilizar seleção do sistema (predefinido)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"Áudio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="3517061573669307965">"Áudio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"Áudio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049481">"Áudio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Utilizar seleção do sistema (predefinido)"</item>
diff --git a/packages/SettingsLib/res/values-pt/arrays.xml b/packages/SettingsLib/res/values-pt/arrays.xml
index 81285aa..2da83e4 100644
--- a/packages/SettingsLib/res/values-pt/arrays.xml
+++ b/packages/SettingsLib/res/values-pt/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"Áudio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="2908219194098827570">"Áudio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049225">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Usar seleção do sistema (padrão)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"Áudio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="3517061573669307965">"Áudio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049481">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Usar seleção do sistema (padrão)"</item>
diff --git a/packages/SettingsLib/res/values-ro/arrays.xml b/packages/SettingsLib/res/values-ro/arrays.xml
index 48a3fa7..2c27539 100644
--- a/packages/SettingsLib/res/values-ro/arrays.xml
+++ b/packages/SettingsLib/res/values-ro/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="2908219194098827570">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049225">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Folosiți selectarea sistemului (prestabilit)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="3517061573669307965">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049481">"Audio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Folosiți selectarea sistemului (prestabilit)"</item>
diff --git a/packages/SettingsLib/res/values-ru/arrays.xml b/packages/SettingsLib/res/values-ru/arrays.xml
index 5617aa6..c1cc189 100644
--- a/packages/SettingsLib/res/values-ru/arrays.xml
+++ b/packages/SettingsLib/res/values-ru/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"Аудиокодек: <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="2908219194098827570">"Аудиокодек: <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"Аудиокодек: <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049225">"Аудиокодек: <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Выбор системы (по умолчанию)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"Аудиокодек: <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="3517061573669307965">"Аудиокодек: <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"Аудиокодек: <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049481">"Аудиокодек: <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Выбор системы (по умолчанию)"</item>
diff --git a/packages/SettingsLib/res/values-si/arrays.xml b/packages/SettingsLib/res/values-si/arrays.xml
index 01d0dd2..529d6bc 100644
--- a/packages/SettingsLib/res/values-si/arrays.xml
+++ b/packages/SettingsLib/res/values-si/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ශ්රව්යය"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> ශ්රව්යය"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> ශ්රව්යය"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> ශ්රව්යය"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"පද්ධති තේරීම භාවිත කරන්න (පෙරනිමි)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ශ්රව්යය"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> ශ්රව්යය"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> ශ්රව්යය"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> ශ්රව්යය"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"පද්ධති තේරීම භාවිත කරන්න (පෙරනිමි)"</item>
diff --git a/packages/SettingsLib/res/values-sk/arrays.xml b/packages/SettingsLib/res/values-sk/arrays.xml
index 5dcf791..a67c890 100644
--- a/packages/SettingsLib/res/values-sk/arrays.xml
+++ b/packages/SettingsLib/res/values-sk/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"Zvuk: <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="2908219194098827570">"Zvuk: <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"Zvuk: <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049225">"Zvuk: <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Použiť voľbu systému (predvolené)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"Zvuk: <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="3517061573669307965">"Zvuk: <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"Zvuk: <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049481">"Zvuk: <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Použiť voľbu systému (predvolené)"</item>
diff --git a/packages/SettingsLib/res/values-sl/arrays.xml b/packages/SettingsLib/res/values-sl/arrays.xml
index 7ba23af..f3546c0 100644
--- a/packages/SettingsLib/res/values-sl/arrays.xml
+++ b/packages/SettingsLib/res/values-sl/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"Zvok <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="2908219194098827570">"Zvok <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"Zvok <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049225">"Zvok <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Uporabi sistemsko izbiro (privzeto)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"Zvok <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="3517061573669307965">"Zvok <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"Zvok <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049481">"Zvok <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Uporabi sistemsko izbiro (privzeto)"</item>
diff --git a/packages/SettingsLib/res/values-sq/arrays.xml b/packages/SettingsLib/res/values-sq/arrays.xml
index fccfc2f..cd8e126 100644
--- a/packages/SettingsLib/res/values-sq/arrays.xml
+++ b/packages/SettingsLib/res/values-sq/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"Audioja e <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="2908219194098827570">"Audioja e <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"Audioja e <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049225">"Audioja e <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Përdor përzgjedhjen e sistemit (e parazgjedhur)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"Audioja e <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="3517061573669307965">"Audioja e <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"Audioja e <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049481">"Audioja e <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Përdor përzgjedhjen e sistemit (e parazgjedhur)"</item>
diff --git a/packages/SettingsLib/res/values-sr/arrays.xml b/packages/SettingsLib/res/values-sr/arrays.xml
index 11b4b76..8ed00e9 100644
--- a/packages/SettingsLib/res/values-sr/arrays.xml
+++ b/packages/SettingsLib/res/values-sr/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> аудио"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> аудио"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> аудио"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> аудио"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Користи избор система (подразумевано)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> аудио"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> аудио"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> аудио"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> аудио"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Користи избор система (подразумевано)"</item>
diff --git a/packages/SettingsLib/res/values-sv/arrays.xml b/packages/SettingsLib/res/values-sv/arrays.xml
index be68c71..107179d 100644
--- a/packages/SettingsLib/res/values-sv/arrays.xml
+++ b/packages/SettingsLib/res/values-sv/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>-ljud"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>-ljud"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>-ljud"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>-ljud"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Använd systemval (standardinställning)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>-ljud"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>-ljud"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>-ljud"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>-ljud"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Använd systemval (standardinställning)"</item>
diff --git a/packages/SettingsLib/res/values-sw/arrays.xml b/packages/SettingsLib/res/values-sw/arrays.xml
index da99b91..8e321f2 100644
--- a/packages/SettingsLib/res/values-sw/arrays.xml
+++ b/packages/SettingsLib/res/values-sw/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"Sauti ya <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="2908219194098827570">"Sauti ya <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"Sauti ya <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049225">"Sauti ya <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Tumia Uteuzi wa Mfumo (Chaguomsingi)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"Sauti ya <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="3517061573669307965">"Sauti ya <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"Sauti ya <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049481">"Sauti ya <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Tumia Uteuzi wa Mfumo (Chaguomsingi)"</item>
diff --git a/packages/SettingsLib/res/values-ta/arrays.xml b/packages/SettingsLib/res/values-ta/arrays.xml
index 1c55954..2b49b1e 100644
--- a/packages/SettingsLib/res/values-ta/arrays.xml
+++ b/packages/SettingsLib/res/values-ta/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ஆடியோ"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> ஆடியோ"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> ஆடியோ"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> ஆடியோ"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"சாதனத் தேர்வைப் பயன்படுத்து (இயல்பு)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ஆடியோ"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> ஆடியோ"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> ஆடியோ"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> ஆடியோ"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"சாதனத் தேர்வைப் பயன்படுத்து (இயல்பு)"</item>
diff --git a/packages/SettingsLib/res/values-te/arrays.xml b/packages/SettingsLib/res/values-te/arrays.xml
index e1c0406..1363a40 100644
--- a/packages/SettingsLib/res/values-te/arrays.xml
+++ b/packages/SettingsLib/res/values-te/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ఆడియో"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> ఆడియో"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> ఆడియో"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> ఆడియో"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"సిస్టమ్ ఎంపికను ఉపయోగించండి (ఆటోమేటిక్)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ఆడియో"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> ఆడియో"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> ఆడియో"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> ఆడియో"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"సిస్టమ్ ఎంపికను ఉపయోగించండి (ఆటోమేటిక్)"</item>
diff --git a/packages/SettingsLib/res/values-th/arrays.xml b/packages/SettingsLib/res/values-th/arrays.xml
index 21fe6e4..e207b6f 100644
--- a/packages/SettingsLib/res/values-th/arrays.xml
+++ b/packages/SettingsLib/res/values-th/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"เสียง <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="2908219194098827570">"เสียง <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"เสียง <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049225">"เสียง <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"ใช้การเลือกของระบบ (ค่าเริ่มต้น)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"เสียง <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="3517061573669307965">"เสียง <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"เสียง <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049481">"เสียง <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"ใช้การเลือกของระบบ (ค่าเริ่มต้น)"</item>
diff --git a/packages/SettingsLib/res/values-tl/arrays.xml b/packages/SettingsLib/res/values-tl/arrays.xml
index 9f07cff..ba3ec67 100644
--- a/packages/SettingsLib/res/values-tl/arrays.xml
+++ b/packages/SettingsLib/res/values-tl/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> na audio"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> na audio"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> na audio"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> na audio"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Gamitin ang Pagpili ng System (Default)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> na audio"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> na audio"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> na audio"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> na audio"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Gamitin ang Pagpili ng System (Default)"</item>
diff --git a/packages/SettingsLib/res/values-tr/arrays.xml b/packages/SettingsLib/res/values-tr/arrays.xml
index fc90c9a..3e8738f 100644
--- a/packages/SettingsLib/res/values-tr/arrays.xml
+++ b/packages/SettingsLib/res/values-tr/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ses"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> ses"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> ses"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> ses"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Sistem Seçimini Kullan (Varsayılan)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> ses"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> ses"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> ses"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> ses"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Sistem Seçimini Kullan (Varsayılan)"</item>
diff --git a/packages/SettingsLib/res/values-uk/arrays.xml b/packages/SettingsLib/res/values-uk/arrays.xml
index 4405c37..42c56f2 100644
--- a/packages/SettingsLib/res/values-uk/arrays.xml
+++ b/packages/SettingsLib/res/values-uk/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"Аудіо <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="2908219194098827570">"Аудіо <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"Аудіо <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049225">"Аудіо <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Використовувати вибір системи (за умовчанням)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"Аудіо <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="3517061573669307965">"Аудіо <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"Аудіо <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049481">"Аудіо <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Використовувати вибір системи (за умовчанням)"</item>
diff --git a/packages/SettingsLib/res/values-ur/arrays.xml b/packages/SettingsLib/res/values-ur/arrays.xml
index f4c2500..6171a4c 100644
--- a/packages/SettingsLib/res/values-ur/arrays.xml
+++ b/packages/SettingsLib/res/values-ur/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> آڈیو"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> آڈیو"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> ﺁڈیﻭ"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> ﺁڈیﻭ"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"سسٹم انتخاب کا استعمال کریں (ڈیفالٹ)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> آڈیو"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> آڈیو"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> ﺁڈیﻭ"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> ﺁڈیﻭ"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"سسٹم انتخاب کا استعمال کریں (ڈیفالٹ)"</item>
diff --git a/packages/SettingsLib/res/values-uz/arrays.xml b/packages/SettingsLib/res/values-uz/arrays.xml
index 0770dcc4..a67c623 100644
--- a/packages/SettingsLib/res/values-uz/arrays.xml
+++ b/packages/SettingsLib/res/values-uz/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> audiokodeki"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> audiokodeki"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> audiokodeki"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> audiokodeki"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Tizim tanlovi (birlamchi)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> audiokodeki"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> audiokodeki"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> audiokodeki"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> audiokodeki"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Tizim tanlovi (birlamchi)"</item>
diff --git a/packages/SettingsLib/res/values-vi/arrays.xml b/packages/SettingsLib/res/values-vi/arrays.xml
index 635cf11..591b01f 100644
--- a/packages/SettingsLib/res/values-vi/arrays.xml
+++ b/packages/SettingsLib/res/values-vi/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"Âm thanh <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="2908219194098827570">"Âm thanh <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"Âm thanh <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049225">"Âm thanh <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Sử dụng lựa chọn của hệ thống (Mặc định)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"Âm thanh <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
<item msgid="3517061573669307965">"Âm thanh <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g>"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"Âm thanh <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g>"</item>
+ <item msgid="6486050771049481">"Âm thanh <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g>"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Sử dụng lựa chọn của hệ thống (Mặc định)"</item>
diff --git a/packages/SettingsLib/res/values-zh-rCN/arrays.xml b/packages/SettingsLib/res/values-zh-rCN/arrays.xml
index 29d04e9..b05dd2d 100644
--- a/packages/SettingsLib/res/values-zh-rCN/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> 音频"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> 音频"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> 音频"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> 音频"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"使用系统选择(默认)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> 音频"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> 音频"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> 音频"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> 音频"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"使用系统选择(默认)"</item>
diff --git a/packages/SettingsLib/res/values-zh-rHK/arrays.xml b/packages/SettingsLib/res/values-zh-rHK/arrays.xml
index e7e2f84..18e7d27 100644
--- a/packages/SettingsLib/res/values-zh-rHK/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> 音訊"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> 音訊"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> 音訊"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> 音訊"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"使用系統選擇 (預設)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> 音訊"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> 音訊"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> 音訊"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> 音訊"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"使用系統選擇 (預設)"</item>
diff --git a/packages/SettingsLib/res/values-zh-rTW/arrays.xml b/packages/SettingsLib/res/values-zh-rTW/arrays.xml
index 0fdc14e..228e7b6 100644
--- a/packages/SettingsLib/res/values-zh-rTW/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> 音訊"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> 音訊"</item>
<item msgid="3825367753087348007">"LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> 音訊"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> 音訊"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"系統自動選擇 (預設)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> 音訊"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> 音訊"</item>
<item msgid="2553206901068987657">"LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> 音訊"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> 音訊"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"系統自動選擇 (預設)"</item>
diff --git a/packages/SettingsLib/res/values-zu/arrays.xml b/packages/SettingsLib/res/values-zu/arrays.xml
index 2d43c67..80368ee 100644
--- a/packages/SettingsLib/res/values-zu/arrays.xml
+++ b/packages/SettingsLib/res/values-zu/arrays.xml
@@ -92,6 +92,8 @@
<item msgid="1049450003868150455">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> umsindo"</item>
<item msgid="2908219194098827570">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> umsindo"</item>
<item msgid="3825367753087348007">"I-LDAC"</item>
+ <item msgid="8711430979086781450">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> umsindo"</item>
+ <item msgid="6486050771049225">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> umsindo"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
<item msgid="8868109554557331312">"Sebenzisa ukukhetha kwesistimu (Okuzenzakalelayo)"</item>
@@ -100,6 +102,8 @@
<item msgid="8627333814413492563">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g> umsindo"</item>
<item msgid="3517061573669307965">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_HD">aptX™ HD</xliff:g> umsindo"</item>
<item msgid="2553206901068987657">"I-LDAC"</item>
+ <item msgid="102988075927343894">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_ADAPTIVE">aptX™ Adaptive</xliff:g> umsindo"</item>
+ <item msgid="6486050771049481">"<xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX_TWSP">aptX™ TWS+</xliff:g> umsindo"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
<item msgid="926809261293414607">"Sebenzisa ukukhetha kwesistimu (Okuzenzakalelayo)"</item>
diff --git a/packages/SettingsLib/res/values/arrays.xml b/packages/SettingsLib/res/values/arrays.xml
index c63cf06..75d2703 100644
--- a/packages/SettingsLib/res/values/arrays.xml
+++ b/packages/SettingsLib/res/values/arrays.xml
@@ -164,6 +164,8 @@
<item>2</item>
<item>3</item>
<item>4</item>
+ <item>5</item>
+ <item>6</item>
</string-array>
<!-- Summaries for Bluetooth Audio Codec selection preference. [CHAR LIMIT=50]-->
@@ -502,6 +504,20 @@
<item>show_deuteranomaly</item>
</string-array>
+ <!-- Titles for debug renderer preference. [CHAR LIMIT=50] -->
+ <string-array name="debug_hw_renderer_entries">
+ <item>OpenGL (Default)</item>
+ <item>OpenGL (Skia)</item>
+ <item>Vulkan (Skia)</item>
+ </string-array>
+
+ <!-- Values for debug renderer preference. -->
+ <string-array name="debug_hw_renderer_values" translatable="false" >
+ <item>opengl</item>
+ <item>skiagl</item>
+ <item>skiavk</item>
+ </string-array>
+
<!-- Titles for app process limit preference. [CHAR LIMIT=35] -->
<string-array name="app_process_limit_entries">
<item>Standard limit</item>
diff --git a/packages/SettingsLib/res/values/bliss_strings.xml b/packages/SettingsLib/res/values/bliss_strings.xml
new file mode 100644
index 0000000..14a2e69
--- /dev/null
+++ b/packages/SettingsLib/res/values/bliss_strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 BlissRoms 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.
+-->
+<resources>
+
+ <!-- Description for the screen zoom level that makes interface elements smaller. [CHAR LIMIT=24] -->
+ <string name="screen_zoom_summary_smaller">Smaller</string>
+ <!-- Description for the screen zoom level that makes interface elements smallest. [CHAR LIMIT=24] -->
+ <string name="screen_zoom_summary_smallest">Smallest</string>
+
+ <string name="status_deep_sleep">(Deep sleep: %1$d%2$s)</string>
+
+</resources>
diff --git a/packages/SettingsLib/res/values/cm_arrays.xml b/packages/SettingsLib/res/values/cm_arrays.xml
new file mode 100644
index 0000000..2377d37
--- /dev/null
+++ b/packages/SettingsLib/res/values/cm_arrays.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2020 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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Titles for Bluetooth Audio Codec selection preference. [CHAR LIMIT=50] -->
+ <string-array name="bluetooth_a2dp_codec_titles_cm">
+ <item>Use System Selection (Default)</item>
+ <item>SBC</item>
+ <item>AAC</item>
+ <item><xliff:g id="qualcomm">Qualcomm®</xliff:g> <xliff:g id="aptx">aptX™</xliff:g> audio</item>
+ <item><xliff:g id="qualcomm">Qualcomm®</xliff:g> <xliff:g id="aptx_hd">aptX™ HD</xliff:g> audio</item>
+ <item>LDAC</item>
+ <item><xliff:g id="qualcomm">Qualcomm®</xliff:g> <xliff:g id="aptx_adaptive">aptX™ Adaptive</xliff:g> audio</item>
+ <item><xliff:g id="qualcomm">Qualcomm®</xliff:g> <xliff:g id="aptx_twsp">aptX™ TWS+</xliff:g> audio</item>
+ </string-array>
+
+ <!-- Summaries for Bluetooth Audio Codec selection preference. [CHAR LIMIT=50]-->
+ <string-array name="bluetooth_a2dp_codec_summaries_cm" >
+ <item>Use System Selection (Default)</item>
+ <item>SBC</item>
+ <item>AAC</item>
+ <item><xliff:g id="qualcomm">Qualcomm®</xliff:g> <xliff:g id="aptx">aptX™</xliff:g> audio</item>
+ <item><xliff:g id="qualcomm">Qualcomm®</xliff:g> <xliff:g id="aptx_hd">aptX™ HD</xliff:g> audio</item>
+ <item>LDAC</item>
+ <item><xliff:g id="qualcomm">Qualcomm®</xliff:g> <xliff:g id="aptx_adaptive">aptX™ Adaptive</xliff:g> audio</item>
+ <item><xliff:g id="qualcomm">Qualcomm®</xliff:g> <xliff:g id="aptx_twsp">aptX™ TWS+</xliff:g> audio</item>
+ </string-array>
+
+ <!-- Titles for Bluetooth Audio Codec Channel Mode selection preference. [CHAR LIMIT=50] -->
+ <string-array name="bluetooth_a2dp_codec_channel_mode_titles_cm">
+ <item>Use System Selection (Default)</item>
+ <item>Mono</item>
+ <item>Stereo</item>
+ <item>Dual Channel</item>
+ </string-array>
+
+ <!-- Values for Bluetooth Audio Codec Channel Mode selection preference. -->
+ <string-array name="bluetooth_a2dp_codec_channel_mode_values_cm" translatable="false" >
+ <item>0</item>
+ <item>1</item>
+ <item>2</item>
+ <item>3</item>
+ </string-array>
+
+ <!-- Summaries for Bluetooth Audio Codec Channel Mode selection preference. [CHAR LIMIT=50]-->
+ <string-array name="bluetooth_a2dp_codec_channel_mode_summaries_cm" >
+ <item>Use System Selection (Default)</item>
+ <item>Mono</item>
+ <item>Stereo</item>
+ <item>Dual Channel</item>
+ </string-array>
+</resources>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index a550136..c88fda9 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -853,6 +853,9 @@
<!-- UI debug setting: show the amount of overdraw in apps using the GPU [CHAR LIMIT=25] -->
<string name="debug_hw_overdraw">Debug GPU overdraw</string>
+ <!-- UI debug setting: select the renderer to use by RenderThread [CHAR LIMIT=25] -->
+ <string name="debug_hw_renderer">Set GPU Renderer</string>
+
<!-- UI debug setting: disable use of overlays? [CHAR LIMIT=25] -->
<string name="disable_overlays">Disable HW overlays</string>
<!-- UI debug setting: disable use of overlays summary [CHAR LIMIT=50] -->
@@ -1150,9 +1153,9 @@
<!-- Hint text for the IP address -->
<string name="wifi_ip_address_hint" translatable="false">192.168.1.128</string>
<!-- Hint text for DNS -->
- <string name="wifi_dns1_hint" translatable="false">8.8.8.8</string>
+ <string name="wifi_dns1_hint" translatable="false">1.0.0.1</string>
<!-- Hint text for DNS -->
- <string name="wifi_dns2_hint" translatable="false">8.8.4.4</string>
+ <string name="wifi_dns2_hint" translatable="false">1.1.1.1</string>
<!-- Hint text for the gateway -->
<string name="wifi_gateway_hint" translatable="false">192.168.1.1</string>
<!-- Hint text for network prefix length -->
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
index a89cf37..e1510c7 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
@@ -1868,7 +1868,7 @@
@Override
public boolean filterApp(AppEntry entry) {
- return true;
+ return !hasFlag(entry.info.privateFlags, ApplicationInfo.PRIVATE_FLAG_IS_RESOURCE_OVERLAY);
}
};
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
index 3c78560..cce2267 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
@@ -39,6 +39,7 @@
public class A2dpProfile implements LocalBluetoothProfile {
private static final String TAG = "A2dpProfile";
+ private static boolean V = true;
private Context mContext;
@@ -218,6 +219,11 @@
}
public boolean supportsHighQualityAudio(BluetoothDevice device) {
+ if (V) Log.d(TAG, " execute supportsHighQualityAudio()");
+ if (mService == null) {
+ if (V) Log.d(TAG,"mService is null.");
+ return false;
+ }
BluetoothDevice bluetoothDevice = (device != null) ? device : mService.getActiveDevice();
if (bluetoothDevice == null) {
return false;
@@ -227,6 +233,11 @@
}
public boolean isHighQualityAudioEnabled(BluetoothDevice device) {
+ if (V) Log.d(TAG, " execute isHighQualityAudioEnabled()");
+ if (mService == null) {
+ if (V) Log.d(TAG,"mService is null.");
+ return false;
+ }
BluetoothDevice bluetoothDevice = (device != null) ? device : mService.getActiveDevice();
if (bluetoothDevice == null) {
return false;
@@ -253,13 +264,18 @@
}
public void setHighQualityAudioEnabled(BluetoothDevice device, boolean enabled) {
+ if (V) Log.d(TAG, " execute setHighQualityAudioEnabled()");
+ int prefValue = enabled
+ ? BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED
+ : BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED;
+ if (mService == null) {
+ if (V) Log.d(TAG,"mService is null.");
+ return;
+ }
BluetoothDevice bluetoothDevice = (device != null) ? device : mService.getActiveDevice();
if (bluetoothDevice == null) {
return;
}
- int prefValue = enabled
- ? BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED
- : BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED;
mService.setOptionalCodecsEnabled(bluetoothDevice, prefValue);
if (getConnectionStatus(bluetoothDevice) != BluetoothProfile.STATE_CONNECTED) {
return;
@@ -272,6 +288,7 @@
}
public String getHighQualityAudioOptionLabel(BluetoothDevice device) {
+ if (V) Log.d(TAG, " execute getHighQualityAudioOptionLabel()");
BluetoothDevice bluetoothDevice = (device != null) ? device : mService.getActiveDevice();
int unknownCodecId = R.string.bluetooth_profile_a2dp_high_quality_unknown_codec;
if (bluetoothDevice == null || !supportsHighQualityAudio(device)
@@ -281,7 +298,7 @@
// We want to get the highest priority codec, since that's the one that will be used with
// this device, and see if it is high-quality (ie non-mandatory).
BluetoothCodecConfig[] selectable = null;
- if (mService.getCodecStatus(device) != null) {
+ if (mService != null && mService.getCodecStatus(device) != null) {
selectable = mService.getCodecStatus(device).getCodecsSelectableCapabilities();
// To get the highest priority, we sort in reverse.
Arrays.sort(selectable,
@@ -312,13 +329,20 @@
case BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC:
index = 5;
break;
+ case BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_ADAPTIVE:
+ index = 6;
+ break;
+ case BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_TWSP:
+ index = 7;
+ break;
}
if (index < 0) {
return mContext.getString(unknownCodecId);
}
return mContext.getString(R.string.bluetooth_profile_a2dp_high_quality,
- mContext.getResources().getStringArray(R.array.bluetooth_a2dp_codec_titles)[index]);
+ mContext.getResources().getStringArray(
+ R.array.bluetooth_a2dp_codec_titles_cm)[index]);
}
public String toString() {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothCallback.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothCallback.java
index 3152e65..f0c12a3 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothCallback.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothCallback.java
@@ -16,6 +16,7 @@
package com.android.settingslib.bluetooth;
+import android.bluetooth.BluetoothCodecStatus;
/**
* BluetoothCallback provides a callback interface for the settings
@@ -140,4 +141,15 @@
*/
default void onAclConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) {
}
+
+ /**
+ * Called when a2dp codec config is changed. It listens to
+ * {@link android.bluetooth.BluetoothA2dp#ACTION_CODEC_CONFIG_CHANGED}.
+ *
+ * @param cachedDevice Bluetooth device that changed
+ * @param codecStatus the current codec status of the a2dp profile
+ */
+ default void onA2dpCodecConfigChanged(CachedBluetoothDevice cachedDevice,
+ BluetoothCodecStatus codecStatus) {
+ }
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
index 4b4861a..9b958e7 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
@@ -18,6 +18,7 @@
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothCodecStatus;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothHearingAid;
@@ -108,6 +109,8 @@
addHandler(BluetoothDevice.ACTION_CLASS_CHANGED, new ClassChangedHandler());
addHandler(BluetoothDevice.ACTION_UUID, new UuidChangedHandler());
addHandler(BluetoothDevice.ACTION_BATTERY_LEVEL_CHANGED, new BatteryLevelChangedHandler());
+ addHandler(BluetoothHeadset.ACTION_HF_TWSP_BATTERY_STATE_CHANGED ,
+ new TwspBatteryLevelChangedHandler());
// Active device broadcasts
addHandler(BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED, new ActiveDeviceChangedHandler());
@@ -124,6 +127,7 @@
// ACL connection changed broadcasts
addHandler(BluetoothDevice.ACTION_ACL_CONNECTED, new AclStateChangedHandler());
addHandler(BluetoothDevice.ACTION_ACL_DISCONNECTED, new AclStateChangedHandler());
+ addHandler(BluetoothA2dp.ACTION_CODEC_CONFIG_CHANGED, new A2dpCodecConfigChangedHandler());
registerAdapterIntentReceiver();
}
@@ -238,6 +242,13 @@
}
}
+ private void dispatchA2dpCodecConfigChanged(CachedBluetoothDevice cachedDevice,
+ BluetoothCodecStatus codecStatus) {
+ for (BluetoothCallback callback : mCallbacks) {
+ callback.onA2dpCodecConfigChanged(cachedDevice, codecStatus);
+ }
+ }
+
@VisibleForTesting
void addHandler(String action, Handler handler) {
mHandlerMap.put(action, handler);
@@ -426,6 +437,24 @@
}
}
+ private class TwspBatteryLevelChangedHandler implements Handler {
+ public void onReceive(Context context, Intent intent,
+ BluetoothDevice device) {
+ CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(device);
+ if (cachedDevice != null) {
+ cachedDevice.mTwspBatteryState =
+ intent.getIntExtra(
+ BluetoothHeadset.EXTRA_HF_TWSP_BATTERY_STATE, -1);
+ cachedDevice.mTwspBatteryLevel =
+ intent.getIntExtra(
+ BluetoothHeadset.EXTRA_HF_TWSP_BATTERY_LEVEL, -1);
+ Log.i(TAG, cachedDevice + ": mTwspBatteryState: " + cachedDevice.mTwspBatteryState
+ + "mTwspBatteryLevel: " + cachedDevice.mTwspBatteryLevel);
+ cachedDevice.refresh();
+ }
+ }
+ }
+
private class ActiveDeviceChangedHandler implements Handler {
@Override
public void onReceive(Context context, Intent intent, BluetoothDevice device) {
@@ -502,4 +531,28 @@
dispatchAudioModeChanged();
}
}
+
+ private class A2dpCodecConfigChangedHandler implements Handler {
+
+ @Override
+ public void onReceive(Context context, Intent intent, BluetoothDevice device) {
+ final String action = intent.getAction();
+ if (action == null) {
+ Log.w(TAG, "A2dpCodecConfigChangedHandler: action is null");
+ return;
+ }
+
+ CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(device);
+ if (cachedDevice == null) {
+ Log.w(TAG, "A2dpCodecConfigChangedHandler: device is null");
+ return;
+ }
+
+ BluetoothCodecStatus codecStatus = intent.getParcelableExtra(
+ BluetoothCodecStatus.EXTRA_CODEC_STATUS);
+ Log.d(TAG, "A2dpCodecConfigChangedHandler: device=" + device +
+ ", codecStatus=" + codecStatus);
+ dispatchA2dpCodecConfigChanged(cachedDevice, codecStatus);
+ }
+ }
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index db219c9..948caf9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -59,6 +59,7 @@
private static final long MAX_HEARING_AIDS_DELAY_FOR_AUTO_CONNECT = 15000;
private static final long MAX_HOGP_DELAY_FOR_AUTO_CONNECT = 30000;
private static final long MAX_MEDIA_PROFILE_CONNECT_DELAY = 60000;
+ private static final boolean mIsTwsConnectEnabled = false;
private final Context mContext;
private final BluetoothAdapter mLocalAdapter;
@@ -82,6 +83,8 @@
private final Collection<Callback> mCallbacks = new CopyOnWriteArrayList<>();
+ public int mTwspBatteryState;
+ public int mTwspBatteryLevel;
/**
* Last time a bt profile auto-connect was attempted.
* If an ACTION_UUID intent comes in within
@@ -131,6 +134,24 @@
mDevice = device;
fillData();
mHiSyncId = BluetoothHearingAid.HI_SYNC_ID_INVALID;
+ mTwspBatteryState = -1;
+ mTwspBatteryLevel = -1;
+ }
+
+ /* Gets Device for seondary TWS device
+ * @param mDevice Primary TWS device to get secondary
+ * @return Description of the device
+ */
+
+ private BluetoothDevice getTwsPeerDevice() {
+ BluetoothAdapter bluetoothAdapter;
+ BluetoothDevice peerDevice = null;
+ if (mDevice.isTwsPlusDevice()) {
+ bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ String peerAddress = mDevice.getTwsPlusPeerAddress();
+ peerDevice = bluetoothAdapter.getRemoteDevice(peerAddress);
+ }
+ return peerDevice;
}
/**
@@ -215,6 +236,10 @@
mProfiles.remove(profile);
mRemovedProfiles.add(profile);
mLocalNapRoleConnected = false;
+ } else if (profile instanceof HeadsetProfile
+ && newProfileState == BluetoothProfile.STATE_DISCONNECTED) {
+ mTwspBatteryState = -1;
+ mTwspBatteryLevel = -1;
}
}
@@ -282,6 +307,7 @@
}
mConnectAttempted = SystemClock.elapsedRealtime();
+ Log.d(TAG, "connect: mConnectAttempted = " + mConnectAttempted);
connectAllEnabledProfiles();
}
@@ -320,6 +346,13 @@
Log.d(TAG, "No profiles. Maybe we will connect later for device " + mDevice);
return;
}
+ // BondingInitiatedLocally flag should be reset in onBondingStateChanged
+ // But Settings executing onBondingStateChanged twice and its lead to auto connection
+ // failure. this flag will be moved from here once settings issue fixed.
+ if (mDevice.isBondingInitiatedLocally()) {
+ Log.w(TAG, "reset BondingInitiatedLocally flag");
+ mDevice.setBondingInitiatedLocally(false);
+ }
mLocalAdapter.connectAllEnabledProfiles(mDevice);
}
@@ -381,6 +414,17 @@
if (state != BluetoothDevice.BOND_NONE) {
final BluetoothDevice dev = mDevice;
+ if (mDevice.isTwsPlusDevice()) {
+ BluetoothDevice peerDevice = getTwsPeerDevice();
+ if (peerDevice != null) {
+ final boolean peersuccessful = peerDevice.removeBond();
+ if (peersuccessful) {
+ if (BluetoothUtils.D) {
+ Log.d(TAG, "Command sent successfully:REMOVE_BOND " + peerDevice.getName());
+ }
+ }
+ }
+ }
if (dev != null) {
final boolean successful = dev.removeBond();
if (successful) {
@@ -688,8 +732,8 @@
* If a connect was attempted earlier without any UUID, we will do the connect now.
* Otherwise, allow the connect on UUID change.
*/
- if (!mProfiles.isEmpty()
- && ((mConnectAttempted + timeout) > SystemClock.elapsedRealtime())) {
+ if ((mConnectAttempted + timeout) > SystemClock.elapsedRealtime()) {
+ Log.d(TAG, "onUuidChanged: triggering connectAllEnabledProfiles");
connectAllEnabledProfiles();
}
@@ -708,8 +752,17 @@
refresh();
- if (bondState == BluetoothDevice.BOND_BONDED && mDevice.isBondingInitiatedLocally()) {
- connect();
+ if (bondState == BluetoothDevice.BOND_BONDED) {
+ boolean mIsBondingInitiatedLocally = mDevice.isBondingInitiatedLocally();
+ Log.w(TAG, "mIsBondingInitiatedLocally" + mIsBondingInitiatedLocally);
+ if (mIsTwsConnectEnabled) {
+ Log.d(TAG, "Initiating connection to" + mDevice);
+ if (mIsBondingInitiatedLocally || mDevice.isTwsPlusDevice()) {
+ connect();
+ }
+ } else if (mIsBondingInitiatedLocally) {
+ connect();
+ }
}
}
@@ -943,11 +996,28 @@
// BluetoothDevice.BATTERY_LEVEL_BLUETOOTH_OFF, or BluetoothDevice.BATTERY_LEVEL_UNKNOWN,
// any other value should be a framework bug. Thus assume here that if value is greater
// than BluetoothDevice.BATTERY_LEVEL_UNKNOWN, it must be valid
- final int batteryLevel = getBatteryLevel();
- if (batteryLevel > BluetoothDevice.BATTERY_LEVEL_UNKNOWN) {
- // TODO: name com.android.settingslib.bluetooth.Utils something different
- batteryLevelPercentageString =
+
+ if (mDevice.isTwsPlusDevice() && mTwspBatteryState != -1 &&
+ mTwspBatteryLevel != -1) {
+ String s = "TWSP: ";
+ String chargingState;
+ if (mTwspBatteryState == 1) {
+ chargingState = "Charging, ";
+ } else {
+ chargingState = "Discharging, ";
+ }
+ s = s.concat (chargingState);
+ s = s.concat(
+ com.android.settingslib.Utils.formatPercentage(mTwspBatteryLevel));
+ batteryLevelPercentageString = s;
+ Log.i(TAG, "UI string" + batteryLevelPercentageString);
+ } else {
+ final int batteryLevel = getBatteryLevel();
+ if (batteryLevel > BluetoothDevice.BATTERY_LEVEL_UNKNOWN) {
+ // TODO: name com.android.settingslib.bluetooth.Utils something different
+ batteryLevelPercentageString =
com.android.settingslib.Utils.formatPercentage(batteryLevel);
+ }
}
int stringRes = R.string.bluetooth_pairing;
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
index cca9cfa..7c8cc8c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
@@ -224,6 +224,9 @@
cachedDevice.setJustDiscovered(false);
mCachedDevices.remove(i);
}
+ //Clear if there any Tws battery info on BT turning OFF
+ cachedDevice.mTwspBatteryState = -1;
+ cachedDevice.mTwspBatteryLevel = -1;
}
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/development/DevelopmentSettingsEnabler.java b/packages/SettingsLib/src/com/android/settingslib/development/DevelopmentSettingsEnabler.java
index b191f88..e24f812 100644
--- a/packages/SettingsLib/src/com/android/settingslib/development/DevelopmentSettingsEnabler.java
+++ b/packages/SettingsLib/src/com/android/settingslib/development/DevelopmentSettingsEnabler.java
@@ -42,8 +42,7 @@
public static boolean isDevelopmentSettingsEnabled(Context context) {
final UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
final boolean settingEnabled = Settings.Global.getInt(context.getContentResolver(),
- Settings.Global.DEVELOPMENT_SETTINGS_ENABLED,
- Build.TYPE.equals("eng") ? 1 : 0) != 0;
+ Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1) != 0;
final boolean hasRestriction = um.hasUserRestriction(
UserManager.DISALLOW_DEBUGGING_FEATURES);
final boolean isAdmin = um.isAdminUser();
diff --git a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractUptimePreferenceController.java b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractUptimePreferenceController.java
index 5f72269..51cff41 100644
--- a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractUptimePreferenceController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/AbstractUptimePreferenceController.java
@@ -26,6 +26,7 @@
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
+import com.android.settingslib.R;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
@@ -89,7 +90,18 @@
}
private void updateTimes() {
- mUptime.setSummary(DateUtils.formatElapsedTime(SystemClock.elapsedRealtime() / 1000));
+ long ut = Math.max((SystemClock.elapsedRealtime() / 1000), 1);
+
+ float deepSleepRatio = Math.max((float) (SystemClock.elapsedRealtime() - SystemClock.uptimeMillis()), 0f)
+ / SystemClock.elapsedRealtime();
+ int deepSleepPercent = Math.round(deepSleepRatio * 100);
+
+ final StringBuilder summary = new StringBuilder();
+ summary.append(DateUtils.formatElapsedTime(SystemClock.elapsedRealtime() / 1000));
+ summary.append(" ");
+ summary.append(mContext.getString(R.string.status_deep_sleep, deepSleepPercent, "%"));
+
+ mUptime.setSummary(summary.toString());
}
private static class MyHandler extends Handler {
diff --git a/packages/SettingsLib/src/com/android/settingslib/display/DisplayDensityUtils.java b/packages/SettingsLib/src/com/android/settingslib/display/DisplayDensityUtils.java
index a38091d..b2d6425 100644
--- a/packages/SettingsLib/src/com/android/settingslib/display/DisplayDensityUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/display/DisplayDensityUtils.java
@@ -42,7 +42,7 @@
private static final float MIN_SCALE_INTERVAL = 0.09f;
/** Minimum density scale. This is available on all devices. */
- private static final float MIN_SCALE = 0.85f;
+ private static final float MIN_SCALE = 0.70f;
/** Maximum density scale. The actual scale used depends on the device. */
private static final float MAX_SCALE = 1.50f;
@@ -58,7 +58,9 @@
* largest.
*/
private static final int[] SUMMARIES_SMALLER = new int[] {
- R.string.screen_zoom_summary_small
+ R.string.screen_zoom_summary_small,
+ R.string.screen_zoom_summary_smaller,
+ R.string.screen_zoom_summary_smallest
};
/**
diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java
index ce60faf..2dbc99c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java
+++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java
@@ -24,8 +24,12 @@
import static android.os.BatteryManager.EXTRA_LEVEL;
import static android.os.BatteryManager.EXTRA_MAX_CHARGING_CURRENT;
import static android.os.BatteryManager.EXTRA_MAX_CHARGING_VOLTAGE;
+import static android.os.BatteryManager.EXTRA_TEMPERATURE;
import static android.os.BatteryManager.EXTRA_PLUGGED;
import static android.os.BatteryManager.EXTRA_STATUS;
+import static android.os.BatteryManager.EXTRA_DASH_CHARGER;
+import static android.os.BatteryManager.EXTRA_WARP_CHARGER;
+import static android.os.BatteryManager.EXTRA_VOOC_CHARGER;
import android.content.Context;
import android.content.Intent;
@@ -44,20 +48,37 @@
public static final int CHARGING_SLOWLY = 0;
public static final int CHARGING_REGULAR = 1;
public static final int CHARGING_FAST = 2;
+ public static final int CHARGING_DASH = 3;
+ public static final int CHARGING_WARP = 4;
+ public static final int CHARGING_VOOC = 5;
public final int status;
public final int level;
public final int plugged;
public final int health;
+ public final int maxChargingCurrent;
+ public final int maxChargingVoltage;
public final int maxChargingWattage;
+ public final float temperature;
+ public final boolean dashChargeStatus;
+ public final boolean warpChargeStatus;
+ public final boolean voocChargeStatus;
public BatteryStatus(int status, int level, int plugged, int health,
- int maxChargingWattage) {
+ int maxChargingCurrent, int maxChargingVoltage,
+ int maxChargingWattage, float temperature, boolean dashChargeStatus,
+ boolean warpChargeStatus, boolean voocChargeStatus) {
this.status = status;
this.level = level;
this.plugged = plugged;
this.health = health;
+ this.maxChargingCurrent = maxChargingCurrent;
+ this.maxChargingVoltage = maxChargingVoltage;
this.maxChargingWattage = maxChargingWattage;
+ this.temperature = temperature;
+ this.dashChargeStatus = dashChargeStatus;
+ this.warpChargeStatus = warpChargeStatus;
+ this.voocChargeStatus = voocChargeStatus;
}
public BatteryStatus(Intent batteryChangedIntent) {
@@ -65,6 +86,10 @@
plugged = batteryChangedIntent.getIntExtra(EXTRA_PLUGGED, 0);
level = batteryChangedIntent.getIntExtra(EXTRA_LEVEL, 0);
health = batteryChangedIntent.getIntExtra(EXTRA_HEALTH, BATTERY_HEALTH_UNKNOWN);
+ temperature = batteryChangedIntent.getIntExtra(EXTRA_TEMPERATURE, -1);
+ dashChargeStatus = batteryChangedIntent.getBooleanExtra(EXTRA_DASH_CHARGER, false);
+ warpChargeStatus = batteryChangedIntent.getBooleanExtra(EXTRA_WARP_CHARGER, false);
+ voocChargeStatus = batteryChangedIntent.getBooleanExtra(EXTRA_VOOC_CHARGER, false);
final int maxChargingMicroAmp = batteryChangedIntent.getIntExtra(EXTRA_MAX_CHARGING_CURRENT,
-1);
@@ -78,8 +103,12 @@
// to maintain precision equally on both factors.
maxChargingWattage = (maxChargingMicroAmp / 1000)
* (maxChargingMicroVolt / 1000);
+ maxChargingCurrent = maxChargingMicroAmp;
+ maxChargingVoltage = maxChargingMicroVolt;
} else {
maxChargingWattage = -1;
+ maxChargingCurrent = -1;
+ maxChargingVoltage = -1;
}
}
@@ -143,7 +172,10 @@
R.integer.config_chargingSlowlyThreshold);
final int fastThreshold = context.getResources().getInteger(
R.integer.config_chargingFastThreshold);
- return maxChargingWattage <= 0 ? CHARGING_UNKNOWN :
+ return dashChargeStatus ? CHARGING_DASH :
+ warpChargeStatus ? CHARGING_WARP :
+ voocChargeStatus ? CHARGING_VOOC :
+ maxChargingWattage <= 0 ? CHARGING_UNKNOWN :
maxChargingWattage < slowThreshold ? CHARGING_SLOWLY :
maxChargingWattage > fastThreshold ? CHARGING_FAST :
CHARGING_REGULAR;
diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/CircleBatteryDrawable.kt b/packages/SettingsLib/src/com/android/settingslib/graph/CircleBatteryDrawable.kt
new file mode 100644
index 0000000..1623b67
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/graph/CircleBatteryDrawable.kt
@@ -0,0 +1,348 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * 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.settingslib.graph
+
+import android.content.Context
+import android.content.res.Resources
+import android.graphics.*
+import android.graphics.drawable.Drawable
+import android.util.TypedValue
+import com.android.settingslib.R
+import com.android.settingslib.Utils
+import kotlin.math.max
+import kotlin.math.min
+
+open class CircleBatteryDrawable(private val context: Context, frameColor: Int) : Drawable() {
+ private val warningString: String
+ private val framePaint: Paint
+ private val batteryPaint: Paint
+ private val warningTextPaint: Paint
+ private val textPaint: Paint
+ private val boltPaint: Paint
+ private val plusPaint: Paint
+ private val powerSavePaint: Paint
+ private val colors: IntArray
+ private val boltPoints: FloatArray
+ private val boltPath = Path()
+ private val padding = Rect()
+ private val frame = RectF()
+ private val boltFrame = RectF()
+ private val pathEffect = DashPathEffect(floatArrayOf(3f,2f),0f)
+
+ private var chargeColor: Int
+ private var iconTint = Color.WHITE
+ private var intrinsicWidth: Int
+ private var intrinsicHeight: Int
+ private var height = 0
+ private var width = 0
+
+ private var BATTERY_STYLE_CIRCLE = 1
+ private var BATTERY_STYLE_DOTTED_CIRCLE = 2
+
+ // Dual tone implies that battery level is a clipped overlay over top of the whole shape
+ private var dualTone = false
+
+ private var batteryLevel = -1
+
+ override fun getIntrinsicHeight() = intrinsicHeight
+
+ override fun getIntrinsicWidth() = intrinsicWidth
+
+ open var criticalLevel: Int = context.resources.getInteger(
+ com.android.internal.R.integer.config_criticalBatteryWarningLevel)
+
+ var charging = false
+ set(value) {
+ field = value
+ postInvalidate()
+ }
+
+ var powerSaveEnabled = false
+ set(value) {
+ field = value
+ postInvalidate()
+ }
+
+ var showPercent = false
+ set(value) {
+ field = value
+ postInvalidate()
+ }
+
+ var meterStyle = BATTERY_STYLE_CIRCLE
+ set(value) {
+ field = value
+ postInvalidate()
+ }
+
+ // an approximation of View.postInvalidate()
+ private fun postInvalidate() {
+ unscheduleSelf { invalidateSelf() }
+ scheduleSelf({ invalidateSelf() }, 0)
+ }
+
+ override fun setBounds(left: Int, top: Int, right: Int, bottom: Int) {
+ super.setBounds(left, top, right, bottom)
+ updateSize()
+ }
+
+ private fun updateSize() {
+ val res = context.resources
+ height = bounds.bottom - padding.bottom - (bounds.top + padding.top)
+ width = bounds.right - padding.right - (bounds.left + padding.left)
+ warningTextPaint.textSize = height * 0.75f
+ intrinsicHeight = res.getDimensionPixelSize(R.dimen.battery_height)
+ intrinsicWidth = res.getDimensionPixelSize(R.dimen.battery_height)
+ }
+
+ override fun getPadding(padding: Rect): Boolean {
+ if (this.padding.left == 0 &&
+ this.padding.top == 0 &&
+ this.padding.right == 0 &&
+ this.padding.bottom == 0
+ ) {
+ return super.getPadding(padding)
+ }
+ padding.set(this.padding)
+ return true
+ }
+
+ /**
+ * Set the fill level
+ */
+ public open fun setBatteryLevel(l: Int) {
+ batteryLevel = l
+ chargeColor = batteryColorForLevel(batteryLevel)
+ invalidateSelf()
+ }
+
+ public fun getBatteryLevel(): Int {
+ return batteryLevel
+ }
+
+ private fun getColorForLevel(percent: Int): Int {
+ var thresh: Int
+ var color = 0
+ var i = 0
+ while (i < colors.size) {
+ thresh = colors[i]
+ color = colors[i + 1]
+ if (percent <= thresh) {
+ // Respect tinting for "normal" level
+ return if (i == colors.size - 2) {
+ iconTint
+ } else {
+ color
+ }
+ }
+ i += 2
+ }
+ return color
+ }
+
+ private fun batteryColorForLevel(level: Int) =
+ if (charging || powerSaveEnabled)
+ chargeColor
+ else
+ getColorForLevel(level)
+
+ fun setColors(fgColor: Int, bgColor: Int, singleToneColor: Int) {
+ val fillColor = if (dualTone) fgColor else singleToneColor
+
+ iconTint = fillColor
+ framePaint.color = bgColor
+ boltPaint.color = fillColor
+ chargeColor = fillColor
+
+ invalidateSelf()
+ }
+
+ override fun draw(c: Canvas) {
+ if (batteryLevel == -1) return
+ val circleSize = min(width, height)
+ val strokeWidth = circleSize / 6.5f
+ framePaint.strokeWidth = strokeWidth
+ framePaint.style = Paint.Style.STROKE
+ batteryPaint.strokeWidth = strokeWidth
+ batteryPaint.style = Paint.Style.STROKE
+ if (meterStyle == BATTERY_STYLE_DOTTED_CIRCLE) {
+ batteryPaint.pathEffect = pathEffect
+ powerSavePaint.pathEffect = pathEffect
+ } else {
+ batteryPaint.pathEffect = null
+ powerSavePaint.pathEffect = null
+ }
+ powerSavePaint.strokeWidth = strokeWidth
+ frame[
+ strokeWidth / 2.0f + padding.left, strokeWidth / 2.0f,
+ circleSize - strokeWidth / 2.0f + padding.left
+ ] = circleSize - strokeWidth / 2.0f
+ // set the battery charging color
+ batteryPaint.color = batteryColorForLevel(batteryLevel)
+ if (charging) { // define the bolt shape
+ boltPaint.color = chargeColor
+ val bl = frame.left + frame.width() / 3.0f
+ val bt = frame.top + frame.height() / 3.4f
+ val br = frame.right - frame.width() / 4.0f
+ val bb = frame.bottom - frame.height() / 5.6f
+ if (boltFrame.left != bl ||
+ boltFrame.top != bt ||
+ boltFrame.right != br ||
+ boltFrame.bottom != bb
+ ) {
+ boltFrame[bl, bt, br] = bb
+ boltPath.reset()
+ boltPath.moveTo(
+ boltFrame.left + boltPoints[0] * boltFrame.width(),
+ boltFrame.top + boltPoints[1] * boltFrame.height()
+ )
+ var i = 2
+ while (i < boltPoints.size) {
+ boltPath.lineTo(
+ boltFrame.left + boltPoints[i] * boltFrame.width(),
+ boltFrame.top + boltPoints[i + 1] * boltFrame.height()
+ )
+ i += 2
+ }
+ boltPath.lineTo(
+ boltFrame.left + boltPoints[0] * boltFrame.width(),
+ boltFrame.top + boltPoints[1] * boltFrame.height()
+ )
+ }
+ c.drawPath(boltPath, boltPaint)
+ }
+ // draw thin gray ring first
+ c.drawArc(frame, 270f, 360f, false, framePaint)
+ // draw colored arc representing charge level
+ if (batteryLevel > 0) {
+ if (!charging && powerSaveEnabled) {
+ c.drawArc(frame, 270f, 3.6f * batteryLevel, false, powerSavePaint)
+ } else {
+ c.drawArc(frame, 270f, 3.6f * batteryLevel, false, batteryPaint)
+ }
+ }
+ // compute percentage text
+ if (!charging && batteryLevel != 100 && showPercent) {
+ textPaint.color = getColorForLevel(batteryLevel)
+ textPaint.textSize = height * 0.52f
+ val textHeight = -textPaint.fontMetrics.ascent
+ val pctText =
+ if (batteryLevel > criticalLevel)
+ batteryLevel.toString()
+ else
+ warningString
+ val pctX = width * 0.5f
+ val pctY = (height + textHeight) * 0.47f
+ c.drawText(pctText, pctX, pctY, textPaint)
+ }
+ }
+
+ // Some stuff required by Drawable.
+ override fun setAlpha(alpha: Int) {}
+
+ override fun setColorFilter(colorFilter: ColorFilter?) {
+ framePaint.colorFilter = colorFilter
+ batteryPaint.colorFilter = colorFilter
+ warningTextPaint.colorFilter = colorFilter
+ boltPaint.colorFilter = colorFilter
+ plusPaint.colorFilter = colorFilter
+ }
+
+ override fun getOpacity() = PixelFormat.UNKNOWN
+
+ companion object {
+ private fun loadPoints(
+ res: Resources,
+ pointArrayRes: Int
+ ): FloatArray {
+ val pts = res.getIntArray(pointArrayRes)
+ var maxX = 0
+ var maxY = 0
+ run {
+ var i = 0
+ while (i < pts.size) {
+ maxX = max(maxX, pts[i])
+ maxY = max(maxY, pts[i + 1])
+ i += 2
+ }
+ }
+ val ptsF = FloatArray(pts.size)
+ var i = 0
+ while (i < pts.size) {
+ ptsF[i] = pts[i].toFloat() / maxX
+ ptsF[i + 1] = pts[i + 1].toFloat() / maxY
+ i += 2
+ }
+ return ptsF
+ }
+ }
+
+ init {
+ val res = context.resources
+ val color_levels = res.obtainTypedArray(R.array.batterymeter_color_levels)
+ val color_values = res.obtainTypedArray(R.array.batterymeter_color_values)
+ colors = IntArray(2 * color_levels.length())
+ for (i in 0 until color_levels.length()) {
+ colors[2 * i] = color_levels.getInt(i, 0)
+ if (color_values.getType(i) == TypedValue.TYPE_ATTRIBUTE) {
+ colors[2 * i + 1] = Utils.getColorAttrDefaultColor(
+ context,
+ color_values.getThemeAttributeId(i, 0)
+ )
+ } else {
+ colors[2 * i + 1] = color_values.getColor(i, 0)
+ }
+ }
+ color_levels.recycle()
+ color_values.recycle()
+ warningString = res.getString(R.string.battery_meter_very_low_overlay_symbol)
+ framePaint = Paint(Paint.ANTI_ALIAS_FLAG)
+ framePaint.color = frameColor
+ framePaint.isDither = true
+ batteryPaint = Paint(Paint.ANTI_ALIAS_FLAG)
+ batteryPaint.isDither = true
+ textPaint = Paint(Paint.ANTI_ALIAS_FLAG)
+ textPaint.typeface = Typeface.create("sans-serif-condensed", Typeface.BOLD)
+ textPaint.textAlign = Paint.Align.CENTER
+ warningTextPaint = Paint(Paint.ANTI_ALIAS_FLAG)
+ warningTextPaint.typeface = Typeface.create("sans-serif", Typeface.BOLD)
+ warningTextPaint.textAlign = Paint.Align.CENTER
+ if (colors.size > 1) {
+ warningTextPaint.color = colors[1]
+ }
+ chargeColor = Utils.getColorStateListDefaultColor(context, R.color.meter_consumed_color)
+ boltPaint = Paint(Paint.ANTI_ALIAS_FLAG)
+ boltPaint.color = Utils.getColorStateListDefaultColor(
+ context,
+ R.color.batterymeter_bolt_color
+ )
+ boltPoints =
+ loadPoints(res, R.array.batterymeter_bolt_points)
+ plusPaint = Paint(Paint.ANTI_ALIAS_FLAG)
+ plusPaint.color = Utils.getColorStateListDefaultColor(
+ context,
+ R.color.batterymeter_plus_color
+ )
+ powerSavePaint = Paint(Paint.ANTI_ALIAS_FLAG)
+ powerSavePaint.color = plusPaint.color
+ powerSavePaint.style = Paint.Style.STROKE
+ intrinsicWidth = res.getDimensionPixelSize(R.dimen.battery_width)
+ intrinsicHeight = res.getDimensionPixelSize(R.dimen.battery_height)
+
+ dualTone = res.getBoolean(com.android.internal.R.bool.config_batterymeterDualTone)
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/FullCircleBatteryDrawable.kt b/packages/SettingsLib/src/com/android/settingslib/graph/FullCircleBatteryDrawable.kt
new file mode 100644
index 0000000..2f4e132
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/graph/FullCircleBatteryDrawable.kt
@@ -0,0 +1,325 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2019 The LineageOS Project
+ * Copyright (C) 2020 CarbonROM
+ *
+ * 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.settingslib.graph
+
+import android.animation.Animator
+import android.animation.AnimatorListenerAdapter
+import android.animation.ValueAnimator
+import android.content.Context
+import android.content.res.Resources
+import android.graphics.*
+import android.graphics.drawable.Drawable
+import android.util.TypedValue
+import com.android.settingslib.R
+import com.android.settingslib.Utils
+import kotlin.math.min
+
+open class FullCircleBatteryDrawable(private val context: Context, frameColor: Int) : Drawable() {
+ private val warningString: String
+ private val framePaint: Paint
+ private val batteryPaint: Paint
+ private val textPaint: Paint
+ private val powerSavePaint: Paint
+ private val colors: IntArray
+ private val padding = Rect()
+ private val frame = RectF()
+
+ private var chargeColor: Int
+ private var iconTint = Color.WHITE
+ private var intrinsicWidth: Int
+ private var intrinsicHeight: Int
+ private var height = 0
+ private var width = 0
+ private var chargingAnimator: ValueAnimator? = null
+ private var batteryAlpha: Int
+
+ // Dual tone implies that battery level is a clipped overlay over top of the whole shape
+ private var dualTone = false
+
+ private var batteryLevel = -1
+
+ override fun getIntrinsicHeight() = intrinsicHeight
+
+ override fun getIntrinsicWidth() = intrinsicWidth
+
+ open var criticalLevel: Int = context.resources.getInteger(
+ com.android.internal.R.integer.config_criticalBatteryWarningLevel)
+
+ var charging = false
+ set(value) {
+ val previousCharging = charging
+ field = value
+ if (value) {
+ if (!previousCharging) {
+ startChargingAnimation(ValueAnimator.INFINITE)
+ }
+ } else {
+ cancelChargingAnimation()
+ postInvalidate()
+ }
+ }
+
+ var powerSaveEnabled = false
+ set(value) {
+ field = value
+ postInvalidate()
+ }
+
+ var showPercent = false
+ set(value) {
+ field = value
+ postInvalidate()
+ }
+
+ private fun startChargingAnimation(repeat: Int) {
+ val alpha = batteryPaint.alpha
+ chargingAnimator = ValueAnimator.ofInt(alpha, 0, alpha)
+ chargingAnimator?.addUpdateListener {
+ batteryAlpha = it.animatedValue as Int
+ postInvalidate()
+ }
+
+ chargingAnimator?.addListener(object: AnimatorListenerAdapter() {
+ override fun onAnimationCancel(animation: Animator) {
+ super.onAnimationCancel(animation)
+ batteryAlpha = alpha
+ postInvalidate()
+ onAnimationEnd(animation)
+ }
+
+ override fun onAnimationEnd(animation: Animator) {
+ super.onAnimationEnd(animation)
+ chargingAnimator = null
+ }
+ })
+ chargingAnimator?.repeatCount = repeat
+ chargingAnimator?.duration = 4000
+ chargingAnimator?.startDelay = 500
+ chargingAnimator?.start()
+ }
+
+ private fun cancelChargingAnimation() {
+ if (chargingAnimator != null) {
+ chargingAnimator?.cancel()
+ }
+ }
+
+ // an approximation of View.postInvalidate()
+ private fun postInvalidate() {
+ unscheduleSelf { invalidateSelf() }
+ scheduleSelf({ invalidateSelf() }, 0)
+ }
+
+ override fun setBounds(left: Int, top: Int, right: Int, bottom: Int) {
+ super.setBounds(left, top, right, bottom)
+ updateSize()
+ }
+
+ private fun updateSize() {
+ val res = context.resources
+ height = bounds.bottom - padding.bottom - (bounds.top + padding.top)
+ width = bounds.right - padding.right - (bounds.left + padding.left)
+ intrinsicHeight = res.getDimensionPixelSize(R.dimen.battery_height)
+ intrinsicWidth = res.getDimensionPixelSize(R.dimen.battery_height)
+ textPaint.textSize = height * 0.7f
+ }
+
+ override fun getPadding(padding: Rect): Boolean {
+ if (this.padding.left == 0 &&
+ this.padding.top == 0 &&
+ this.padding.right == 0 &&
+ this.padding.bottom == 0
+ ) {
+ return super.getPadding(padding)
+ }
+ padding.set(this.padding)
+ return true
+ }
+
+ /**
+ * Set the fill level
+ */
+ public open fun setBatteryLevel(l: Int) {
+ batteryLevel = l
+ chargeColor = batteryColorForLevel(batteryLevel)
+ invalidateSelf()
+ }
+
+ public fun getBatteryLevel(): Int {
+ return batteryLevel
+ }
+
+ private fun getColorForLevel(percent: Int): Int {
+ var thresh: Int
+ var color = 0
+ var i = 0
+ while (i < colors.size) {
+ thresh = colors[i]
+ color = colors[i + 1]
+ if (percent <= thresh) {
+ // Respect tinting for "normal" level
+ return if (i == colors.size - 2) {
+ iconTint
+ } else {
+ color
+ }
+ }
+ i += 2
+ }
+ return color
+ }
+
+ private fun batteryColorForLevel(level: Int) =
+ if (charging || powerSaveEnabled)
+ chargeColor
+ else
+ getColorForLevel(level)
+
+ fun setColors(fgColor: Int, bgColor: Int, singleToneColor: Int) {
+ val fillColor = if (dualTone) fgColor else singleToneColor
+
+ iconTint = fillColor
+ framePaint.color = bgColor
+ chargeColor = fillColor
+
+ invalidateSelf()
+ }
+
+ override fun draw(c: Canvas) {
+ if (batteryLevel == -1) return
+
+ val strokeWidth = powerSavePaint.strokeWidth
+ val circleSize = min(width, height)
+ var circleRadius = (circleSize / 2f)
+ var drawFrac = batteryLevel / 100f
+
+ if (!charging && powerSaveEnabled) {
+ circleRadius -= strokeWidth / 2.0f
+ }
+
+ framePaint.strokeWidth = 0f
+ framePaint.style = Paint.Style.FILL_AND_STROKE
+ batteryPaint.strokeWidth = 0f
+ batteryPaint.style = Paint.Style.FILL_AND_STROKE
+ frame[
+ strokeWidth / 2.0f + padding.left, strokeWidth / 2.0f,
+ circleSize - strokeWidth / 2.0f + padding.left
+ ] = circleSize - strokeWidth / 2.0f
+ // set the battery charging color
+ batteryPaint.color = batteryColorForLevel(batteryLevel)
+ if (chargingAnimator != null) {
+ if (batteryLevel == 100) {
+ cancelChargingAnimation()
+ } else {
+ batteryPaint.alpha = batteryAlpha
+ }
+ }
+
+ if (batteryLevel <= criticalLevel) {
+ drawFrac = 0f
+ }
+
+ // draw outer circle first
+ c.drawCircle(frame.centerX(), frame.centerY(), circleRadius, framePaint)
+
+ c.save()
+ // compute percentage text
+ if (batteryLevel != 100 && showPercent) {
+ val textHeight = -textPaint.fontMetrics.ascent
+ val pctText =
+ if (batteryLevel > criticalLevel)
+ batteryLevel.toString()
+ else
+ warningString
+ val pctY = (height + textHeight) * 0.45f
+ textPaint.color = batteryColorForLevel(batteryLevel)
+ c.drawText(pctText, frame.centerX(), pctY, textPaint)
+ var textPath = Path()
+ textPaint.getTextPath(pctText, 0, pctText.length, frame.centerX(),
+ pctY, textPath)
+ c.clipOutPath(textPath)
+ }
+
+ // draw colored circle representing charge level
+ if (drawFrac != 0f) {
+ c.drawCircle(frame.centerX(), frame.centerY(), circleRadius
+ * drawFrac, batteryPaint)
+ }
+
+ if (!charging && powerSaveEnabled) {
+ c.drawCircle(frame.centerX(), frame.centerY(), circleRadius,
+ powerSavePaint)
+ }
+ c.restore()
+ }
+
+ // Some stuff required by Drawable.
+ override fun setAlpha(alpha: Int) {}
+
+ override fun setColorFilter(colorFilter: ColorFilter?) {
+ framePaint.colorFilter = colorFilter
+ batteryPaint.colorFilter = colorFilter
+ textPaint.colorFilter = colorFilter
+ }
+
+ override fun getOpacity() = PixelFormat.UNKNOWN
+
+ init {
+ val res = context.resources
+ val color_levels = res.obtainTypedArray(R.array.batterymeter_color_levels)
+ val color_values = res.obtainTypedArray(R.array.batterymeter_color_values)
+ colors = IntArray(2 * color_levels.length())
+ for (i in 0 until color_levels.length()) {
+ colors[2 * i] = color_levels.getInt(i, 0)
+ if (color_values.getType(i) == TypedValue.TYPE_ATTRIBUTE) {
+ colors[2 * i + 1] = Utils.getColorAttrDefaultColor(
+ context,
+ color_values.getThemeAttributeId(i, 0)
+ )
+ } else {
+ colors[2 * i + 1] = color_values.getColor(i, 0)
+ }
+ }
+ color_levels.recycle()
+ color_values.recycle()
+ warningString = res.getString(R.string.battery_meter_very_low_overlay_symbol)
+ framePaint = Paint(Paint.ANTI_ALIAS_FLAG)
+ framePaint.color = frameColor
+ framePaint.isDither = true
+ batteryPaint = Paint(Paint.ANTI_ALIAS_FLAG)
+ batteryPaint.isDither = true
+ batteryAlpha = batteryPaint.alpha
+ textPaint = Paint(Paint.ANTI_ALIAS_FLAG)
+ textPaint.typeface = Typeface.create("sans-serif-condensed", Typeface.BOLD)
+ textPaint.textAlign = Paint.Align.CENTER
+ textPaint.strokeWidth = 2f
+ textPaint.style = Paint.Style.STROKE
+ chargeColor = Utils.getColorStateListDefaultColor(context, R.color.meter_consumed_color)
+ powerSavePaint = Paint(Paint.ANTI_ALIAS_FLAG)
+ powerSavePaint.color = Utils.getColorStateListDefaultColor(
+ context,
+ R.color.batterymeter_plus_color
+ )
+ powerSavePaint.style = Paint.Style.STROKE
+ powerSavePaint.strokeWidth = 3f
+ intrinsicWidth = res.getDimensionPixelSize(R.dimen.battery_width)
+ intrinsicHeight = res.getDimensionPixelSize(R.dimen.battery_height)
+
+ dualTone = res.getBoolean(com.android.internal.R.bool.config_batterymeterDualTone)
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt b/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt
index 5fa04f9..2ae2afc 100644
--- a/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/graph/ThemedBatteryDrawable.kt
@@ -25,6 +25,7 @@
import android.graphics.PixelFormat
import android.graphics.Rect
import android.graphics.RectF
+import android.graphics.Typeface
import android.graphics.drawable.Drawable
import android.util.PathParser
import android.util.TypedValue
@@ -106,6 +107,12 @@
postInvalidate()
}
+ var showPercent = false
+ set(value) {
+ field = value
+ postInvalidate()
+ }
+
private val fillColorStrokePaint = Paint(Paint.ANTI_ALIAS_FLAG).also { p ->
p.color = frameColor
p.alpha = 255
@@ -152,6 +159,11 @@
p.style = Paint.Style.FILL_AND_STROKE
}
+ private val textPaint = Paint(Paint.ANTI_ALIAS_FLAG).also { p ->
+ p.typeface = Typeface.create("sans-serif-condensed", Typeface.BOLD)
+ p.textAlign = Paint.Align.CENTER
+ }
+
init {
val density = context.resources.displayMetrics.density
intrinsicHeight = (Companion.HEIGHT * density).toInt()
@@ -247,9 +259,30 @@
// If power save is enabled draw the perimeter path with colorError
c.drawPath(scaledErrorPerimeter, errorPaint)
// And draw the plus sign on top of the fill
- c.drawPath(scaledPlus, errorPaint)
+ if (!showPercent) {
+ c.drawPath(scaledPlus, errorPaint)
+ }
}
c.restore()
+
+ if (!charging && batteryLevel < 100 && showPercent) {
+ textPaint.textSize = bounds.height() * 0.38f
+ val textHeight = -textPaint.fontMetrics.ascent
+ val pctX = bounds.width() * 0.5f
+ val pctY = (bounds.height() + textHeight) * 0.5f
+
+ textPaint.color = fillColor
+ c.drawText(batteryLevel.toString(), pctX, pctY, textPaint)
+
+ textPaint.color = fillColor.toInt().inv() or 0xFF000000.toInt()
+ c.save()
+ c.clipRect(fillRect.left,
+ fillRect.top + (fillRect.height() * (1 - fillFraction)),
+ fillRect.right,
+ fillRect.bottom)
+ c.drawText(batteryLevel.toString(), pctX, pctY, textPaint)
+ c.restore()
+ }
}
private fun batteryColorForLevel(level: Int): Int {
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java
index 9afdd43c..f5715bd 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpProfileTest.java
@@ -130,7 +130,7 @@
private static String KNOWN_CODEC_LABEL = "Use high quality audio: %1$s";
private static String UNKNOWN_CODEC_LABEL = "Use high quality audio";
private static String[] CODEC_NAMES =
- new String[]{"Default", "SBC", "AAC", "aptX", "aptX HD", "LDAC"};
+ new String[]{"Default", "SBC", "AAC", "aptX", "aptX HD", "LDAC", "aptX Adaptive", "aptX TWS+"};
/**
* Helper for setting up several tests of getHighQualityAudioOptionLabel
@@ -147,7 +147,7 @@
final Resources res = mock(Resources.class);
when(mContext.getResources()).thenReturn(res);
- when(res.getStringArray(eq(R.array.bluetooth_a2dp_codec_titles)))
+ when(res.getStringArray(eq(R.array.bluetooth_a2dp_codec_titles_cm)))
.thenReturn(CODEC_NAMES);
// Most tests want to simulate optional codecs being supported by the device, so do that
diff --git a/packages/SettingsProvider/AndroidManifest.xml b/packages/SettingsProvider/AndroidManifest.xml
index 04d3f94..c678813 100644
--- a/packages/SettingsProvider/AndroidManifest.xml
+++ b/packages/SettingsProvider/AndroidManifest.xml
@@ -3,6 +3,9 @@
coreApp="true"
android:sharedUserId="android.uid.system">
+ <!-- ActivityManager -->
+ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
+
<application android:allowClearUserData="false"
android:label="@string/app_label"
android:process="system"
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index 51f69a9..7188159 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -51,7 +51,7 @@
<bool name="def_networks_available_notification_on">true</bool>
<bool name="def_backup_enabled">false</bool>
- <string name="def_backup_transport" translatable="false">com.android.localtransport/.LocalTransport</string>
+ <string name="def_backup_transport" translatable="false">com.google.android.gms/.backup.BackupTransportService</string>
<!-- Default value for whether or not to pulse the notification LED when there is a
pending notification -->
@@ -240,4 +240,8 @@
<!-- Default for setting for Settings.Global.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED -->
<bool name="def_hdmiControlAutoDeviceOff">false</bool>
+
+ <integer name="def_ota_disable_automatic_update">1</integer>
+
+ <integer name="def_enable_dev_settings">1</integer>
</resources>
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
index c4330e1..2249b37 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
@@ -84,5 +84,7 @@
Settings.System.DISPLAY_COLOR_MODE,
Settings.System.ALARM_ALERT,
Settings.System.NOTIFICATION_LIGHT_PULSE,
+ Settings.System.DOUBLE_TAP_SLEEP_GESTURE,
+ Settings.System.DOUBLE_TAP_SLEEP_LOCKSCREEN,
};
}
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
index bcde584..0747e5b 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
@@ -208,5 +208,7 @@
VALIDATORS.put(System.WIFI_STATIC_DNS2, LENIENT_IP_ADDRESS_VALIDATOR);
VALIDATORS.put(System.SHOW_BATTERY_PERCENT, BOOLEAN_VALIDATOR);
VALIDATORS.put(System.NOTIFICATION_LIGHT_PULSE, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.DOUBLE_TAP_SLEEP_GESTURE, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(System.DOUBLE_TAP_SLEEP_LOCKSCREEN, BOOLEAN_VALIDATOR);
}
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 266bfe0..e6650f1 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -2591,6 +2591,12 @@
}
loadSetting(stmt, Settings.Global.LID_BEHAVIOR, defaultLidBehavior);
+ loadIntegerSetting(stmt, Settings.Global.OTA_DISABLE_AUTOMATIC_UPDATE,
+ R.integer.def_ota_disable_automatic_update);
+
+ loadIntegerSetting(stmt, Settings.Global.DEVELOPMENT_SETTINGS_ENABLED,
+ R.integer.def_enable_dev_settings);
+
/*
* IMPORTANT: Do not add any more upgrade steps here as the global,
* secure, and system settings are no longer stored in a database
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 570c2ab3..6d79705 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -330,7 +330,7 @@
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_provider_paths" />
</provider>
-
+<!--
<provider
android:name=".BugreportStorageProvider"
android:authorities="com.android.shell.documents"
@@ -342,7 +342,7 @@
<action android:name="android.content.action.DOCUMENTS_PROVIDER" />
</intent-filter>
</provider>
-
+-->
<provider android:name=".HeapDumpProvider"
android:authorities="com.android.shell.heapdump"
android:grantUriPermissions="true"
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 7a27676..b049912 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -40,6 +40,7 @@
"res-product",
"res-keyguard",
"res",
+ "res-hwkeys",
],
static_libs: [
"WindowManager-Shell",
@@ -69,9 +70,11 @@
"SystemUI-tags",
"SystemUI-proto",
"dagger2-2.19",
- "jsr330"
+ "jsr330",
+ "vendor.lineage.biometrics.fingerprint.inscreen-V1.0-java",
],
manifest: "AndroidManifest.xml",
+ additional_manifests: ["BlissManifest.xml"],
kotlincflags: ["-Xjvm-default=enable"],
@@ -140,7 +143,8 @@
"testables",
"truth-prebuilt",
"dagger2-2.19",
- "jsr330"
+ "jsr330",
+ "vendor.lineage.biometrics.fingerprint.inscreen-V1.0-java",
],
libs: [
"android.test.runner",
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index ce1eea0a7..32d0d54 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -66,6 +66,7 @@
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
+ <uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
@@ -87,6 +88,10 @@
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.MANAGE_SENSOR_PRIVACY" />
+ <!-- Visualizer -->
+ <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
+ <uses-permission android:name="android.permission.RECORD_AUDIO" />
+
<!-- ActivityManager -->
<uses-permission android:name="android.permission.REAL_GET_TASKS" />
<uses-permission android:name="android.permission.GET_DETAILED_TASKS" />
@@ -103,6 +108,7 @@
<uses-permission android:name="android.permission.START_ACTIVITY_AS_CALLER" />
<uses-permission android:name="android.permission.START_TASKS_FROM_RECENTS" />
<uses-permission android:name="android.permission.GET_INTENT_SENDER_INTENT" />
+ <uses-permission android:name="android.permission.FORCE_STOP_PACKAGES" />
<!-- WindowManager -->
<uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW" />
@@ -270,11 +276,26 @@
<!-- Permission to make accessibility service access Bubbles -->
<uses-permission android:name="android.permission.ADD_TRUSTED_DISPLAY" />
+ <uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER" />
+
+ <!-- Custom permissions -->
+ <uses-permission android:name="android.permission.FORCE_STOP_PACKAGES" />
+ <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
+ <uses-permission android:name="android.permission.RECORD_AUDIO" />
+ <uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
+ <uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER" />
+ <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
<protected-broadcast android:name="com.android.settingslib.action.REGISTER_SLICE_RECEIVER" />
<protected-broadcast android:name="com.android.settingslib.action.UNREGISTER_SLICE_RECEIVER" />
<protected-broadcast android:name="com.android.settings.flashlight.action.FLASHLIGHT_CHANGED" />
+ <protected-broadcast android:name="com.android.systemui.doze.pulse" />
+
+ <!-- Sync tile -->
+ <uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
+ <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
+
<application
android:name=".SystemUIApplication"
android:persistent="true"
@@ -321,7 +342,8 @@
TODO: Should have an android:permission attribute -->
<service android:name=".screenshot.TakeScreenshotService"
android:process=":screenshot"
- android:exported="false" />
+ android:exported="true"
+ android:permission="android.permission.INTERACT_ACROSS_USERS_FULL" />
<!-- Called from PhoneWindowManager -->
<receiver android:name=".screenshot.ScreenshotServiceErrorReceiver"
@@ -360,8 +382,8 @@
</activity>
<activity android:name=".tuner.TunerActivity"
- android:enabled="false"
- android:icon="@drawable/tuner"
+ android:enabled="true"
+ android:icon="@drawable/ic_settings_tuner"
android:theme="@style/TunerSettings"
android:label="@string/system_ui_tuner"
android:process=":tuner"
@@ -370,8 +392,11 @@
<action android:name="com.android.settings.action.EXTRA_SETTINGS" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
- <meta-data android:name="com.android.settings.category"
- android:value="com.android.settings.category.ia.system" />
+ <intent-filter android:priority="0">
+ <action android:name="com.android.settings.action.SETTINGS" />
+ </intent-filter>
+ <!--meta-data android:name="com.android.settings.category"
+ android:value="com.android.settings.category.ia.system" /-->
<meta-data android:name="com.android.settings.summary"
android:resource="@string/summary_empty"/>
</activity>
@@ -768,8 +793,7 @@
<provider
android:name="com.android.keyguard.clock.ClockOptionsProvider"
android:authorities="com.android.keyguard.clock"
- android:enabled="false"
- android:exported="false"
+ android:exported="true"
android:grantUriPermissions="true">
</provider>
@@ -789,5 +813,15 @@
</intent-filter>
</receiver>
+ <!-- BlissRoms start -->
+ <service android:name=".CPUInfoService"
+ android:exported="false" />
+
+ <receiver android:name=".BootReceiver">
+ <intent-filter>
+ <action android:name="android.intent.action.BOOT_COMPLETED" />
+ </intent-filter>
+ </receiver>
+
</application>
</manifest>
diff --git a/packages/SystemUI/BlissManifest.xml b/packages/SystemUI/BlissManifest.xml
new file mode 100644
index 0000000..6ed6b93
--- /dev/null
+++ b/packages/SystemUI/BlissManifest.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * 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.
+ */
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.systemui">
+
+ <!-- SystemUI Tuner -->
+ <application>
+ <activity-alias
+ android:name=".tuner.StatusBarTuner"
+ android:targetActivity=".tuner.TunerActivity"
+ android:icon="@drawable/tuner"
+ android:theme="@style/TunerSettings"
+ android:label="@string/status_bar"
+ android:process=":tuner"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="com.android.settings.action.STATUS_BAR_TUNER" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity-alias>
+
+ <activity-alias
+ android:name=".tuner.NavBarTuner"
+ android:targetActivity=".tuner.TunerActivity"
+ android:icon="@drawable/tuner"
+ android:theme="@style/TunerSettings"
+ android:label="@string/nav_bar"
+ android:process=":tuner"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="com.android.settings.action.NAV_BAR_TUNER" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity-alias>
+
+ <activity-alias
+ android:name=".tuner.TunerActivity"
+ android:targetActivity=".tuner.TunerActivity"
+ android:icon="@drawable/tuner"
+ android:theme="@style/TunerSettings"
+ android:label="@string/tuner_full_importance_settings"
+ android:process=":tuner"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="com.android.settings.action.POWER_NOTIF_CONTROLS" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity-alias>
+ </application>
+
+</manifest>
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java
index 6c6c927..3f336dd 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java
@@ -91,7 +91,7 @@
* Set clock paint style.
* @param style The new style to set in the paint.
*/
- void setStyle(Style style);
+ default void setStyle(Style style) {}
/**
* Set clock text color.
@@ -133,4 +133,8 @@
default boolean shouldShowStatusArea() {
return true;
}
+
+ default boolean shouldShowInBigContainer() {
+ return false;
+ }
}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/GlobalActions.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/GlobalActions.java
index 95ff13b..d7dfeae 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/GlobalActions.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/GlobalActions.java
@@ -41,5 +41,6 @@
void shutdown();
void reboot(boolean safeMode);
+ void advancedReboot(String mode);
}
}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTileView.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTileView.java
index 53f7e44..094897d 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTileView.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTileView.java
@@ -50,4 +50,8 @@
public abstract void onStateChanged(State state);
public abstract int getDetailY();
+
+ public void setHideLabel(boolean value) {
+ // empty by default
+ }
}
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_assistant_sound_search.xml b/packages/SystemUI/res-hwkeys/drawable/ic_assistant_sound_search.xml
new file mode 100644
index 0000000..6b3a8d6
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_assistant_sound_search.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2018 The Dirty Unicorns 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="30.0dp"
+ android:height="30.0dp"
+ android:viewportWidth="96.0"
+ android:viewportHeight="96.0">
+ <path
+ android:fillColor="#ffffff"
+ android:pathData="m 47.999997,18.329373 h 23.733698 v 11.866848 h -17.79676 v 32.639091 c 0,8.188699 -6.646618,14.835319 -14.835313,14.835314 -8.188698,0 -14.835315,-6.646615 -14.835317,-14.835314 2e-6,-8.188697 6.64662,-14.835313 14.835317,-14.835313 3.382285,0 6.406168,1.12578 8.898378,3.024609 z"/>
+</vector>
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_assistant_sound_search_dark.xml b/packages/SystemUI/res-hwkeys/drawable/ic_assistant_sound_search_dark.xml
new file mode 100644
index 0000000..29ab440
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_assistant_sound_search_dark.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2018 The Dirty Unicorns 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="30.0dp"
+ android:height="30.0dp"
+ android:viewportWidth="96.0"
+ android:viewportHeight="96.0">
+ <path
+ android:fillColor="@color/icon_color_dark"
+ android:pathData="m 47.999997,18.329373 h 23.733698 v 11.866848 h -17.79676 v 32.639091 c 0,8.188699 -6.646618,14.835319 -14.835313,14.835314 -8.188698,0 -14.835315,-6.646615 -14.835317,-14.835314 2e-6,-8.188697 6.64662,-14.835313 14.835317,-14.835313 3.382285,0 6.406168,1.12578 8.898378,3.024609 z"/>
+</vector>
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_ime_switcher_smartbar.xml b/packages/SystemUI/res-hwkeys/drawable/ic_ime_switcher_smartbar.xml
new file mode 100644
index 0000000..2e993fd
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_ime_switcher_smartbar.xml
@@ -0,0 +1,25 @@
+<!--
+ ~ 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="24.0dp"
+ android:height="24.0dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:pathData="M20.000000,5.000000L4.000000,5.000000C2.900000,5.000000 2.000000,5.900000 2.000000,7.000000l0.000000,10.000000c0.000000,1.100000 0.900000,2.000000 2.000000,2.000000l16.000000,0.000000c1.100000,0.000000 2.000000,-0.900000 2.000000,-2.000000L22.000000,7.000000C22.000000,5.900000 21.100000,5.000000 20.000000,5.000000zM11.000000,8.000000l2.000000,0.000000l0.000000,2.000000l-2.000000,0.000000L11.000000,8.000000zM11.000000,11.000000l2.000000,0.000000l0.000000,2.000000l-2.000000,0.000000L11.000000,11.000000zM8.000000,8.000000l2.000000,0.000000l0.000000,2.000000L8.000000,10.000000L8.000000,8.000000zM8.000000,11.000000l2.000000,0.000000l0.000000,2.000000L8.000000,13.000000L8.000000,11.000000zM7.000000,13.000000L5.000000,13.000000l0.000000,-2.000000l2.000000,0.000000L7.000000,13.000000zM7.000000,10.000000L5.000000,10.000000L5.000000,8.000000l2.000000,0.000000L7.000000,10.000000zM16.000000,17.000000L8.000000,17.000000l0.000000,-2.000000l8.000000,0.000000L16.000000,17.000000zM16.000000,13.000000l-2.000000,0.000000l0.000000,-2.000000l2.000000,0.000000L16.000000,13.000000zM16.000000,10.000000l-2.000000,0.000000L14.000000,8.000000l2.000000,0.000000L16.000000,10.000000zM19.000000,13.000000l-2.000000,0.000000l0.000000,-2.000000l2.000000,0.000000L19.000000,13.000000zM19.000000,10.000000l-2.000000,0.000000L17.000000,8.000000l2.000000,0.000000L19.000000,10.000000z"
+ android:fillColor="@color/icon_color_ime_switcher"/>
+</vector>
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_ime_switcher_smartbar_dark.xml b/packages/SystemUI/res-hwkeys/drawable/ic_ime_switcher_smartbar_dark.xml
new file mode 100644
index 0000000..3610600
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_ime_switcher_smartbar_dark.xml
@@ -0,0 +1,25 @@
+<!--
+ ~ 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="24.0dp"
+ android:height="24.0dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:pathData="M20.000000,5.000000L4.000000,5.000000C2.900000,5.000000 2.000000,5.900000 2.000000,7.000000l0.000000,10.000000c0.000000,1.100000 0.900000,2.000000 2.000000,2.000000l16.000000,0.000000c1.100000,0.000000 2.000000,-0.900000 2.000000,-2.000000L22.000000,7.000000C22.000000,5.900000 21.100000,5.000000 20.000000,5.000000zM11.000000,8.000000l2.000000,0.000000l0.000000,2.000000l-2.000000,0.000000L11.000000,8.000000zM11.000000,11.000000l2.000000,0.000000l0.000000,2.000000l-2.000000,0.000000L11.000000,11.000000zM8.000000,8.000000l2.000000,0.000000l0.000000,2.000000L8.000000,10.000000L8.000000,8.000000zM8.000000,11.000000l2.000000,0.000000l0.000000,2.000000L8.000000,13.000000L8.000000,11.000000zM7.000000,13.000000L5.000000,13.000000l0.000000,-2.000000l2.000000,0.000000L7.000000,13.000000zM7.000000,10.000000L5.000000,10.000000L5.000000,8.000000l2.000000,0.000000L7.000000,10.000000zM16.000000,17.000000L8.000000,17.000000l0.000000,-2.000000l8.000000,0.000000L16.000000,17.000000zM16.000000,13.000000l-2.000000,0.000000l0.000000,-2.000000l2.000000,0.000000L16.000000,13.000000zM16.000000,10.000000l-2.000000,0.000000L14.000000,8.000000l2.000000,0.000000L16.000000,10.000000zM19.000000,13.000000l-2.000000,0.000000l0.000000,-2.000000l2.000000,0.000000L19.000000,13.000000zM19.000000,10.000000l-2.000000,0.000000L17.000000,8.000000l2.000000,0.000000L19.000000,10.000000z"
+ android:fillColor="@color/icon_color_dark"/>
+</vector>
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_skip_next.xml b/packages/SystemUI/res-hwkeys/drawable/ic_skip_next.xml
new file mode 100644
index 0000000..e4a57b2
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_skip_next.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Dirty Unicorns 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="24.0dp"
+ android:height="24.0dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+
+ <path
+ android:fillColor="#ffffff"
+ android:pathData="M6 18l8.5-6L6 6v12zM16 6v12h2V6h-2z" />
+</vector>
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_skip_previous.xml b/packages/SystemUI/res-hwkeys/drawable/ic_skip_previous.xml
new file mode 100644
index 0000000..7cdddde
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_skip_previous.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Dirty Unicorns 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="24.0dp"
+ android:height="24.0dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+
+ <path
+ android:fillColor="#ffffff"
+ android:pathData="M6 6h2v12H6zm3.5 6l8.5 6V6z" />
+</vector>
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_smartbar_screen_pinning_off.xml b/packages/SystemUI/res-hwkeys/drawable/ic_smartbar_screen_pinning_off.xml
new file mode 100644
index 0000000..112ce8b
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_smartbar_screen_pinning_off.xml
@@ -0,0 +1,8 @@
+<!-- drawable/pin_off.xml -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:width="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path android:fillColor="#fff" android:pathData="M2,5.27L3.28,4L20,20.72L18.73,22L12.8,16.07V22H11.2V16H6V14L8,12V11.27L2,5.27M16,12L18,14V16H17.82L8,6.18V4H7V2H17V4H16V12Z" />
+</vector>
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_back_hw.xml b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_back_hw.xml
new file mode 100644
index 0000000..97b8aeb
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_back_hw.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Dirty Unicorns 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="28.0dp"
+ android:height="28.0dp"
+ android:viewportWidth="96.0"
+ android:viewportHeight="96.0">
+
+ <path
+ android:fillColor="@color/icon_color_back"
+ android:pathData="M69,20c-0.8,0-1.5,0.2-2.2,0.5l0,0L25,42.8l0,0c-0.1,0.1-0.2,0.1-0.3,0.2c-1.6,1.1-2.7,2.9-2.7,5
+s1.1,3.9,2.7,5c0.1,0.1,0.2,0.1,0.3,0.2l0,0l19.5,10.4l21.8,11.7l0,0c0.2,0.1,0.5,0.3,0.8,0.4l0,0l0,0c0.6,0.2,1.2,0.4,1.9,0.4
+c2.8,0,5-2.2,5-5V25C74,22.2,71.8,20,69,20z" />
+</vector>
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_bt.xml b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_bt.xml
new file mode 100644
index 0000000..cf5e739
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_bt.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Dirty Unicorns 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="30.0dp"
+ android:height="30.0dp"
+ android:viewportWidth="96.0"
+ android:viewportHeight="96.0">
+
+ <group>
+ <path
+ android:fillColor="@color/icon_color_bluetooth"
+ android:pathData="M70.7,58.5L70.7,58.5L70.7,58.5c-0.1,0-0.1-0.1-0.2-0.1l-12.5-7l-1.1-0.6C55.8,50.3,55,49.3,55,48
+c0-1.1,0.7-2.1,1.6-2.6l1-0.5l0.4-0.2l12.5-7c0.1,0,0.1-0.1,0.2-0.1l0,0v0C71.5,36.9,72,36,72,35s-0.5-1.9-1.3-2.5v0l0,0
+c-0.2-0.2-0.5-0.3-0.7-0.4L46.1,20.6l0,0C45.5,20.2,44.8,20,44,20c-2.2,0-4,1.8-4,4v13.7L32,33c-1.9-1.1-4.4-0.5-5.5,1.5l-2,3.5
+c-1.1,1.9-0.5,4.4,1.5,5.5l7.9,4.6L26,52.6c-1.9,1.1-2.6,3.6-1.5,5.5l2,3.5c1.1,1.9,3.6,2.6,5.5,1.5l8-4.6V72c0,2.2,1.8,4,4,4
+c0.8,0,1.5-0.2,2.1-0.6l0,0L70,63.8c0.3-0.1,0.5-0.2,0.7-0.4h0C71.5,62.9,72,62,72,61S71.5,59.1,70.7,58.5z" />
+ </group>
+</vector>
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_clear_notifications.xml b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_clear_notifications.xml
new file mode 100644
index 0000000..58f4ab5
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_clear_notifications.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Dirty Unicorns 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="30.0dp"
+ android:height="30.0dp"
+ android:viewportWidth="96.0"
+ android:viewportHeight="96.0">
+
+ <path
+ android:fillColor="@color/icon_color_clear_notifications"
+ android:pathData="M78,32H38c-2.2,0-4-1.8-4-4v-4c0-2.2,1.8-4,4-4h40c2.2,0,4,1.8,4,4v4C82,30.2,80.2,32,78,32z" />
+ <path
+ android:fillColor="@color/icon_color_clear_notifications"
+ android:pathData="M68,54H28c-2.2,0-4-1.8-4-4v-4c0-2.2,1.8-4,4-4h40c2.2,0,4,1.8,4,4v4C72,52.2,70.2,54,68,54z" />
+ <path
+ android:fillColor="@color/icon_color_clear_notifications"
+ android:pathData="M58,76H18c-2.2,0-4-1.8-4-4v-4c0-2.2,1.8-4,4-4h40c2.2,0,4,1.8,4,4v4C62,74.2,60.2,76,58,76z" />
+</vector>
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_docked_hw.xml b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_docked_hw.xml
new file mode 100644
index 0000000..585c3ec
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_docked_hw.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Dirty Unicorns 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="30.0dp"
+ android:height="30.0dp"
+ android:viewportWidth="96.0"
+ android:viewportHeight="96.0">
+ <group>
+ <path
+ android:fillColor="#ffffff"
+ android:pathData="M74,20h-2H24h-2c-3.3,0-6,2.7-6,6v12c0,3.3,2.7,6,6,6h52c3.3,0,6-2.7,6-6V26C80,22.7,77.3,20,74,20z" />
+ <path
+ android:fillColor="#ffffff"
+ android:pathData="M74,52H22c-3.3,0-6,2.7-6,6v12c0,3.3,2.7,6,6,6h2h48h2c3.3,0,6-2.7,6-6V58C80,54.7,77.3,52,74,52z" />
+ </group>
+</vector>
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_expanded_desktop.xml b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_expanded_desktop.xml
new file mode 100644
index 0000000..7bb1b77
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_expanded_desktop.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Dirty Unicorns 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="30.0dp"
+ android:height="30.0dp"
+ android:viewportWidth="96.0"
+ android:viewportHeight="96.0">
+
+
+ <group>
+ <path
+ android:fillColor="@color/icon_color_expanded_desktop"
+ android:pathData="M22,40h52c2.2,0,4-1.8,4-4c0-0.7-0.2-1.4-0.5-1.9l0,0l-0.1-0.1c-0.1-0.1-0.2-0.3-0.3-0.4l-7.9-11.3
+c0-0.1-0.1-0.1-0.1-0.1L69,22l0,0C68,20.8,66.6,20,65,20H31c-1.6,0-3.1,0.8-4,2l0,0l-0.1,0.1c0,0,0,0.1-0.1,0.1l-8,11.4
+c-0.1,0.1-0.1,0.2-0.2,0.3l-0.1,0.1l0,0c-0.4,0.6-0.6,1.3-0.6,2C18,38.2,19.8,40,22,40z" />
+ <path
+ android:fillColor="@color/icon_color_expanded_desktop"
+ android:pathData="M74,56H22c-2.2,0-4,1.8-4,4c0,0.8,0.2,1.4,0.6,2l0,0l0.1,0.1c0.1,0.1,0.1,0.2,0.2,0.3l8,11.4
+c0,0,0,0.1,0.1,0.1L27,74l0,0c0.9,1.2,2.4,2,4,2h34c1.6,0,3-0.8,3.9-1.9l0,0l0.1-0.2c0,0,0.1-0.1,0.1-0.1l7.9-11.3
+c0.1-0.1,0.2-0.3,0.3-0.4l0.1-0.1l0,0c0.3-0.6,0.5-1.2,0.5-1.9C78,57.8,76.2,56,74,56z" />
+ </group>
+</vector>
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_google_assistant.xml b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_google_assistant.xml
new file mode 100644
index 0000000..499d77a
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_google_assistant.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Dirty Unicorns 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="30.0dp"
+ android:height="30.0dp"
+ android:viewportWidth="96.0"
+ android:viewportHeight="96.0">
+ <path
+ android:fillColor="@color/icon_color_google_assistant"
+ android:pathData="M72,42h-4h-4H48c-2.2,0-4,1.8-4,4v4c0,2.2,1.8,4,4,4h14.8c-2.4,5.9-8.1,10-14.8,10c-8.8,0-16-7.2-16-16
+s7.2-16,16-16c2.9,0,5.6,0.8,7.9,2.1l0,0c0.4,0.3,0.8,0.5,1.3,0.5c0.6,0,1.1-0.2,1.4-0.6l0,0l5.9-5.6c0,0,0,0,0.1-0.1l0,0l0,0
+c0.3-0.4,0.5-0.8,0.5-1.4c0-0.6-0.3-1.1-0.7-1.5l0,0c0,0-0.1,0-0.1-0.1c-0.1-0.1-0.2-0.1-0.2-0.2C59.7,21.9,54.1,20,48,20
+c-15.5,0-28,12.5-28,28c0,15.5,12.5,28,28,28s28-12.5,28-28v-2C76,43.8,74.2,42,72,42z" />
+</vector>
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_home_hw.xml b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_home_hw.xml
new file mode 100644
index 0000000..890b7d2
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_home_hw.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Dirty Unicorns 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="28.0dp"
+ android:height="28.0dp"
+ android:viewportWidth="96.0"
+ android:viewportHeight="96.0">
+ <path
+ android:fillColor="@color/icon_color_home"
+ android:pathData="M 48 20 C 63.4639729953 20 76 32.5360270047 76 48 C 76 63.4639729953 63.4639729953 76 48 76 C 32.5360270047 76 20 63.4639729953 20 48 C 20 32.5360270047 32.5360270047 20 48 20 Z" />
+ <path
+ android:fillColor="@color/icon_color_home"
+ android:pathData="M48,10c-21,0-38,17-38,38s17,38,38,38s38-17,38-38S69,10,48,10z
+M48,82c-18.8,0-34-15.2-34-34
+c0-18.8,15.2-34,34-34s34,15.2,34,34C82,66.8,66.8,82,48,82z" />
+</vector>
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_hotspot.xml b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_hotspot.xml
new file mode 100644
index 0000000..b9cf4cd
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_hotspot.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Dirty Unicorns 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="30.0dp"
+ android:height="30.0dp"
+ android:viewportWidth="96.0"
+ android:viewportHeight="96.0">
+ <path
+ android:fillColor="@color/icon_color_hotspot"
+ android:pathData="M74,22.3c0-2.4-1.9-4.3-4.3-4.3H26.3c-2.4,0-4.3,1.9-4.3,4.3c0,0.9,0.3,1.8,0.8,2.5l0,0L42,59.5V66v4v4
+c0,2.2,1.8,4,4,4h4c2.2,0,4-1.8,4-4v-4v-4v-6.5l19.3-34.9l0,0C73.8,23.9,74,23.2,74,22.3z
+M62.8,27.8l-3,5.9c0,0.1-0.1,0.2-0.1,0.3
+l0,0.1l0,0c-0.4,0.5-1,0.9-1.7,0.9H38c-0.7,0-1.3-0.4-1.7-0.9l0,0l0,0c-0.1-0.1-0.1-0.2-0.2-0.3l-3-5.9C33.1,27.5,33,27.3,33,27
+c0-1.1,0.9-2,2-2h26c1.1,0,2,0.9,2,2C63,27.3,62.9,27.6,62.8,27.8L62.8,27.8z" />
+</vector>
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_ime_down.xml b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_ime_down.xml
new file mode 100644
index 0000000..393e956
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_ime_down.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Dirty Unicorns 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="30.0dp"
+ android:height="30.0dp"
+ android:viewportWidth="96.0"
+ android:viewportHeight="96.0">
+ <path
+ android:fillColor="@color/icon_color_ime_down"
+ android:pathData="M51.9,42.1L51.9,42.1c-3.6,3.7-7,0.8-7.6,0.1L33.1,30.9c-1.2-1.2-3.1-1.2-4.2,0l-6,6c-1.2,1.2-1.2,3.1,0,4.2
+l22.3,23.7c1.6,1.6,4.1,1.6,5.7,0l22.3-23.7c1.2-1.2,1.2-3.1,0-4.2l-6-6c-1.2-1.2-3.1-1.2-4.2,0L51.9,42.1z" />
+</vector>
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_ime_left.xml b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_ime_left.xml
new file mode 100644
index 0000000..f539f53
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_ime_left.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Dirty Unicorns 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="24.0dp"
+ android:height="24.0dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="@color/icon_color_ime_left"
+ android:pathData="M15.41,16.09l-4.58,-4.59 4.58,-4.59L14.0,5.5l-6.0,6.0 6.0,6.0z" />
+</vector>
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_ime_right.xml b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_ime_right.xml
new file mode 100644
index 0000000..3752a9c
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_ime_right.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Dirty Unicorns 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="24.0dp"
+ android:height="24.0dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="@color/icon_color_ime_right"
+ android:pathData="M8.59,16.34l4.58,-4.59 -4.58,-4.59L10.0,5.75l6.0,6.0 -6.0,6.0z" />
+</vector>
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_ime_up.xml b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_ime_up.xml
new file mode 100644
index 0000000..59c557b
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_ime_up.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Dirty Unicorns 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="30.0dp"
+ android:height="30.0dp"
+ android:viewportWidth="96.0"
+ android:viewportHeight="96.0">
+ <path
+ android:fillColor="@color/icon_color_ime_up"
+ android:pathData="M51.9,53.9L51.9,53.9c-3.6-3.7-7-0.8-7.6-0.1L33.1,65.1c-1.2,1.2-3.1,1.2-4.2,0l-6-6c-1.2-1.2-1.2-3.1,0-4.2
+l22.3-23.7c1.6-1.6,4.1-1.6,5.7,0l22.3,23.7c1.2,1.2,1.2,3.1,0,4.2l-6,6c-1.2,1.2-3.1,1.2-4.2,0L51.9,53.9z" />
+</vector>
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_in_app_search.xml b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_in_app_search.xml
new file mode 100644
index 0000000..cf8b5840
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_in_app_search.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Dirty Unicorns 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="30.0dp"
+ android:height="30.0dp"
+ android:viewportWidth="96.0"
+ android:viewportHeight="96.0">
+ <path
+ android:fillColor="@color/icon_color_in_app_search"
+ android:pathData="M78.8,65.2L65.9,52.2C67.3,49.1,68,45.6,68,42c0-14.4-11.6-26-26-26S16,27.6,16,42c0,14.4,11.6,26,26,26
+c3.6,0,7.1-0.7,10.2-2.1l12.9,12.9c1.6,1.6,4.1,1.6,5.7,0l8-8C80.4,69.3,80.4,66.7,78.8,65.2z
+M42,56c-7.7,0-14-6.3-14-14 s6.3-14,14-14s14,6.3,14,14S49.7,56,42,56z" />
+</vector>
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_killtask.xml b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_killtask.xml
new file mode 100644
index 0000000..1648b5b
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_killtask.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Dirty Unicorns 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="30.0dp"
+ android:height="30.0dp"
+ android:viewportWidth="96.0"
+ android:viewportHeight="96.0">
+ <path
+ android:fillColor="@color/icon_color_force_close_app"
+ android:pathData="M75.3,62.1L75.3,62.1c-0.2-0.2-0.2-0.3-0.3-0.3L61.2,48l13.9-13.9c0.6-0.6,0.9-1.4,0.9-2.3
+c0-0.9-0.4-1.8-1.1-2.4l-8.4-8.4c-0.1-0.1-0.1-0.1-0.2-0.2l-0.1-0.1h0c-0.6-0.5-1.3-0.8-2.1-0.8s-1.5,0.3-2.1,0.8h0L62,20.8
+c-0.1,0.1-0.2,0.2-0.2,0.2L48,34.8L34.2,21.1c-0.1-0.1-0.2-0.2-0.2-0.2l-0.1-0.1h0c-0.6-0.5-1.3-0.8-2.1-0.8s-1.5,0.3-2.1,0.8h0
+l-0.1,0.1c-0.1,0.1-0.1,0.1-0.2,0.2l-8.4,8.4c-0.6,0.6-1.1,1.4-1.1,2.4c0,0.9,0.4,1.7,0.9,2.3L34.8,48L21.1,61.8
+c-0.1,0.1-0.2,0.2-0.2,0.2l-0.1,0.1v0c-0.5,0.6-0.7,1.3-0.7,2s0.3,1.5,0.7,2v0l0.1,0.1c0,0.1,0.1,0.1,0.1,0.1l8.5,8.5
+c0,0.1,0.1,0.1,0.1,0.1l0.1,0.1h0c0.6,0.5,1.3,0.8,2.1,0.8c0.8,0,1.5-0.3,2.1-0.8h0l0.1-0.1c0,0,0,0,0,0L48,61.2l13.9,13.9
+c0,0,0,0,0,0l0.1,0.1h0c0.6,0.5,1.3,0.8,2.1,0.8c0.8,0,1.5-0.3,2.1-0.8h0l0.1-0.1c0.1,0,0.1-0.1,0.1-0.1l8.5-8.5
+c0.1,0,0.1-0.1,0.1-0.1l0.1-0.1v0c0.5-0.6,0.7-1.3,0.7-2S75.7,62.7,75.3,62.1L75.3,62.1z" />
+</vector>
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_lastapp.xml b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_lastapp.xml
new file mode 100644
index 0000000..76ef362
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_lastapp.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Dirty Unicorns 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="30.0dp"
+ android:height="30.0dp"
+ android:viewportWidth="96.0"
+ android:viewportHeight="96.0">
+ <path
+ android:fillColor="@color/icon_color_last_app"
+ android:pathData="M78,45c0-1.7-1.3-3-3-3c-1.7,0-3,1.3-3,3c0,0-3.5,17-14,17s-10-8.3-10-10h8c2.2,0,4-1.8,4-4
+c0-0.7-0.2-1.4-0.5-2l0,0l-0.1-0.1c-0.1-0.2-0.2-0.3-0.4-0.5L41.6,21.5c-0.1-0.2-0.3-0.4-0.4-0.6l0,0h0C40.6,20.4,39.9,20,39,20
+s-1.6,0.4-2.2,0.9h0l0,0c-0.2,0.2-0.3,0.4-0.4,0.6L19.2,45.2c-0.3,0.3-0.5,0.6-0.7,0.9l-0.1,0.1l0,0C18.2,46.7,18,47.3,18,48
+c0,2.2,1.8,4,4,4h6c0,0.1,0,0.1,0,0.2c0,0,0,0.1,0,0.2C28.1,55.2,29.5,76,52,76c0,0,0,0,0,0C78.5,76,78,45,78,45z" />
+</vector>
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_menu_hw.xml b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_menu_hw.xml
new file mode 100644
index 0000000..47a2e1b
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_menu_hw.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Dirty Unicorns 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="30.0dp"
+ android:height="30.0dp"
+ android:viewportWidth="512.000000"
+ android:viewportHeight="512.000000">
+
+ <group
+ android:translateY="512.000000"
+ android:scaleX="0.100000"
+ android:scaleY="-0.100000">
+ <path
+ android:fillColor="@color/icon_color_menu"
+ android:strokeWidth="1"
+ android:pathData="M1360 3901 c-147 -45 -231 -209 -186 -363 18 -65 79 -138 140 -171 l41 -22 1195 -3
+c845 -2 1207 0 1235 8 62 17 126 70 160 131 27 49 30 63 30 144 0 74 -4 98 -22 131
+-28 53 -74 99 -127 127 l-41 22 -1200 2 c-660 1 -1211 -2 -1225 -6z" />
+ <path
+ android:fillColor="@color/icon_color_menu"
+ android:strokeWidth="1"
+ android:pathData="M1324 2821 c-54 -25 -111 -83 -138 -140 -29 -65 -29 -189 2 -247 33 -64 70 -102
+126 -132 l51 -27 1184 -3 c1353 -3 1256 -9 1346 81 143 144 102 385 -80 468 -38 18
+-100 19 -1245 19 -1154 0 -1207 -1 -1246 -19z" />
+ <path
+ android:fillColor="@color/icon_color_menu"
+ android:strokeWidth="1"
+ android:pathData="M1353 1757 c-60 -22 -117 -72 -148 -128 -27 -49 -30 -63 -30 -144 0 -74 4 -98 22
+-131 28 -53 74 -99 127 -127 l41 -22 1215 0 1215 0 40 22 c202 109 203 408 1 516
+l-41 22 -1205 2 c-906 1 -1213 -1 -1237 -10z" />
+ </group>
+</vector>
+
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_no_action.xml b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_no_action.xml
new file mode 100644
index 0000000..2e30033
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_no_action.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Dirty Unicorns 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="30.0dp"
+ android:height="30.0dp"
+ android:viewportWidth="96.0"
+ android:viewportHeight="96.0">
+ <path
+ android:fillColor="@color/icon_color_no_action"
+ android:pathData="M48,20c-15.5,0-28,12.5-28,28c0,15.5,12.5,28,28,28s28-12.5,28-28C76,32.5,63.5,20,48,20z
+M44,30
+c0-1.1,0.9-2,2-2h4c1.1,0,2,0.9,2,2v20c0,1.1-0.9,2-2,2h-4c-1.1,0-2-0.9-2-2V30z
+M48,68c-2.8,0-5-2.2-5-5s2.2-5,5-5s5,2.2,5,5 S50.8,68,48,68z" />
+</vector>
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_notification_panel.xml b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_notification_panel.xml
new file mode 100644
index 0000000..b0dff62
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_notification_panel.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Dirty Unicorns 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="30.0dp"
+ android:height="30.0dp"
+ android:viewportWidth="96.0"
+ android:viewportHeight="96.0">
+ <group>
+ <path
+ android:fillColor="@color/icon_color_notification_panel"
+ android:pathData="M48,80c3.3,0,6-2.7,6-6H42C42,77.3,44.7,80,48,80z" />
+ <path
+ android:fillColor="@color/icon_color_notification_panel"
+ android:pathData="M73.4,66.6L68,61.6V42h-0.1c0.1-0.7,0.1-1.3,0.1-2c0-9-5.9-16.6-14.1-19.1c-0.5-2.8-3-4.9-5.9-4.9
+s-5.4,2.1-5.9,4.9C33.9,23.4,28,31,28,40c0,0.7,0,1.3,0.1,2H28v19.6l-5.4,4.9c-0.8,0.8-0.8,2,0,2.8C23,69.8,23.5,70,24,70h4h40h4
+c0.5,0,1-0.2,1.4-0.6C74.2,68.6,74.2,67.4,73.4,66.6z" />
+ </group>
+</vector>
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_one_handed_mode_left.xml b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_one_handed_mode_left.xml
new file mode 100644
index 0000000..3faf6ce
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_one_handed_mode_left.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Dirty Unicorns 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="30.0dp"
+ android:height="30.0dp"
+ android:viewportWidth="96.000000"
+ android:viewportHeight="96.000000">
+
+ <group
+ android:translateY="96.000000"
+ android:scaleX="0.100000"
+ android:scaleY="-0.100000">
+ <path
+ android:fillColor="@color/icon_color_one_handed_mode"
+ android:strokeWidth="1"
+ android:pathData="M493 618 l-143 -142 -54 53 c-86 85 -90 80 -94 -125 -2 -156 -1 -172 16 -187 17
+-15 41 -17 188 -15 204 4 208 8 120 97 l-56 56 145 145 c80 80 145 151 145 159 0
+22 -81 101 -104 101 -12 0 -76 -56 -163 -142z" />
+ </group>
+</vector>
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_one_handed_mode_right.xml b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_one_handed_mode_right.xml
new file mode 100644
index 0000000..7f34fee
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_one_handed_mode_right.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Dirty Unicorns 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="30.0dp"
+ android:height="30.0dp"
+ android:viewportWidth="96.000000"
+ android:viewportHeight="96.000000">
+
+ <group
+ android:translateY="96.000000"
+ android:scaleX="0.100000"
+ android:scaleY="-0.100000">
+ <path
+ android:fillColor="@color/icon_color_one_handed_mode"
+ android:strokeWidth="1"
+ android:pathData="M242 717 c-23 -23 -42 -49 -42 -58 0 -8 65 -79 145 -159 l145 -145 -56 -56 c-88
+-89 -84 -93 120 -97 147 -2 171 0 188 15 17 15 18 31 16 187 -4 205 -8 210 -94 125
+l-54 -53 -143 142 c-87 86 -151 142 -163 142 -11 0 -39 -19 -62 -43z" />
+ </group>
+</vector>
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_power_menu.xml b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_power_menu.xml
new file mode 100644
index 0000000..669cf6e
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_power_menu.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Dirty Unicorns 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="30.0dp"
+ android:height="30.0dp"
+ android:viewportWidth="96.0"
+ android:viewportHeight="96.0">
+ <path
+ android:fillColor="@color/icon_color_power_menu"
+ android:pathData="M76.8,47.2c0-12-7.3-22.2-17.7-26.6c0,0-1.5-0.6-3.3-0.6c-1.8,0-3.3,1.5-3.3,3.3V25v22.2c0,2.4-2,4.4-4.4,4.4
+s-4.4-2-4.4-4.4V25v-1.7c0-1.8-1.5-3.3-3.3-3.3c-1.8,0-3.3,0.6-3.3,0.6c-10.4,4.3-17.7,14.6-17.7,26.6c0,3.1,0.5,6.1,1.4,8.9h0
+c0,0.2,0.1,0.3,0.2,0.5c0.2,0.5,0.4,1,0.6,1.5c0.1,0.3,0.2,0.5,0.3,0.8c0.2,0.4,0.4,0.8,0.6,1.2c0.1,0.3,0.3,0.6,0.5,0.9
+c0.2,0.3,0.4,0.7,0.6,1c0.2,0.3,0.4,0.7,0.6,1c0.2,0.3,0.3,0.5,0.5,0.8c0.2,0.4,0.5,0.7,0.8,1c0.2,0.2,0.3,0.4,0.5,0.6
+c0.3,0.4,0.6,0.7,0.9,1.1c0.1,0.2,0.3,0.3,0.4,0.4c0.4,0.4,0.7,0.8,1.1,1.1c0.1,0.1,0.2,0.2,0.3,0.3c0.4,0.4,0.9,0.8,1.3,1.2
+c0.1,0,0.1,0.1,0.2,0.1c5,4,11.3,6.5,18.2,6.5s13.2-2.4,18.2-6.5c0.1,0,0.1-0.1,0.2-0.1c0.5-0.4,0.9-0.8,1.3-1.2
+c0.1-0.1,0.2-0.2,0.3-0.3c0.4-0.4,0.8-0.7,1.1-1.1c0.1-0.1,0.3-0.3,0.4-0.4c0.3-0.4,0.6-0.7,0.9-1.1c0.2-0.2,0.3-0.4,0.5-0.6
+c0.3-0.3,0.5-0.7,0.8-1c0.2-0.3,0.4-0.5,0.5-0.8c0.2-0.3,0.4-0.6,0.6-1c0.2-0.3,0.4-0.7,0.6-1c0.2-0.3,0.3-0.6,0.5-0.9
+c0.2-0.4,0.4-0.8,0.6-1.2c0.1-0.3,0.2-0.5,0.3-0.8c0.2-0.5,0.4-1,0.6-1.5c0.1-0.2,0.1-0.3,0.2-0.5h0C76.3,53.2,76.8,50.3,76.8,47.2z" />
+</vector>
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_recent_hw.xml b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_recent_hw.xml
new file mode 100644
index 0000000..78338e3
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_recent_hw.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Dirty Unicorns 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="28.0dp"
+ android:height="28.0dp"
+ android:viewportWidth="96.0"
+ android:viewportHeight="96.0">
+
+ <path
+ android:fillColor="@color/icon_color_overview"
+ android:pathData="M70,76H26c-3.3,0-6-2.7-6-6V26c0-3.3,2.7-6,6-6h44c3.3,0,6,2.7,6,6v44C76,73.3,73.3,76,70,76z" />
+</vector>
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_record_screen.xml b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_record_screen.xml
new file mode 100644
index 0000000..a1e8131
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_record_screen.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Dirty Unicorns 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="30.0dp"
+ android:height="30.0dp"
+ android:viewportWidth="96.0"
+ android:viewportHeight="96.0">
+ <group>
+ <path
+ android:fillColor="@color/icon_color_screenrecord"
+ android:pathData="M79,30c-0.5,0-1,0.2-1.5,0.4l0,0l-11.6,5.8c-0.1,0-0.2,0.1-0.3,0.2l-0.1,0.1l0,0C64.6,37,64,37.9,64,39v18
+c0,1,0.5,1.9,1.3,2.5l0,0l0,0c0.2,0.2,0.5,0.3,0.7,0.4l11.5,5.8l0,0C78,65.8,78.5,66,79,66c1.7,0,3-1.3,3-3V33
+C82,31.3,80.7,30,79,30z" />
+ <path
+ android:fillColor="@color/icon_color_screenrecord"
+ android:pathData="M52,26H22h-2c-3.3,0-6,2.7-6,6v32c0,3.3,2.7,6,6,6h32c3.3,0,6-2.7,6-6v-2V32C58,28.7,55.3,26,52,26z" />
+ </group>
+</vector>
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_region_screenshot.xml b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_region_screenshot.xml
new file mode 100644
index 0000000..2be6fd8
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_region_screenshot.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Dirty Unicorns 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="30.0dp"
+ android:height="30.0dp"
+ android:viewportWidth="96.0"
+ android:viewportHeight="96.0">
+ <path
+ android:fillColor="@color/icon_color_region_screenshot"
+ android:pathData="M82,36H64c-2.2,0-4-1.8-4-4V14c0-2.2,1.8-4,4-4h18c2.2,0,4,1.8,4,4v18C86,34.2,84.2,36,82,36z" />
+ <path
+ android:fillColor="@color/icon_color_region_screenshot"
+ android:pathData="M72,42h-2h-2h-8c-3.3,0-6-2.7-6-6v-8v-2v-2c0-2.2-1.8-4-4-4h-2H27c-3.8,0-7,3.2-7,7v42c0,3.8,3.2,7,7,7h42
+c3.8,0,7-3.2,7-7V48v-2C76,43.8,74.2,42,72,42z
+M65,66h-9h-6h-2H31c-1.7,0-3-1.3-3-3c0-0.6,0.2-1.1,0.5-1.6l0,0l0,0
+c0-0.1,0.1-0.1,0.1-0.2l9.9-13.8C39,46.6,39.9,46,41,46c1.1,0,2.1,0.6,2.6,1.5L52,60l4.4-6.6h0c0.5-0.9,1.5-1.5,2.6-1.5
+s2.1,0.6,2.6,1.5h0l5.7,7.6c0.1,0.1,0.1,0.2,0.2,0.3l0,0l0,0c0.3,0.5,0.5,1,0.5,1.6C68,64.7,66.7,66,65,66z" />
+</vector>
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_screen_off.xml b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_screen_off.xml
new file mode 100644
index 0000000..b113019
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_screen_off.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Dirty Unicorns 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="30.0dp"
+ android:height="30.0dp"
+ android:viewportWidth="96.0"
+ android:viewportHeight="96.0">
+
+ <group>
+ <path
+ android:fillColor="@color/icon_color_screen_off"
+ android:pathData="M44,14H16c-1.1,0-2,0.9-2,2v6c0,1.1,0.9,2,2,2h17.2L14.7,42.5h0C14.3,42.9,14,43.4,14,44v6c0,1.1,0.9,2,2,2
+h28c1.1,0,2-0.9,2-2v-6c0-1.1-0.9-2-2-2H26.8l18.5-18.5c0.1-0.1,0.2-0.2,0.3-0.3l0,0c0.3-0.3,0.5-0.8,0.5-1.3v-6
+C46,14.9,45.1,14,44,14z" />
+ <path
+ android:fillColor="@color/icon_color_screen_off"
+ android:pathData="M44,60H28c-1.1,0-2,0.9-2,2v2c0,1.1,0.9,2,2,2h9.2L26.6,76.6l0,0C26.2,76.9,26,77.4,26,78v2
+c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2v-2c0-1.1-0.9-2-2-2h-9.2l10.5-10.5c0.1-0.1,0.2-0.2,0.3-0.3l0,0h0c0.3-0.3,0.5-0.8,0.5-1.3v-2
+C46,60.9,45.1,60,44,60z" />
+ <path
+ android:fillColor="@color/icon_color_screen_off"
+ android:pathData="M81.6,41.2L81.6,41.2c0.3-0.3,0.4-0.8,0.4-1.2v-4c0-1.1-0.9-2-2-2H56c-1.1,0-2,0.9-2,2v4c0,1.1,0.9,2,2,2
+h13.2L54.7,56.5C54.3,56.8,54,57.4,54,58v4c0,1.1,0.9,2,2,2h24c1.1,0,2-0.9,2-2v-4c0-1.1-0.9-2-2-2H66.8l14.4-14.4
+C81.3,41.5,81.5,41.3,81.6,41.2z" />
+ </group>
+</vector>
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_screenshot.xml b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_screenshot.xml
new file mode 100644
index 0000000..109c007
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_screenshot.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Dirty Unicorns 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="30.0dp"
+ android:height="30.0dp"
+ android:viewportWidth="96.0"
+ android:viewportHeight="96.0">
+ <path
+ android:fillColor="@color/icon_color_screenshot"
+ android:pathData="M69,20H27c-3.8,0-7,3.2-7,7v42c0,3.8,3.2,7,7,7h42c3.8,0,7-3.2,7-7V27C76,23.2,72.8,20,69,20z
+M65,66h-9h-6
+h-2H31c-1.7,0-3-1.3-3-3c0-0.6,0.2-1.1,0.5-1.6l0,0l0,0c0-0.1,0.1-0.1,0.1-0.2l9.9-13.8C39,46.6,39.9,46,41,46
+c1.1,0,2.1,0.6,2.6,1.5L52,60l4.4-6.6h0c0.5-0.9,1.5-1.5,2.6-1.5s2.1,0.6,2.6,1.5h0l5.7,7.6c0.1,0.1,0.1,0.2,0.2,0.3l0,0l0,0
+c0.3,0.5,0.5,1,0.5,1.6C68,64.7,66.7,66,65,66z" />
+</vector>
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_settings_panel.xml b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_settings_panel.xml
new file mode 100644
index 0000000..8b5c76f
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_settings_panel.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Dirty Unicorns 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="30.0dp"
+ android:height="30.0dp"
+ android:viewportWidth="96.0"
+ android:viewportHeight="96.0">
+ <path
+ android:fillColor="@color/icon_color_settings_panel"
+ android:pathData="M75.6,55.3L68,50.9h0c-4.9-2.8,0-5.7,0-5.7l7.6-4.4c1.2-0.7,1.6-2.2,0.9-3.4l-5-8.7c-0.7-1.2-2.2-1.6-3.4-0.9
+l-7.9,4.6c-0.4,0.2-4.6,1.9-4.6-2.6h0v-9.3c0-1.4-1.1-2.5-2.5-2.5H43c-1.4,0-2.5,1.1-2.5,2.5v9.3c0,4.6-4.7,2.6-4.7,2.6l-7.9-4.6
+c-1.2-0.7-2.7-0.3-3.4,0.9l-5,8.7c-0.7,1.2-0.3,2.7,0.9,3.4l7.6,4.4h0c0,0,4.9,2.9,0,5.7h0l-7.6,4.4c-1.2,0.7-1.6,2.2-0.9,3.4l5,8.7
+c0.7,1.2,2.2,1.6,3.4,0.9l8.1-4.7c0.9-0.3,4.4-1.4,4.4,2.6h0v9.3c0,1.4,1.1,2.5,2.5,2.5h10c1.4,0,2.5-1.1,2.5-2.5v-9.3h0
+c0-4,3.5-3,4.4-2.6l8.1,4.7c1.2,0.7,2.7,0.3,3.4-0.9l5-8.7C77.2,57.5,76.8,55.9,75.6,55.3z
+M48,54.4c-3.6,0-6.4-2.9-6.4-6.4
+s2.9-6.4,6.4-6.4s6.4,2.9,6.4,6.4S51.6,54.4,48,54.4z" />
+</vector>
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_torch.xml b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_torch.xml
new file mode 100644
index 0000000..2724e5e
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_torch.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Dirty Unicorns 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="30.0dp"
+ android:height="30.0dp"
+ android:viewportWidth="96.0"
+ android:viewportHeight="96.0">
+
+ <path
+ android:fillColor="@color/icon_color_flashlight"
+ android:pathData="M65,47.9c0.1-0.1,0.1-0.2,0.2-0.3l0.1-0.1l0,0c0.5-0.8,0.7-1.6,0.7-2.6c0-2.8-2.2-5-5-5h-9l10-14l0,0
+c0.6-0.8,1-1.9,1-3c0-2.8-2.2-5-5-5H39c-2.4,0-4.5,1.7-4.9,4.1l0,0l-4,23.8c0,0.1,0,0.2-0.1,0.4L30,46.6l0,0c0,0.1,0,0.3,0,0.4
+c0,2.8,2.2,5,5,5h13l-9.5,20.1c-0.1,0.2-0.2,0.3-0.2,0.5l0,0.1l0,0C38.1,73.1,38,73.5,38,74c0,2.2,1.8,4,4,4c1.3,0,2.5-0.7,3.2-1.7
+l0,0l0-0.1c0,0,0-0.1,0.1-0.1L65,47.9z" />
+</vector>
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_volume_panel.xml b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_volume_panel.xml
new file mode 100644
index 0000000..5433b0d
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_volume_panel.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Dirty Unicorns 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="30.0dp"
+ android:height="30.0dp"
+ android:viewportWidth="96.0"
+ android:viewportHeight="96.0">
+ <group>
+ <path
+ android:fillColor="@color/icon_color_volume_panel"
+ android:pathData="M54,22c-0.5,0-1,0.1-1.5,0.3l0,0l0,0c-0.3,0.1-0.5,0.3-0.8,0.4L34.8,32H16c-3.3,0-6,2.7-6,6v2v16v2
+c0,3.3,2.7,6,6,6h18.8l16.9,9.3c0.6,0.4,1.4,0.7,2.3,0.7c2.2,0,4-1.8,4-4V26C58,23.8,56.2,22,54,22z" />
+ <path
+ android:fillColor="@color/icon_color_volume_panel"
+ android:pathData="M86,32c0-2.2-1.8-4-4-4h-8c-2.2,0-4,1.8-4,4v32c0,2.2,1.8,4,4,4c1.8,0,3.3-1.2,3.8-2.9l0,0l0.1-0.3l0,0l0,0
+c0,0,0,0,0,0l8-31.9l0,0C86,32.6,86,32.3,86,32z" />
+ </group>
+</vector>
diff --git a/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_wifi.xml b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_wifi.xml
new file mode 100644
index 0000000..85f0f3a
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/drawable/ic_sysbar_wifi.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Dirty Unicorns 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="30.0dp"
+ android:height="30.0dp"
+ android:viewportWidth="96.0"
+ android:viewportHeight="96.0">
+
+ <path
+ android:fillColor="@color/icon_color_wifi"
+ android:pathData="M78.2,25.4c0-3-2.4-5.4-5.4-5.4H23.2c-3,0-5.4,2.4-5.4,5.4c0,0.9,0.2,1.6,0.6,2.4l0,0l24,45l0,0
+c0.1,0.1,0.1,0.2,0.2,0.3c1.2,1.8,3.1,2.9,5.4,2.9s4.3-1.2,5.4-2.9c0.1-0.1,0.1-0.2,0.2-0.4l0,0l11.2-21l12.6-23.5l0,0
+c0.2-0.3,0.3-0.5,0.4-0.8l0,0l0,0C78,26.8,78.2,26.1,78.2,25.4z
+M65.9,30.6L65.9,30.6c-0.1,0.2-0.2,0.4-0.3,0.5l-2.8,5.6
+c0,0.1,0,0.1-0.1,0.1l0,0l0,0c-0.3,0.6-1,1.1-1.8,1.1H35c-0.7,0-1.3-0.4-1.7-1l0,0l0-0.1c0-0.1-0.1-0.2-0.1-0.3l-2.8-5.6
+c-0.1-0.2-0.2-0.3-0.3-0.5l0,0l0,0C30,30.4,30,30.2,30,30c0-1.1,0.9-2,2-2h32c1.1,0,2,0.9,2,2C66,30.2,66,30.4,65.9,30.6L65.9,30.6z" />
+</vector>
diff --git a/packages/SystemUI/res-hwkeys/values-af-rZA/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-af-rZA/custom_strings.xml
new file mode 100644
index 0000000..e88bc8e
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-af-rZA/custom_strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_screenshot">Skermfoto</string>
+ <string name="label_action_expanded_desktop">Uitgebreide werkskerm</string>
+ <string name="label_action_flashlight">Flitslig</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-af/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-af/custom_strings.xml
new file mode 100644
index 0000000..e88bc8e
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-af/custom_strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_screenshot">Skermfoto</string>
+ <string name="label_action_expanded_desktop">Uitgebreide werkskerm</string>
+ <string name="label_action_flashlight">Flitslig</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-am-rET/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-am-rET/custom_strings.xml
new file mode 100644
index 0000000..f64c1b3
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-am-rET/custom_strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-am/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-am/custom_strings.xml
new file mode 100644
index 0000000..f64c1b3
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-am/custom_strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-ar-rSA/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-ar-rSA/custom_strings.xml
new file mode 100644
index 0000000..1255940
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-ar-rSA/custom_strings.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">لا إجراء</string>
+ <string name="label_action_settings_panel">لوحة الإعدادات</string>
+ <string name="label_action_notification_panel">لوحة التنبيهات</string>
+ <string name="label_action_screenshot">لقطة الشاشة</string>
+ <string name="label_action_region_screenshot">لقطة الشاشة الجزئية</string>
+ <string name="label_action_screenrecord">تسجيل الشاشة</string>
+ <string name="label_action_expanded_desktop">سطح المكتب الموسّع</string>
+ <string name="label_action_screen_off">أغلق الشاشة</string>
+ <string name="label_action_force_close_app">أغلق التطبيق بالقوة</string>
+ <string name="label_action_search_assistant">مساعد البحث</string>
+ <string name="label_action_google_now_on_tap">Google Now بنقرة واحدة</string>
+ <string name="label_action_voice_search">البحث الصوتي</string>
+ <string name="label_action_in_app_search">البحث داخل التطبيق</string>
+ <string name="label_action_flashlight">الكشاف</string>
+ <string name="label_action_bluetooth">البلوتوث</string>
+ <string name="label_action_wifi">الشبكة اللاسلكية</string>
+ <string name="label_action_hotspot">نقطة إتصال</string>
+ <string name="label_action_last_app">التطبيق السابق</string>
+ <string name="label_action_overview">التطبيقات الأخيرة</string>
+ <string name="label_action_power_menu">قائمة الإغلاق</string>
+ <string name="label_action_menu">قائمة</string>
+ <string name="label_action_back">رجوع</string>
+ <string name="label_action_home">الرئيسية</string>
+ <string name="label_action_ime_switcher">مغّير طريقة الإدخال</string>
+ <string name="label_action_stop_screenpinning">أوقف تثبيت الشاشة</string>
+ <string name="label_action_ime_down">سهم وسيلة الإدخال لأسفل</string>
+ <string name="label_action_ime_left">سهم وسيلة الإدخال لليسار</string>
+ <string name="label_action_ime_right">سهم وسيلة الإدخال لليمين</string>
+ <string name="label_action_ime_up">سهم وسيلة الإدخال للأعلى</string>
+ <string name="label_action_volume_panel">قائمة مستوى الصوت</string>
+ <string name="label_action_clear_notifications">مسح التنبيهات</string>
+ <string name="label_action_split_screen">تقسيم الشاشة</string>
+ <string name="label_action_one_handed_mode_left">نمط اليد الواحدة (الجانب الأيسر)</string>
+ <string name="label_action_one_handed_mode_right">نمط اليد الواحدة (الجانب الأيمن)</string>
+ <string name="label_action_media_left">المسار السابق</string>
+ <string name="label_action_media_right">المسار التالي</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">تم إغلاق %s</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-ar/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-ar/custom_strings.xml
new file mode 100644
index 0000000..1a948e6
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-ar/custom_strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">لا شيء</string>
+ <string name="label_action_settings_panel">لوحة الإعدادات السريعة</string>
+ <string name="label_action_notification_panel">لوحة الاشعارات</string>
+ <string name="label_action_screenshot">لقطة الشاشة</string>
+ <string name="label_action_region_screenshot">لقطة شاشة جزئية</string>
+ <string name="label_action_screenrecord">تسجيل الشاشة</string>
+ <string name="label_action_expanded_desktop">سطح المكتب الموسّع</string>
+ <string name="label_action_screen_off">إطفاء الشاشة</string>
+ <string name="label_action_force_close_app">أغلاق التطبيق بالقوة</string>
+ <string name="label_action_google_assistant">مساعد جوجل</string>
+ <string name="label_action_in_app_search">البحث داخل التطبيق</string>
+ <string name="label_action_flashlight">الكشاف</string>
+ <string name="label_action_bluetooth">البلوتوث</string>
+ <string name="label_action_wifi">واي فاي</string>
+ <string name="label_action_hotspot">نقطة الإتصال</string>
+ <string name="label_action_last_app">التطبيق السابق</string>
+ <string name="label_action_overview">التطبيقات الأخيرة</string>
+ <string name="label_action_power_menu">قائمة زر التشغيل</string>
+ <string name="label_action_menu">القائمة</string>
+ <string name="label_action_back">رجوع</string>
+ <string name="label_action_home">الرئيسية</string>
+ <string name="label_action_ime_switcher">مغّير طريقة الإدخال</string>
+ <string name="label_action_stop_screenpinning">أوقف تثبيت الشاشة</string>
+ <string name="label_action_ime_down">سهم وسيلة الإدخال لأسفل</string>
+ <string name="label_action_ime_left">سهم وسيلة الإدخال لليسار</string>
+ <string name="label_action_ime_right">سهم وسيلة الإدخال لليمين</string>
+ <string name="label_action_ime_up">سهم وسيلة الإدخال للأعلى</string>
+ <string name="label_action_volume_panel">لوحة الصوت</string>
+ <string name="label_action_clear_notifications">مسح الإشعارات</string>
+ <string name="label_action_split_screen">تقسيم الشاشة</string>
+ <string name="label_action_one_handed_mode_left">نمط اليد الواحدة (الجانب الأيسر)</string>
+ <string name="label_action_one_handed_mode_right">نمط اليد الواحدة (الجانب الأيمن)</string>
+ <string name="label_action_media_left">المسار السابق</string>
+ <string name="label_action_media_right">المسار التالي</string>
+ <string name="label_action_assistant_sound_search">بحث صوتي ب Google</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">تم إغلاق %s</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-as-rIN/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-as-rIN/custom_strings.xml
new file mode 100644
index 0000000..f64c1b3
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-as-rIN/custom_strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-ast-rES/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-ast-rES/custom_strings.xml
new file mode 100644
index 0000000..f64c1b3
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-ast-rES/custom_strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-az-rAZ/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-az-rAZ/custom_strings.xml
new file mode 100644
index 0000000..744b411
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-az-rAZ/custom_strings.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Hərəkət yoxdur</string>
+ <string name="label_action_settings_panel">Parametrlər paneli</string>
+ <string name="label_action_notification_panel">Bildiriş paneli</string>
+ <string name="label_action_screenshot">Ekran görüntüsü</string>
+ <string name="label_action_region_screenshot">Qismən ekran görüntüsü</string>
+ <string name="label_action_screenrecord">Ekranı yadda saxla</string>
+ <string name="label_action_expanded_desktop">Genişləndirilmiş masaüstü</string>
+ <string name="label_action_screen_off">Ekranı söndür</string>
+ <string name="label_action_force_close_app">Tətbiqi bağlanmağa zorla</string>
+ <string name="label_action_in_app_search">Tətbiqetmə içində axtarış</string>
+ <string name="label_action_flashlight">Fənər</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Giriş nöqtəsi</string>
+ <string name="label_action_last_app">Son tətbiqetmə</string>
+ <string name="label_action_overview">Son İstifadə Edilənlər</string>
+ <string name="label_action_power_menu">Güc menyusu</string>
+ <string name="label_action_menu">Menyu</string>
+ <string name="label_action_back">Geri</string>
+ <string name="label_action_home">Əsas səhifə</string>
+ <string name="label_action_ime_switcher">Klaviatura Dəyişdirici</string>
+ <string name="label_action_stop_screenpinning">Ekran sabitləməyi dayandır</string>
+ <string name="label_action_ime_down">Aşağı kursor giriş üsulu</string>
+ <string name="label_action_ime_left">Sol kursor giriş üsulu</string>
+ <string name="label_action_ime_right">Sağ kursor giriş üsuku</string>
+ <string name="label_action_ime_up">Yuxarı kursor giriş üsulu</string>
+ <string name="label_action_volume_panel">Səs paneli</string>
+ <string name="label_action_clear_notifications">Bildirişləri təmizlə</string>
+ <string name="label_action_split_screen">Bölünmüş ekran</string>
+ <string name="label_action_one_handed_mode_left">Tək əl modu (sol tərəf)</string>
+ <string name="label_action_one_handed_mode_right">Tək əl modu (sağ tərəf)</string>
+ <string name="label_action_media_left">Əvvəlki parça</string>
+ <string name="label_action_media_right">Sonrakı parça</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s sonlandırıldı</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-be-rBY/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-be-rBY/custom_strings.xml
new file mode 100644
index 0000000..42283f2
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-be-rBY/custom_strings.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Няма дзеяння</string>
+ <string name="label_action_settings_panel">Панэль налад</string>
+ <string name="label_action_notification_panel">Панэль апавяшчэнняў</string>
+ <string name="label_action_screenshot">Скрыншот</string>
+ <string name="label_action_region_screenshot">Скрыншот абранай вобласці экрана</string>
+ <string name="label_action_screenrecord">Запіс экрана</string>
+ <string name="label_action_expanded_desktop">Рэжым пашыранага экрану</string>
+ <string name="label_action_screen_off">Выключыць экран</string>
+ <string name="label_action_force_close_app">Прымусова закрыць праграму</string>
+ <string name="label_action_in_app_search">Пошук у праграме</string>
+ <string name="label_action_flashlight">Ліхтарык</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Кропка доступу</string>
+ <string name="label_action_last_app">Апошняя праграма</string>
+ <string name="label_action_overview">Нядаўнія</string>
+ <string name="label_action_power_menu">Меню кнопкі сілкавання</string>
+ <string name="label_action_menu">Меню</string>
+ <string name="label_action_back">Назад</string>
+ <string name="label_action_home">Дадому</string>
+ <string name="label_action_ime_switcher">IME перамыкач</string>
+ <string name="label_action_stop_screenpinning">Спыніць замацаванне экрана</string>
+ <string name="label_action_ime_down">Курсор уніз пры ўводзе</string>
+ <string name="label_action_ime_left">Курсор улева пры ўводзе</string>
+ <string name="label_action_ime_right">Курсор управа пры ўводзе</string>
+ <string name="label_action_ime_up">Курсор уверх пры ўводзе</string>
+ <string name="label_action_volume_panel">Панэль гучнасці</string>
+ <string name="label_action_clear_notifications">Ачысціць апавяшчэння</string>
+ <string name="label_action_split_screen">Падзяліць экран</string>
+ <string name="label_action_one_handed_mode_left">Рэжым «Кіраванне адной рукой» (левы бок)</string>
+ <string name="label_action_one_handed_mode_right">Рэжым «Кіраванне адной рукой» (правы бок)</string>
+ <string name="label_action_media_left">Папярэдні трэк</string>
+ <string name="label_action_media_right">Наступны трэк</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s зачынена</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-bg-rBG/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-bg-rBG/custom_strings.xml
new file mode 100644
index 0000000..bdb0b20
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-bg-rBG/custom_strings.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Няма действие</string>
+ <string name="label_action_screenshot">Екранна снимка</string>
+ <string name="label_action_region_screenshot">Частична екранна снимка</string>
+ <string name="label_action_expanded_desktop">Разширен екран</string>
+ <string name="label_action_screen_off">Изключване на екрана</string>
+ <string name="label_action_force_close_app">Принудително спиране</string>
+ <string name="label_action_voice_search">Гласово търсене</string>
+ <string name="label_action_in_app_search">Търсене в приложенията</string>
+ <string name="label_action_flashlight">Фенерче</string>
+ <string name="label_action_bluetooth">Блутуут</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Гореща точка</string>
+ <string name="label_action_last_app">Последно приложение</string>
+ <string name="label_action_overview">Скорошни</string>
+ <string name="label_action_power_menu">Меню мощност</string>
+ <string name="label_action_menu">Меню</string>
+ <string name="label_action_back">Назад</string>
+ <string name="label_action_home">Начало</string>
+ <string name="label_action_ime_down">Метод за въвеждане на курсора надолу</string>
+ <string name="label_action_ime_left">Метод за въвеждане на курсора наляво</string>
+ <string name="label_action_ime_right">Метод за въвеждане на курсора надясно</string>
+ <string name="label_action_ime_up">Метод за въвеждане на курсора нагоре</string>
+ <string name="label_action_volume_panel">Звуков панел</string>
+ <string name="label_action_clear_notifications">Изчисти уведомления</string>
+ <string name="label_action_split_screen">Разделен Екран</string>
+ <string name="label_action_one_handed_mode_left">Режим една ръка (отляво)</string>
+ <string name="label_action_one_handed_mode_right">Режим една ръка (отдясно)</string>
+ <string name="label_action_media_left">Предишна песен</string>
+ <string name="label_action_media_right">Следващата песен</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s затворени</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-bg/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-bg/custom_strings.xml
new file mode 100644
index 0000000..0345ce6
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-bg/custom_strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Няма действие</string>
+ <string name="label_action_settings_panel">Панел за бързи настройки</string>
+ <string name="label_action_notification_panel">Панел за уведомления</string>
+ <string name="label_action_screenshot">Екранна снимка</string>
+ <string name="label_action_region_screenshot">Частична екранна снимка</string>
+ <string name="label_action_screenrecord">Запис на екрана</string>
+ <string name="label_action_expanded_desktop">Разширен екран</string>
+ <string name="label_action_screen_off">Изключване на екрана</string>
+ <string name="label_action_force_close_app">Принудително спиране</string>
+ <string name="label_action_google_assistant">Google асистент</string>
+ <string name="label_action_in_app_search">Търсене в приложенията</string>
+ <string name="label_action_flashlight">Фенерче</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Точка за достъп</string>
+ <string name="label_action_last_app">Последно приложение</string>
+ <string name="label_action_overview">Последни</string>
+ <string name="label_action_power_menu">Меню за изключване</string>
+ <string name="label_action_menu">Меню</string>
+ <string name="label_action_back">Назад</string>
+ <string name="label_action_home">Начало</string>
+ <string name="label_action_ime_switcher">Метот за въвеждане</string>
+ <string name="label_action_stop_screenpinning">Спри закачането на екрана</string>
+ <string name="label_action_ime_down">Метод за въвеждане на курсора надолу</string>
+ <string name="label_action_ime_left">Метод за въвеждане на курсора наляво</string>
+ <string name="label_action_ime_right">Метод за въвеждане на курсора надясно</string>
+ <string name="label_action_ime_up">Метод за въвеждане на курсора нагоре</string>
+ <string name="label_action_volume_panel">Звуков панел</string>
+ <string name="label_action_clear_notifications">Изчисти уведомления</string>
+ <string name="label_action_split_screen">Раздели екрана</string>
+ <string name="label_action_one_handed_mode_left">Режим една ръка (отляво)</string>
+ <string name="label_action_one_handed_mode_right">Режим една ръка (отдясно)</string>
+ <string name="label_action_media_left">Предишна песен</string>
+ <string name="label_action_media_right">Следващата песен</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s затворени</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-bn-rBD/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-bn-rBD/custom_strings.xml
new file mode 100644
index 0000000..1f532a0
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-bn-rBD/custom_strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">কোনো পদক্ষেপ নয়</string>
+ <string name="label_action_settings_panel">কিউএস প্যানেল</string>
+ <string name="label_action_notification_panel">নোটিফিকেশন প্যানেল</string>
+ <string name="label_action_screenshot">স্ক্রিনশট</string>
+ <string name="label_action_region_screenshot">আংশিক স্ক্রিনশট</string>
+ <string name="label_action_screenrecord">রেকর্ডিং পর্দা</string>
+ <string name="label_action_expanded_desktop">সম্প্রসারিত ডেস্কটপ</string>
+ <string name="label_action_screen_off">স্ক্রিন বন্ধ করুন</string>
+ <string name="label_action_force_close_app">অ্যাপ বলপূর্বক বন্ধ করুন</string>
+ <string name="label_action_google_assistant">গুগল অ্যাসিস্ট্যান্ট</string>
+ <string name="label_action_in_app_search">অ্যাপের মধ্যে অনুসন্ধান করুন</string>
+ <string name="label_action_flashlight">ফ্ল্যাশলাইট</string>
+ <string name="label_action_bluetooth">ব্লুটুথ</string>
+ <string name="label_action_wifi">ওয়াই ফাই</string>
+ <string name="label_action_hotspot">হটস্পট</string>
+ <string name="label_action_last_app">সর্বশেষ অ্যাপ</string>
+ <string name="label_action_overview">সাম্প্রতিক</string>
+ <string name="label_action_power_menu">পাওয়ার মেন্যু</string>
+ <string name="label_action_menu">মেন্যু</string>
+ <string name="label_action_back">পেছনে যান</string>
+ <string name="label_action_home">হোম</string>
+ <string name="label_action_ime_switcher">আইএমই পরিবর্তনকারী</string>
+ <string name="label_action_stop_screenpinning">স্ক্রিন পিনিং বন্ধ করুন</string>
+ <string name="label_action_ime_down">ইনপুট পদ্ধতি কার্সর নিচে নামান</string>
+ <string name="label_action_ime_left">ইনপুট পদ্ধতি কার্সর বামে</string>
+ <string name="label_action_ime_right">ইনপুট পদ্ধতি কার্সর ডানে</string>
+ <string name="label_action_ime_up">ইনপুট পদ্ধতি কার্সর উপরে</string>
+ <string name="label_action_volume_panel">ভলিউম প্যানেল</string>
+ <string name="label_action_clear_notifications">নোটিফিকেশন পরিষ্কার করুন</string>
+ <string name="label_action_split_screen">স্প্লিট স্ক্রিন</string>
+ <string name="label_action_one_handed_mode_left">এক হাত মোড (বাম দিক)</string>
+ <string name="label_action_one_handed_mode_right">এক হাত মোড (ডান দিক)</string>
+ <string name="label_action_media_left">পূর্ববর্তী ট্র্যাক</string>
+ <string name="label_action_media_right">পরবর্তী ট্র্যাক</string>
+ <string name="label_action_assistant_sound_search">গুগল শব্দ অনুসন্ধান</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s বন্ধ করা হয়েছে</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-bo-rBT/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-bo-rBT/custom_strings.xml
new file mode 100644
index 0000000..f64c1b3
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-bo-rBT/custom_strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-bs-rBA/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-bs-rBA/custom_strings.xml
new file mode 100644
index 0000000..f64c1b3
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-bs-rBA/custom_strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-ca-rES/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-ca-rES/custom_strings.xml
new file mode 100644
index 0000000..04947ed
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-ca-rES/custom_strings.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">No facis res</string>
+ <string name="label_action_settings_panel">Panell de configuració</string>
+ <string name="label_action_notification_panel">Panell de notificacions</string>
+ <string name="label_action_screenshot">Captura de pantalla</string>
+ <string name="label_action_region_screenshot">Captura de pantalla parcial</string>
+ <string name="label_action_screenrecord">Enregistra la pantalla</string>
+ <string name="label_action_expanded_desktop">Escriptori Extès</string>
+ <string name="label_action_flashlight">Llanterna</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_back">Enrere</string>
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-ca/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-ca/custom_strings.xml
new file mode 100644
index 0000000..4d1d645
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-ca/custom_strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Cap acció</string>
+ <string name="label_action_settings_panel">Panell d\'opcions ràpides</string>
+ <string name="label_action_notification_panel">Panell de notificacions</string>
+ <string name="label_action_screenshot">Captura de pantalla</string>
+ <string name="label_action_region_screenshot">Captura de pantalla parcial</string>
+ <string name="label_action_screenrecord">Enregistra la pantalla</string>
+ <string name="label_action_expanded_desktop">Escriptori Estès</string>
+ <string name="label_action_screen_off">Apagar la pantalla</string>
+ <string name="label_action_force_close_app">Força el tancament de l\'aplicació</string>
+ <string name="label_action_google_assistant">Assistent de Google</string>
+ <string name="label_action_in_app_search">Cerca a l\'aplicació</string>
+ <string name="label_action_flashlight">Llanterna</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Zona WiFi</string>
+ <string name="label_action_last_app">Darrera aplicació</string>
+ <string name="label_action_overview">Aplicacions recents</string>
+ <string name="label_action_power_menu">Menú d\'apagada</string>
+ <string name="label_action_menu">Menú</string>
+ <string name="label_action_back">Enrere</string>
+ <string name="label_action_home">Inici</string>
+ <string name="label_action_ime_switcher">Selector d\'IME</string>
+ <string name="label_action_stop_screenpinning">Atura la fixació de pantalla</string>
+ <string name="label_action_ime_down">Cursor de mètode d\'entrada cap avall</string>
+ <string name="label_action_ime_left">Cursor de mètode d\'entrada cap a l\'esquerra</string>
+ <string name="label_action_ime_right">Cursor de mètode d\'entrada cap a la dreta</string>
+ <string name="label_action_ime_up">Cursor de mètode d\'entrada cap a dalt</string>
+ <string name="label_action_volume_panel">Panell de volum</string>
+ <string name="label_action_clear_notifications">Netejar notificacions</string>
+ <string name="label_action_split_screen">Pantalla dividida</string>
+ <string name="label_action_one_handed_mode_left">Mode a una mà (costat esquerre)</string>
+ <string name="label_action_one_handed_mode_right">Mode a una mà (costat dret)</string>
+ <string name="label_action_media_left">Pista anterior</string>
+ <string name="label_action_media_right">Pista posterior</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">Aplicació %s finalitzada</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-cs-rCZ/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-cs-rCZ/custom_strings.xml
new file mode 100644
index 0000000..41b5e29
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-cs-rCZ/custom_strings.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Žádná akce</string>
+ <string name="label_action_settings_panel">Panel rychlého nastavení</string>
+ <string name="label_action_notification_panel">Panel upozornění</string>
+ <string name="label_action_screenshot">Snímek obrazovky</string>
+ <string name="label_action_region_screenshot">Částečný snímek obrazovky</string>
+ <string name="label_action_screenrecord">Záznam obrazovky</string>
+ <string name="label_action_expanded_desktop">Rozšířená plocha</string>
+ <string name="label_action_screen_off">Vypnout obrazovku</string>
+ <string name="label_action_force_close_app">Vynutit ukončení aplikace</string>
+ <string name="label_action_search_assistant">Vyhledávací asistent</string>
+ <string name="label_action_google_now_on_tap">Asistent Google</string>
+ <string name="label_action_voice_search">Hlasové vyhledávání</string>
+ <string name="label_action_in_app_search">Hledat v aplikacích</string>
+ <string name="label_action_flashlight">Svítilna</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Hotspot</string>
+ <string name="label_action_last_app">Poslední aplikace</string>
+ <string name="label_action_overview">Nedávné</string>
+ <string name="label_action_power_menu">Nabídka tlačítka Vypnout</string>
+ <string name="label_action_menu">Nabídka</string>
+ <string name="label_action_back">Zpět</string>
+ <string name="label_action_home">Domů</string>
+ <string name="label_action_ime_switcher">Editor IME</string>
+ <string name="label_action_stop_screenpinning">Vypnout připnutí obrazovky</string>
+ <string name="label_action_ime_down">Vstupní metoda - kurzor dolů</string>
+ <string name="label_action_ime_left">Vstupní metoda - kurzor doleva</string>
+ <string name="label_action_ime_right">Vstupní metoda - kurzor doprava</string>
+ <string name="label_action_ime_up">Vstupní metoda - kurzor nahoru</string>
+ <string name="label_action_volume_panel">Panel hlasitosti</string>
+ <string name="label_action_clear_notifications">Vymazat oznámení</string>
+ <string name="label_action_split_screen">Rozdělená obrazovka</string>
+ <string name="label_action_one_handed_mode_left">Režim jedné ruky (vlevo)</string>
+ <string name="label_action_one_handed_mode_right">Režim jedné ruky (vpravo)</string>
+ <string name="label_action_media_left">Předchozí skladba</string>
+ <string name="label_action_media_right">Další skladba</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s aplikace ukončena</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-cs/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-cs/custom_strings.xml
new file mode 100644
index 0000000..6cdc19c
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-cs/custom_strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Žádná akce</string>
+ <string name="label_action_settings_panel">Panel rychlého nastavení</string>
+ <string name="label_action_notification_panel">Panel upozornění</string>
+ <string name="label_action_screenshot">Snímek obrazovky</string>
+ <string name="label_action_region_screenshot">Částečný snímek obrazovky</string>
+ <string name="label_action_screenrecord">Záznam obrazovky</string>
+ <string name="label_action_expanded_desktop">Rozšířená plocha</string>
+ <string name="label_action_screen_off">Vypnout obrazovku</string>
+ <string name="label_action_force_close_app">Vynutit ukončení aplikace</string>
+ <string name="label_action_google_assistant">Asistent Google</string>
+ <string name="label_action_in_app_search">Hledat v aplikacích</string>
+ <string name="label_action_flashlight">Svítilna</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Hotspot</string>
+ <string name="label_action_last_app">Poslední aplikace</string>
+ <string name="label_action_overview">Nedávné</string>
+ <string name="label_action_power_menu">Nabídka tlačítka Vypnout</string>
+ <string name="label_action_menu">Nabídka</string>
+ <string name="label_action_back">Zpět</string>
+ <string name="label_action_home">Domů</string>
+ <string name="label_action_ime_switcher">Editor IME</string>
+ <string name="label_action_stop_screenpinning">Vypnout připnutí obrazovky</string>
+ <string name="label_action_ime_down">Vstupní metoda - kurzor dolů</string>
+ <string name="label_action_ime_left">Vstupní metoda - kurzor doleva</string>
+ <string name="label_action_ime_right">Vstupní metoda - kurzor doprava</string>
+ <string name="label_action_ime_up">Vstupní metoda - kurzor nahoru</string>
+ <string name="label_action_volume_panel">Panel hlasitosti</string>
+ <string name="label_action_clear_notifications">Vymazat oznámení</string>
+ <string name="label_action_split_screen">Rozdělená obrazovka</string>
+ <string name="label_action_one_handed_mode_left">Režim jedné ruky (vlevo)</string>
+ <string name="label_action_one_handed_mode_right">Režim jedné ruky (vpravo)</string>
+ <string name="label_action_media_left">Předchozí skladba</string>
+ <string name="label_action_media_right">Další skladba</string>
+ <string name="label_action_assistant_sound_search">Vyhledávání zvuku Google</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s aplikace ukončena</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-da-rDK/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-da-rDK/custom_strings.xml
new file mode 100644
index 0000000..147140b
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-da-rDK/custom_strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_region_screenshot">Delvis screenshot</string>
+ <string name="label_action_flashlight">Lommelygte</string>
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-da/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-da/custom_strings.xml
new file mode 100644
index 0000000..cbf5ffa
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-da/custom_strings.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Ingen handling</string>
+ <string name="label_action_settings_panel">QS panel</string>
+ <string name="label_action_notification_panel">Notifikationspanel</string>
+ <string name="label_action_screenshot">Skærmbillede</string>
+ <string name="label_action_region_screenshot">Delvis screenshot</string>
+ <string name="label_action_screenrecord">Optag Skærm</string>
+ <string name="label_action_expanded_desktop">Udvidet skrivebord</string>
+ <string name="label_action_screen_off">Sluk skærmen</string>
+ <string name="label_action_force_close_app">Tving til at lukke?</string>
+ <string name="label_action_google_assistant">Google assistant</string>
+ <string name="label_action_in_app_search">Søgning i app</string>
+ <string name="label_action_flashlight">Lommelygte</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Hotspot</string>
+ <string name="label_action_last_app">Seneste app</string>
+ <string name="label_action_overview">Seneste</string>
+ <string name="label_action_power_menu">Power Menu</string>
+ <string name="label_action_menu">Menu</string>
+ <string name="label_action_back">Tilbage</string>
+ <string name="label_action_home">Hjem</string>
+ <string name="label_action_volume_panel">Lydstyrkepanel</string>
+ <string name="label_action_clear_notifications">Ryd underretninger</string>
+ <string name="label_action_split_screen">Opdel skærm</string>
+ <string name="label_action_one_handed_mode_left">En hånds betjening (venstre side)</string>
+ <string name="label_action_one_handed_mode_right">En hånds betjening (højre side)</string>
+ <string name="label_action_media_left">Forrige nummer</string>
+ <string name="label_action_media_right">Næste nummer</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s lukket</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-de-rDE/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-de-rDE/custom_strings.xml
new file mode 100644
index 0000000..64add9d
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-de-rDE/custom_strings.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Keine Aktion</string>
+ <string name="label_action_settings_panel">Einstellungs Panel</string>
+ <string name="label_action_notification_panel">Benachrichtigungsleiste</string>
+ <string name="label_action_screenshot">Bildschirmfoto</string>
+ <string name="label_action_region_screenshot">Partieller Screenshot</string>
+ <string name="label_action_screenrecord">Bildschirmaufnahme</string>
+ <string name="label_action_expanded_desktop">Erweiterter Desktop</string>
+ <string name="label_action_screen_off">Bildschirm ausschalten</string>
+ <string name="label_action_force_close_app">App beenden</string>
+ <string name="label_action_search_assistant">Suchassistent</string>
+ <string name="label_action_google_now_on_tap">Google Now On Tap</string>
+ <string name="label_action_voice_search">Sprachsuche</string>
+ <string name="label_action_in_app_search">In-App Suche</string>
+ <string name="label_action_flashlight">Taschenlampe</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WLAN</string>
+ <string name="label_action_hotspot">Hotspot</string>
+ <string name="label_action_last_app">Letzte Anwendung</string>
+ <string name="label_action_overview">Anwendungsverlauf</string>
+ <string name="label_action_power_menu">Powermenü</string>
+ <string name="label_action_menu">Menü</string>
+ <string name="label_action_back">Zurück</string>
+ <string name="label_action_home">Startseite</string>
+ <string name="label_action_ime_switcher">IME-Wechsler</string>
+ <string name="label_action_stop_screenpinning">Bildschirmfixierung stoppen</string>
+ <string name="label_action_ime_down">Eingabemethode Cursor unten</string>
+ <string name="label_action_ime_left">Eingabemethode Cursor links</string>
+ <string name="label_action_ime_right">Eingabemethode Cursor rechts</string>
+ <string name="label_action_ime_up">Eingabemethode Cursor oben</string>
+ <string name="label_action_volume_panel">Lautstärkeregler</string>
+ <string name="label_action_clear_notifications">Benachrichtigungen löschen</string>
+ <string name="label_action_split_screen">Geteilter Bildschirm</string>
+ <string name="label_action_one_handed_mode_left">Einhandmodus (linke Seite)</string>
+ <string name="label_action_one_handed_mode_right">Einhandmodus (rechte Seite)</string>
+ <string name="label_action_media_left">Vorheriger Titel</string>
+ <string name="label_action_media_right">Nächster Titel</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s beendet</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-de/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-de/custom_strings.xml
new file mode 100644
index 0000000..fc8648c
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-de/custom_strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Keine Aktion</string>
+ <string name="label_action_settings_panel">Schnelleinstellungen</string>
+ <string name="label_action_notification_panel">Benachrichtigungsleiste</string>
+ <string name="label_action_screenshot">Bildschirmfoto</string>
+ <string name="label_action_region_screenshot">Teil-Bildschirmaufnahme</string>
+ <string name="label_action_screenrecord">Bildschirmaufnahme</string>
+ <string name="label_action_expanded_desktop">Erweiterter Desktop</string>
+ <string name="label_action_screen_off">Bildschirm ausschalten</string>
+ <string name="label_action_force_close_app">App beenden erzwingen</string>
+ <string name="label_action_google_assistant">Google Assistant</string>
+ <string name="label_action_in_app_search">In-App Suche</string>
+ <string name="label_action_flashlight">Taschenlampe</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WLAN</string>
+ <string name="label_action_hotspot">Hotspot</string>
+ <string name="label_action_last_app">Letzte App</string>
+ <string name="label_action_overview">Verlauf</string>
+ <string name="label_action_power_menu">Powermenü</string>
+ <string name="label_action_menu">Menü</string>
+ <string name="label_action_back">Zurück</string>
+ <string name="label_action_home">Startseite</string>
+ <string name="label_action_ime_switcher">IME-Wechsler</string>
+ <string name="label_action_stop_screenpinning">Bildschirmfixierung beenden</string>
+ <string name="label_action_ime_down">Eingabemethode Cursor unten</string>
+ <string name="label_action_ime_left">Eingabemethode Cursor links</string>
+ <string name="label_action_ime_right">Eingabemethode Cursor rechts</string>
+ <string name="label_action_ime_up">Eingabemethode Cursor oben</string>
+ <string name="label_action_volume_panel">Lautstärkeregler</string>
+ <string name="label_action_clear_notifications">Benachrichtigungen löschen</string>
+ <string name="label_action_split_screen">Geteilter Bildschirm</string>
+ <string name="label_action_one_handed_mode_left">Einhandmodus (linke Seite)</string>
+ <string name="label_action_one_handed_mode_right">Einhandmodus (rechte Seite)</string>
+ <string name="label_action_media_left">Vorheriger Titel</string>
+ <string name="label_action_media_right">Nächster Titel</string>
+ <string name="label_action_assistant_sound_search">Google Sounderkenner</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s beendet</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-el-rGR/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-el-rGR/custom_strings.xml
new file mode 100644
index 0000000..c34fdf7
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-el-rGR/custom_strings.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Καμία ενέργεια</string>
+ <string name="label_action_settings_panel">Πάνελ ρυθμίσεων</string>
+ <string name="label_action_notification_panel">Πάνελ ειδοποιήσεων</string>
+ <string name="label_action_screenshot">Στιγμιότυπο οθόνης</string>
+ <string name="label_action_region_screenshot">Μερικό στιγμιότυπο οθόνης</string>
+ <string name="label_action_screenrecord">Βιντεοσκόπηση οθόνης</string>
+ <string name="label_action_expanded_desktop">Εκτεταμένη επιφάνεια εργασίας</string>
+ <string name="label_action_screen_off">Απενεργοποίηση οθόνης</string>
+ <string name="label_action_force_close_app">Αναγκαστικό κλείσιμο εφαρμογής</string>
+ <string name="label_action_search_assistant">Βοηθός αναζήτησης</string>
+ <string name="label_action_google_now_on_tap">Αγγίξτε για Google Now</string>
+ <string name="label_action_voice_search">Φωνητική αναζήτηση</string>
+ <string name="label_action_in_app_search">Αναζήτηση μέσα στην εφαρμογή</string>
+ <string name="label_action_flashlight">Φακός</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Σημείο πρόσβασης</string>
+ <string name="label_action_last_app">Τελευταία εφαρμογή</string>
+ <string name="label_action_overview">Πρόσφατα</string>
+ <string name="label_action_power_menu">Μενού ενεργοποίησης</string>
+ <string name="label_action_menu">Μενού</string>
+ <string name="label_action_back">Πίσω</string>
+ <string name="label_action_home">Αρχική σελίδα</string>
+ <string name="label_action_ime_switcher">Εναλλαγή μεθόδου εισαγωγής</string>
+ <string name="label_action_stop_screenpinning">Σταμάτημα καρφιτσώματος οθόνης</string>
+ <string name="label_action_ime_down">Δρομέας μεθόδου εισαγωγής κάτω</string>
+ <string name="label_action_ime_left">Δρομέας μεθόδου εισαγωγής αριστερά</string>
+ <string name="label_action_ime_right">Δρομέας μεθόδου εισαγωγής δεξιά</string>
+ <string name="label_action_ime_up">Δρομέας μεθόδου εισαγωγής πάνω</string>
+ <string name="label_action_volume_panel">Πίνακας έντασης</string>
+ <string name="label_action_clear_notifications">Εκκαθάριση ειδοποιήσεων</string>
+ <string name="label_action_split_screen">Διαχωρισμός οθόνης</string>
+ <string name="label_action_one_handed_mode_left">Λειτουργία ενός χεριού (αριστερή μεριά)</string>
+ <string name="label_action_one_handed_mode_right">Λειτουργία ενός χεριού (δεξιά μεριά)</string>
+ <string name="label_action_media_left">Προηγούμενο κομμάτι</string>
+ <string name="label_action_media_right">Επόμενο κομμάτι</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s τερματίστηκαν</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-el/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-el/custom_strings.xml
new file mode 100644
index 0000000..245e109
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-el/custom_strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Καμία ενέργεια</string>
+ <string name="label_action_settings_panel">Πάνελ ρυθμίσεων</string>
+ <string name="label_action_notification_panel">Πάνελ ειδοποιήσεων</string>
+ <string name="label_action_screenshot">Στιγμιότυπο οθόνης</string>
+ <string name="label_action_region_screenshot">Μερικό στιγμιότυπο οθόνης</string>
+ <string name="label_action_screenrecord">Βιντεοσκόπηση οθόνης</string>
+ <string name="label_action_expanded_desktop">Εκτεταμένη επιφάνεια εργασίας</string>
+ <string name="label_action_screen_off">Απενεργοποίηση οθόνης</string>
+ <string name="label_action_force_close_app">Αναγκαστικό κλείσιμο εφαρμογής</string>
+ <string name="label_action_google_assistant">Google Βοηθός</string>
+ <string name="label_action_in_app_search">Αναζήτηση μέσα στην εφαρμογή</string>
+ <string name="label_action_flashlight">Φακός</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Σημείο πρόσβασης Wi-Fi</string>
+ <string name="label_action_last_app">Τελευταία εφαρμογή</string>
+ <string name="label_action_overview">Πρόσφατα</string>
+ <string name="label_action_power_menu">Μενού ενεργοποίησης</string>
+ <string name="label_action_menu">Μενού</string>
+ <string name="label_action_back">Πίσω</string>
+ <string name="label_action_home">Αρχική σελίδα</string>
+ <string name="label_action_ime_switcher">Αλλαγή IME</string>
+ <string name="label_action_stop_screenpinning">Σταμάτημα καρφιτσώματος οθόνης</string>
+ <string name="label_action_ime_down">Δρομέας μεθόδου εισαγωγής κάτω</string>
+ <string name="label_action_ime_left">Δρομέας μεθόδου εισαγωγής αριστερά</string>
+ <string name="label_action_ime_right">Δρομέας μεθόδου εισαγωγής δεξιά</string>
+ <string name="label_action_ime_up">Δρομέας μεθόδου εισαγωγής πάνω</string>
+ <string name="label_action_volume_panel">Πίνακας έντασης</string>
+ <string name="label_action_clear_notifications">Εκκαθάριση ειδοποιήσεων</string>
+ <string name="label_action_split_screen">Διαχωρισμός οθόνης</string>
+ <string name="label_action_one_handed_mode_left">Λειτουργία ενός χεριού (αριστερή μεριά)</string>
+ <string name="label_action_one_handed_mode_right">Λειτουργία ενός χεριού (δεξιά μεριά)</string>
+ <string name="label_action_media_left">Προηγούμενο κομμάτι</string>
+ <string name="label_action_media_right">Επόμενο κομμάτι</string>
+ <string name="label_action_assistant_sound_search">Αναζήτηση ήχου Google</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s τερματίστηκαν</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-en-rUS/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-en-rUS/custom_strings.xml
new file mode 100644
index 0000000..f64c1b3
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-en-rUS/custom_strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-eo-rUY/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-eo-rUY/custom_strings.xml
new file mode 100644
index 0000000..f64c1b3
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-eo-rUY/custom_strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-eo/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-eo/custom_strings.xml
new file mode 100644
index 0000000..f64c1b3
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-eo/custom_strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-es-rES/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-es-rES/custom_strings.xml
new file mode 100644
index 0000000..e87d09a
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-es-rES/custom_strings.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Sen acción</string>
+ <string name="label_action_settings_panel">Panel de axustes</string>
+ <string name="label_action_notification_panel">Panel de notificacións</string>
+ <string name="label_action_screenshot">Captura de pantalla</string>
+ <string name="label_action_region_screenshot">Captura de pantalla parcial</string>
+ <string name="label_action_screenrecord">Gravar a pantalla</string>
+ <string name="label_action_expanded_desktop">Escritorio estendido</string>
+ <string name="label_action_screen_off">Apagar a pantalla</string>
+ <string name="label_action_force_close_app">Forzar peche do aplicativo</string>
+ <string name="label_action_search_assistant">Asistente de procura</string>
+ <string name="label_action_google_now_on_tap">Google Now ao tocar</string>
+ <string name="label_action_voice_search">Procura con voz</string>
+ <string name="label_action_in_app_search">Buscar no aplicativo</string>
+ <string name="label_action_flashlight">Lanterna</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Punto de acceso</string>
+ <string name="label_action_last_app">Último aplicativo</string>
+ <string name="label_action_overview">Recentes</string>
+ <string name="label_action_power_menu">Menu de enerxía</string>
+ <string name="label_action_menu">Menu</string>
+ <string name="label_action_back">Volver</string>
+ <string name="label_action_home">Inicio</string>
+ <string name="label_action_ime_switcher">Alternador IME</string>
+ <string name="label_action_stop_screenpinning">Deter fixado de pantalla</string>
+ <string name="label_action_ime_down">Método de entrada cursor hacia abaixo</string>
+ <string name="label_action_ime_left">Método de entrada cursor hacia a esquerda</string>
+ <string name="label_action_ime_right">Método de entrada cursor hacia a dereita</string>
+ <string name="label_action_ime_up">Método de entrada cursor hacia arriba</string>
+ <string name="label_action_volume_panel">Panel de volume</string>
+ <string name="label_action_clear_notifications">Limpar as notificacións</string>
+ <string name="label_action_split_screen">Dividir a pantalla</string>
+ <string name="label_action_one_handed_mode_left">Modo a unha man (lado esquerdo)</string>
+ <string name="label_action_one_handed_mode_right">Modo a unha man (lado dereito)</string>
+ <string name="label_action_media_left">Canción anterior</string>
+ <string name="label_action_media_right">Seguinte canción</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s matado</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-es-rMX/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-es-rMX/custom_strings.xml
new file mode 100644
index 0000000..701b98c
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-es-rMX/custom_strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Sin acción</string>
+ <string name="label_action_settings_panel">Panel de Ajustes Rápidos</string>
+ <string name="label_action_notification_panel">Panel de notificaciones</string>
+ <string name="label_action_screenshot">Captura de pantalla</string>
+ <string name="label_action_region_screenshot">Captura de pantalla parcial</string>
+ <string name="label_action_screenrecord">Grabar pantalla</string>
+ <string name="label_action_expanded_desktop">Escritorio extendido</string>
+ <string name="label_action_screen_off">Apagar a pantalla</string>
+ <string name="label_action_force_close_app">Cierre de aplicación forzada</string>
+ <string name="label_action_google_assistant">Asistente de Google</string>
+ <string name="label_action_in_app_search">Búsqueda en la aplicación</string>
+ <string name="label_action_flashlight">Linterna</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Punto de acceso</string>
+ <string name="label_action_last_app">Última aplicación</string>
+ <string name="label_action_overview">Aplicaciones recientes</string>
+ <string name="label_action_power_menu">Menú de apagado</string>
+ <string name="label_action_menu">Menú</string>
+ <string name="label_action_back">Atrás</string>
+ <string name="label_action_home">Inicio</string>
+ <string name="label_action_ime_switcher">Cambiador de IME</string>
+ <string name="label_action_stop_screenpinning">Detener fijado de pantalla</string>
+ <string name="label_action_ime_down">Método de entrada cursor hacia abajo</string>
+ <string name="label_action_ime_left">Método de entrada cursor hacia la izquierda</string>
+ <string name="label_action_ime_right">Método de entrada cursor hacia la derecha</string>
+ <string name="label_action_ime_up">Método de entrada cursos hacia arriba</string>
+ <string name="label_action_volume_panel">Panel de volumen</string>
+ <string name="label_action_clear_notifications">Eliminar notificaciones</string>
+ <string name="label_action_split_screen">Pantalla dividida</string>
+ <string name="label_action_one_handed_mode_left">Modo de una mano (Lado izquierdo)</string>
+ <string name="label_action_one_handed_mode_right">Modo de una mano (Lado derecho)</string>
+ <string name="label_action_media_left">Pista anterior</string>
+ <string name="label_action_media_right">Siguiente pista</string>
+ <string name="label_action_assistant_sound_search">Búsqueda de sonidos de Google</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s terminado</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-es/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-es/custom_strings.xml
new file mode 100644
index 0000000..2c18b50
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-es/custom_strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Sin acción</string>
+ <string name="label_action_settings_panel">Panel de ajustes</string>
+ <string name="label_action_notification_panel">Panel de notificaciones</string>
+ <string name="label_action_screenshot">Captura de pantalla</string>
+ <string name="label_action_region_screenshot">Captura de pantalla parcial</string>
+ <string name="label_action_screenrecord">Grabar pantalla</string>
+ <string name="label_action_expanded_desktop">Escritorio extendido</string>
+ <string name="label_action_screen_off">Apagar la pantalla</string>
+ <string name="label_action_force_close_app">Forzar cierre de la aplicación</string>
+ <string name="label_action_google_assistant">Asistente de Google</string>
+ <string name="label_action_in_app_search">Búsqueda dentro de la aplicación</string>
+ <string name="label_action_flashlight">Linterna</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Zona Wi-Fi</string>
+ <string name="label_action_last_app">Última aplicación</string>
+ <string name="label_action_overview">Recientes</string>
+ <string name="label_action_power_menu">Menú de apagado</string>
+ <string name="label_action_menu">Menú</string>
+ <string name="label_action_back">Atrás</string>
+ <string name="label_action_home">Inicio</string>
+ <string name="label_action_ime_switcher">Selector de IME</string>
+ <string name="label_action_stop_screenpinning">Detener fijado de pantalla</string>
+ <string name="label_action_ime_down">Cursor de método de entrada hacia abajo</string>
+ <string name="label_action_ime_left">Cursor de método de entrada a la izquierda</string>
+ <string name="label_action_ime_right">Cursor de método de entrada a la derecha</string>
+ <string name="label_action_ime_up">Cursor de método de entrada hacia arriba</string>
+ <string name="label_action_volume_panel">Panel de volumen</string>
+ <string name="label_action_clear_notifications">Borrar notificaciones</string>
+ <string name="label_action_split_screen">Pantalla dividida</string>
+ <string name="label_action_one_handed_mode_left">Modo solo una mano (lado izquierdo)</string>
+ <string name="label_action_one_handed_mode_right">Modo solo una mano (lado derecho)</string>
+ <string name="label_action_media_left">Canción anterior</string>
+ <string name="label_action_media_right">Siguiente canción</string>
+ <string name="label_action_assistant_sound_search">Búsqueda de sonido de Google</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">Aplicación %s finalizada</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-et-rEE/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-et-rEE/custom_strings.xml
new file mode 100644
index 0000000..a056a10
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-et-rEE/custom_strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Tegevus puudub</string>
+ <string name="label_action_settings_panel">Kiirseadete paneel</string>
+ <string name="label_action_notification_panel">Teavituste paneel</string>
+ <string name="label_action_screenshot">Kuvatõmmis</string>
+ <string name="label_action_region_screenshot">Osaline kuvatõmmis</string>
+ <string name="label_action_screenrecord">Jäädvusta ekraani</string>
+ <string name="label_action_expanded_desktop">Laiendatud töölaud</string>
+ <string name="label_action_screen_off">Lülita ekraan välja</string>
+ <string name="label_action_force_close_app">Sundsulge rakendus</string>
+ <string name="label_action_google_assistant">Google\'i abiline</string>
+ <string name="label_action_in_app_search">Rakendusesisene otsing</string>
+ <string name="label_action_flashlight">Taskulamp</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Kuumkoht</string>
+ <string name="label_action_last_app">Viimane rakendus</string>
+ <string name="label_action_overview">Hiljutised</string>
+ <string name="label_action_power_menu">Toite menüü</string>
+ <string name="label_action_menu">Menüü</string>
+ <string name="label_action_back">Tagasi</string>
+ <string name="label_action_home">Avaekraan</string>
+ <string name="label_action_ime_switcher">IME muutja</string>
+ <string name="label_action_stop_screenpinning">Peata ekraani kinnitamine</string>
+ <string name="label_action_ime_down">Sisendmeetodi kursor all</string>
+ <string name="label_action_ime_left">Sisendmeetodi kursor vasakul</string>
+ <string name="label_action_ime_right">Sisendmeetodi kursor paremal</string>
+ <string name="label_action_ime_up">Sisendmeetodi kursor üleval</string>
+ <string name="label_action_volume_panel">Helitugevuse paneel</string>
+ <string name="label_action_clear_notifications">Kustuta teavitused</string>
+ <string name="label_action_split_screen">Jaga ekraan</string>
+ <string name="label_action_one_handed_mode_left">Ühe käe režiim (vasak pool)</string>
+ <string name="label_action_one_handed_mode_right">Ühe käe režiim (parem pool)</string>
+ <string name="label_action_media_left">Eelmine lugu</string>
+ <string name="label_action_media_right">Järgmine lugu</string>
+ <string name="label_action_assistant_sound_search">Google\'i heliotsing</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s suletud</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-eu-rES/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-eu-rES/custom_strings.xml
new file mode 100644
index 0000000..f64c1b3
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-eu-rES/custom_strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-fa-rIR/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-fa-rIR/custom_strings.xml
new file mode 100644
index 0000000..23cd8dd
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-fa-rIR/custom_strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_settings_panel">پنل قسمت تنظیمات سریع</string>
+ <string name="label_action_screenshot">عکس گرفتن از صفحه فعلی</string>
+ <string name="label_action_flashlight">چراغ قوه</string>
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-fa/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-fa/custom_strings.xml
new file mode 100644
index 0000000..9cb70b4
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-fa/custom_strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">بدون اقدام</string>
+ <string name="label_action_settings_panel">پانل تنظیمات سریع</string>
+ <string name="label_action_notification_panel">پانل اعلانها</string>
+ <string name="label_action_screenshot">عکس گرفتن از صفحه</string>
+ <string name="label_action_region_screenshot">عکس گرفتن از بخشی از صفحه</string>
+ <string name="label_action_screenrecord">فیلم گرفتن از صفحه</string>
+ <string name="label_action_expanded_desktop">میز کار گسترده</string>
+ <string name="label_action_screen_off">خاموش کردن صفحهنمایش</string>
+ <string name="label_action_force_close_app">توقف اجباری برنامه</string>
+ <string name="label_action_google_assistant">دستیار صوتی گوگل</string>
+ <string name="label_action_in_app_search">جستجوی درون برنامهای</string>
+ <string name="label_action_flashlight">چراغ قوه</string>
+ <string name="label_action_bluetooth">بلوتوث</string>
+ <string name="label_action_wifi">وایفای</string>
+ <string name="label_action_hotspot">نقطه اتصال</string>
+ <string name="label_action_last_app">آخرین برنامه اجرا شده</string>
+ <string name="label_action_overview">برنامههای اخیر</string>
+ <string name="label_action_power_menu">منوی پاور</string>
+ <string name="label_action_menu">منو</string>
+ <string name="label_action_back">بازگشت</string>
+ <string name="label_action_home">صفحه اصلی</string>
+ <string name="label_action_ime_switcher">تغییر چینش کیبورد</string>
+ <string name="label_action_stop_screenpinning">توقف حالت سنجاق صفحه</string>
+ <string name="label_action_ime_down">مکان نمای ورودی متن به سمت پایین</string>
+ <string name="label_action_ime_left">مکان نمای ورودی متن به سمت چپ</string>
+ <string name="label_action_ime_right">مکان نمای ورودی متن به سمت راست</string>
+ <string name="label_action_ime_up">مکان نمای ورودی متن به سمت بالا</string>
+ <string name="label_action_volume_panel">پنل تنظیم صدا</string>
+ <string name="label_action_clear_notifications">پاک کردن اعلانها</string>
+ <string name="label_action_split_screen">تقسیم صفحه</string>
+ <string name="label_action_one_handed_mode_left">حالت کار با یک دست (سمت چپ)</string>
+ <string name="label_action_one_handed_mode_right">حالت کار با یک دست (سمت راست)</string>
+ <string name="label_action_media_left">آهنگ قبلی</string>
+ <string name="label_action_media_right">آهنگ بعدی</string>
+ <string name="label_action_assistant_sound_search">جستجوی صوتی گوگل</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s متوقف شد</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-fi-rFI/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-fi-rFI/custom_strings.xml
new file mode 100644
index 0000000..087ec02
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-fi-rFI/custom_strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Ei toimintoa</string>
+ <string name="label_action_settings_panel">Asetusvalikko</string>
+ <string name="label_action_notification_panel">Ilmoitusvalikko</string>
+ <string name="label_action_screenshot">Kuvakaappaus</string>
+ <string name="label_action_region_screenshot">Osittainen kuvakaappaus</string>
+ <string name="label_action_screenrecord">Tallenna näyttöä</string>
+ <string name="label_action_expanded_desktop">Laajennettu työpöytä</string>
+ <string name="label_action_flashlight">Taskulamppu</string>
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-fi/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-fi/custom_strings.xml
new file mode 100644
index 0000000..855140d
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-fi/custom_strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Ei toimintoa</string>
+ <string name="label_action_settings_panel">Pikasetus paneeli</string>
+ <string name="label_action_notification_panel">Ilmoitus paneeli</string>
+ <string name="label_action_screenshot">Näytönkaappaus</string>
+ <string name="label_action_region_screenshot">Osittainen Näytönkaappaus</string>
+ <string name="label_action_screenrecord">Tallenna näyttö tiedostoon</string>
+ <string name="label_action_expanded_desktop">Laajennettu työpöytä</string>
+ <string name="label_action_screen_off">Sammuta näyttö</string>
+ <string name="label_action_force_close_app">Pakota sovelluksen sulkeminen</string>
+ <string name="label_action_google_assistant">Google avustaja</string>
+ <string name="label_action_in_app_search">Sovelluksen sisäinen haku</string>
+ <string name="label_action_flashlight">Taskulamppu</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Kuumapiste</string>
+ <string name="label_action_last_app">Viimeisin sovellus</string>
+ <string name="label_action_overview">Viimeaikaiset</string>
+ <string name="label_action_power_menu">Virta valikko</string>
+ <string name="label_action_menu">Menu</string>
+ <string name="label_action_back">Takaisin</string>
+ <string name="label_action_home">Koti</string>
+ <string name="label_action_ime_switcher">IME vaihtaja</string>
+ <string name="label_action_stop_screenpinning">Lopeta näytön kiinnitys</string>
+ <string name="label_action_ime_down">Syöttötapa osoitin alas</string>
+ <string name="label_action_ime_left">Syöttötapa osoitin vasemmalle</string>
+ <string name="label_action_ime_right">Syöttötapa osoitin oikealle</string>
+ <string name="label_action_ime_up">Syöttötapa osoitin ylös</string>
+ <string name="label_action_volume_panel">Äänenvoimakkuus paneeli</string>
+ <string name="label_action_clear_notifications">Tyhjennä ilmoitukset</string>
+ <string name="label_action_split_screen">Jaettu näyttö</string>
+ <string name="label_action_one_handed_mode_left">Yhden käden tila (vasen puoli)</string>
+ <string name="label_action_one_handed_mode_right">Yhden käden tila (oikea puoli)</string>
+ <string name="label_action_media_left">Edellinen biisi</string>
+ <string name="label_action_media_right">Seuraava biisi</string>
+ <string name="label_action_assistant_sound_search">Googlen ääni haku</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s teurastettu</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-fr-rFR/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-fr-rFR/custom_strings.xml
new file mode 100644
index 0000000..caf38cd
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-fr-rFR/custom_strings.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Aucune action</string>
+ <string name="label_action_settings_panel">Volet des réglages rapides</string>
+ <string name="label_action_notification_panel">Panneau de notification</string>
+ <string name="label_action_screenshot">Capture d\'écran</string>
+ <string name="label_action_region_screenshot">Capture d’écran partielle</string>
+ <string name="label_action_screenrecord">Capture vidéo</string>
+ <string name="label_action_expanded_desktop">Bureau étendu</string>
+ <string name="label_action_screen_off">Éteindre l\'écran</string>
+ <string name="label_action_force_close_app">Forcer l\'arrêt de l\'application</string>
+ <string name="label_action_search_assistant">Assistant de recherche</string>
+ <string name="label_action_google_now_on_tap">Google Now On Tap</string>
+ <string name="label_action_voice_search">Recherche vocale</string>
+ <string name="label_action_in_app_search">Recherche dans l\'application</string>
+ <string name="label_action_flashlight">Lampe de poche</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">Wi-Fi</string>
+ <string name="label_action_hotspot">Point d\'accès</string>
+ <string name="label_action_last_app">Application précédente</string>
+ <string name="label_action_overview">Vue des applications récentes</string>
+ <string name="label_action_power_menu">Menu Marche/Arrêt</string>
+ <string name="label_action_menu">Menu</string>
+ <string name="label_action_back">Retour</string>
+ <string name="label_action_home">Accueil</string>
+ <string name="label_action_ime_switcher">Sélecteur de clavier</string>
+ <string name="label_action_stop_screenpinning">Annuler l\'épinglage de l\'écran</string>
+ <string name="label_action_ime_down">Curseur bas</string>
+ <string name="label_action_ime_left">Curseur gauche</string>
+ <string name="label_action_ime_right">Curseur droit</string>
+ <string name="label_action_ime_up">Curseur haut</string>
+ <string name="label_action_volume_panel">Panneau de volume</string>
+ <string name="label_action_clear_notifications">Supprimer les notifications</string>
+ <string name="label_action_split_screen">Écran partagé</string>
+ <string name="label_action_one_handed_mode_left">Utilisation à une main (gaucher)</string>
+ <string name="label_action_one_handed_mode_right">Utilisation à une main (droitier)</string>
+ <string name="label_action_media_left">Titre précédent</string>
+ <string name="label_action_media_right">Titre suivant</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">Fermeture forcée de %s</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-fr/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-fr/custom_strings.xml
new file mode 100644
index 0000000..c34d803
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-fr/custom_strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Aucune action</string>
+ <string name="label_action_settings_panel">Volet des réglages rapides</string>
+ <string name="label_action_notification_panel">Panneau de notification</string>
+ <string name="label_action_screenshot">Capture d\'écran</string>
+ <string name="label_action_region_screenshot">Capture d’écran partielle</string>
+ <string name="label_action_screenrecord">Capture vidéo</string>
+ <string name="label_action_expanded_desktop">Bureau étendu</string>
+ <string name="label_action_screen_off">Éteindre l\'écran</string>
+ <string name="label_action_force_close_app">Forcer l\'arrêt de l\'application</string>
+ <string name="label_action_google_assistant">Assistant Google</string>
+ <string name="label_action_in_app_search">Recherche dans l\'application</string>
+ <string name="label_action_flashlight">Lampe de poche</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">Wi-Fi</string>
+ <string name="label_action_hotspot">Point d\'accès</string>
+ <string name="label_action_last_app">Application récente</string>
+ <string name="label_action_overview">Récent</string>
+ <string name="label_action_power_menu">Menu Marche/Arrêt</string>
+ <string name="label_action_menu">Menu</string>
+ <string name="label_action_back">Retour</string>
+ <string name="label_action_home">Accueil</string>
+ <string name="label_action_ime_switcher">Sélecteur de clavier</string>
+ <string name="label_action_stop_screenpinning">Annuler l\'épinglage de l\'écran</string>
+ <string name="label_action_ime_down">Curseur bas</string>
+ <string name="label_action_ime_left">Curseur gauche</string>
+ <string name="label_action_ime_right">Curseur droit</string>
+ <string name="label_action_ime_up">Curseur haut</string>
+ <string name="label_action_volume_panel">Panneau de volume</string>
+ <string name="label_action_clear_notifications">Supprimer les notifications</string>
+ <string name="label_action_split_screen">Écran partagé</string>
+ <string name="label_action_one_handed_mode_left">Utilisation à une main (côté gauche)</string>
+ <string name="label_action_one_handed_mode_right">Utilisation à une main (côté droit)</string>
+ <string name="label_action_media_left">Titre précédent</string>
+ <string name="label_action_media_right">Titre suivant</string>
+ <string name="label_action_assistant_sound_search">Google Reconnaissance vocale</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">Fermeture forcée de %s</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-fy-rNL/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-fy-rNL/custom_strings.xml
new file mode 100644
index 0000000..f64c1b3
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-fy-rNL/custom_strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-gd-rGB/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-gd-rGB/custom_strings.xml
new file mode 100644
index 0000000..751a9ee
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-gd-rGB/custom_strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_screenshot">Glacadh-sgrìn</string>
+ <string name="label_action_flashlight">An solas-boillsgidh</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-gl-rES/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-gl-rES/custom_strings.xml
new file mode 100644
index 0000000..9da6130
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-gl-rES/custom_strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Sen acción</string>
+ <string name="label_action_settings_panel">Panel de axustes</string>
+ <string name="label_action_notification_panel">Panel de notificacións</string>
+ <string name="label_action_screenshot">Captura de pantalla</string>
+ <string name="label_action_region_screenshot">Captura de pantalla parcial</string>
+ <string name="label_action_screenrecord">Gravar a pantalla</string>
+ <string name="label_action_expanded_desktop">Escritorio estendido</string>
+ <string name="label_action_screen_off">Apagar a pantalla</string>
+ <string name="label_action_force_close_app">Forzar peche da aplicación</string>
+ <string name="label_action_google_assistant">Asistente de Google</string>
+ <string name="label_action_in_app_search">Busqueda na aplicación</string>
+ <string name="label_action_flashlight">Lanterna</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Punto de acceso</string>
+ <string name="label_action_last_app">Última aplicación</string>
+ <string name="label_action_overview">Recentes</string>
+ <string name="label_action_power_menu">Menú de apagado</string>
+ <string name="label_action_menu">Menú</string>
+ <string name="label_action_back">Voltar</string>
+ <string name="label_action_home">Inicio</string>
+ <string name="label_action_ime_switcher">Trocador IME</string>
+ <string name="label_action_stop_screenpinning">Deter fixado de pantalla</string>
+ <string name="label_action_ime_down">Cursor de método de entrada abaixo</string>
+ <string name="label_action_ime_left">Cursor de método de entrada a esquerda</string>
+ <string name="label_action_ime_right">Cursor de método de entrada a dereita</string>
+ <string name="label_action_ime_up">Cursor de método de entrada arriba</string>
+ <string name="label_action_volume_panel">Panel de volume</string>
+ <string name="label_action_clear_notifications">Limpar as notificacións</string>
+ <string name="label_action_split_screen">Dividir a pantalla</string>
+ <string name="label_action_one_handed_mode_left">Modo a unha man (esquerda)</string>
+ <string name="label_action_one_handed_mode_right">Modo a unha man (dereita)</string>
+ <string name="label_action_media_left">Canción anterior</string>
+ <string name="label_action_media_right">Seguinte canción</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s detida</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-gu-rIN/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-gu-rIN/custom_strings.xml
new file mode 100644
index 0000000..07709ad
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-gu-rIN/custom_strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">કાર્યવાહી નથી</string>
+ <string name="label_action_settings_panel">સેટિંગ્સ પેનલ</string>
+ <string name="label_action_notification_panel">સૂચના પેનલ</string>
+ <string name="label_action_screenshot">સ્ક્રીનશોટ</string>
+ <string name="label_action_region_screenshot">અડધો સ્ક્રીનશોટ</string>
+ <string name="label_action_screenrecord">રેકોર્ડ સ્ક્રીન</string>
+ <string name="label_action_expanded_desktop">ડેસ્કટૉપ વિસ્તૃત કરો</string>
+ <string name="label_action_screen_off">સ્ક્રીન બંધ કરો</string>
+ <string name="label_action_force_close_app">એપ્લિકેશનને ફોર્સ બંધ કરો</string>
+ <string name="label_action_google_assistant">Google સહાય</string>
+ <string name="label_action_in_app_search">ઇન-એપ્લિકેશન શોધ</string>
+ <string name="label_action_flashlight">ફ્લેશલાઇટ</string>
+ <string name="label_action_bluetooth">બ્લુટૂથ</string>
+ <string name="label_action_wifi">વાઇફાઇ</string>
+ <string name="label_action_hotspot">હોટસ્પોટ</string>
+ <string name="label_action_last_app">છેલ્લી એપ્લિકેશન</string>
+ <string name="label_action_overview">તાજેતરના</string>
+ <string name="label_action_power_menu">પાવર મેનૂ</string>
+ <string name="label_action_menu">મેનુ</string>
+ <string name="label_action_back">પાછા જાઓ</string>
+ <string name="label_action_home">હોમ</string>
+ <string name="label_action_ime_switcher">ઈએમઆઈ બદલો</string>
+ <string name="label_action_stop_screenpinning">સ્ક્રીનને પિન કરવું રોકો</string>
+ <string name="label_action_ime_down">ઇનપુટ પદ્ધતિ કર્સર નીચે</string>
+ <string name="label_action_ime_left">ઇનપુટ પદ્ધતિ કર્સર ડાબે</string>
+ <string name="label_action_ime_right">ઇનપુટ પદ્ધતિ કર્સર જમણે</string>
+ <string name="label_action_ime_up">ઇનપુટ પદ્ધતિ કર્સર ઉપર</string>
+ <string name="label_action_volume_panel">વોલ્યુમ પેનલ</string>
+ <string name="label_action_clear_notifications">સૂચનાઓ સાફ કરો</string>
+ <string name="label_action_split_screen">સ્ક્રીન વિભાજીત કરો</string>
+ <string name="label_action_one_handed_mode_left">એક હાથે સ્થિતિ (ડાબી બાજુ)</string>
+ <string name="label_action_one_handed_mode_right">એક હાથે સ્થિતિ (જમણે બાજુ)</string>
+ <string name="label_action_media_left">ગત ટ્રેક</string>
+ <string name="label_action_media_right">આગામી ટ્રેક</string>
+ <string name="label_action_assistant_sound_search">Google સાઉન્ડ શોધ</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s killed</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-haw-rUS/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-haw-rUS/custom_strings.xml
new file mode 100644
index 0000000..f64c1b3
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-haw-rUS/custom_strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-hi-rIN/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-hi-rIN/custom_strings.xml
new file mode 100644
index 0000000..3d0848a
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-hi-rIN/custom_strings.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">कोई क्रिया नहीं</string>
+ <string name="label_action_settings_panel">सेटिंग्स पैनल</string>
+ <string name="label_action_notification_panel">सुचना पटल</string>
+ <string name="label_action_screenshot">स्क्रीनशॉट</string>
+ <string name="label_action_region_screenshot">आंशिक स्क्रीनशॉट</string>
+ <string name="label_action_screenrecord">रिकॉर्ड स्क्रीन</string>
+ <string name="label_action_expanded_desktop">विस्तारित डेस्कटॉप</string>
+ <string name="label_action_screen_off">स्क्रीन बंद</string>
+ <string name="label_action_force_close_app">बल अनुप्रयोग बंद करे</string>
+ <string name="label_action_search_assistant">खोज सहायक</string>
+ <string name="label_action_google_now_on_tap">अभी गूगल करें</string>
+ <string name="label_action_voice_search">आवाज से खोज</string>
+ <string name="label_action_in_app_search">इन-ऐप खोज</string>
+ <string name="label_action_flashlight">टॉर्च</string>
+ <string name="label_action_bluetooth">ब्लू टूथ</string>
+ <string name="label_action_wifi">वाईफ़ाई</string>
+ <string name="label_action_hotspot">हॉटस्पॉट</string>
+ <string name="label_action_last_app">पिछ्ला ऍप</string>
+ <string name="label_action_overview">हाल ही के</string>
+ <string name="label_action_power_menu">पावर मेनू</string>
+ <string name="label_action_menu">मेन्यू</string>
+ <string name="label_action_back">वापस जाएं</string>
+ <string name="label_action_home">होम</string>
+ <string name="label_action_ime_switcher">IME परिवर्तक</string>
+ <string name="label_action_stop_screenpinning">स्क्रीन पिनिंग रोके</string>
+ <string name="label_action_ime_down">इनपुट विधि कर्सर नीचे</string>
+ <string name="label_action_ime_left">इनपुट विधि कर्सर बाएं</string>
+ <string name="label_action_ime_right">इनपुट विधि कर्सर दाए</string>
+ <string name="label_action_ime_up">इनपुट विधि कर्सर ऊपर</string>
+ <string name="label_action_volume_panel">वॉल्यूम पैनल</string>
+ <string name="label_action_clear_notifications">सूचनाएं हटाए</string>
+ <string name="label_action_split_screen">विभाजित स्क्रीन</string>
+ <string name="label_action_one_handed_mode_left">एक हाथ मोड (बाईं ओर)</string>
+ <string name="label_action_one_handed_mode_right">एक हाथ मोड (दाईं ओर)</string>
+ <string name="label_action_media_left">पिछला ट्रैक</string>
+ <string name="label_action_media_right">अगला ट्रैक</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s बंद कर दिया</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-hi/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-hi/custom_strings.xml
new file mode 100644
index 0000000..50f8c38
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-hi/custom_strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">कोई क्रिया नहीं</string>
+ <string name="label_action_settings_panel">सेटिंग्स पैनल</string>
+ <string name="label_action_notification_panel">सुचना पटल</string>
+ <string name="label_action_screenshot">स्क्रीनशॉट</string>
+ <string name="label_action_region_screenshot">आंशिक स्क्रीनशॉट</string>
+ <string name="label_action_screenrecord">रिकॉर्ड स्क्रीन</string>
+ <string name="label_action_expanded_desktop">विस्तारित डेस्कटॉप</string>
+ <string name="label_action_screen_off">स्क्रीन बंद</string>
+ <string name="label_action_force_close_app">बल अनुप्रयोग बंद करे</string>
+ <string name="label_action_google_assistant">गूगल असिस्टेंट</string>
+ <string name="label_action_in_app_search">इन-ऐप खोज</string>
+ <string name="label_action_flashlight">टॉर्च</string>
+ <string name="label_action_bluetooth">ब्लू टूथ</string>
+ <string name="label_action_wifi">वाईफ़ाई</string>
+ <string name="label_action_hotspot">हॉटस्पॉट</string>
+ <string name="label_action_last_app">पिछ्ला ऍप</string>
+ <string name="label_action_overview">हाल ही के</string>
+ <string name="label_action_power_menu">पावर मेनू</string>
+ <string name="label_action_menu">मेन्यू</string>
+ <string name="label_action_back">वापस जाएं</string>
+ <string name="label_action_home">होम</string>
+ <string name="label_action_ime_switcher">IME परिवर्तक</string>
+ <string name="label_action_stop_screenpinning">स्क्रीन पिनिंग रोके</string>
+ <string name="label_action_ime_down">इनपुट विधि कर्सर नीचे</string>
+ <string name="label_action_ime_left">इनपुट विधि कर्सर बाएं</string>
+ <string name="label_action_ime_right">इनपुट विधि कर्सर दाए</string>
+ <string name="label_action_ime_up">इनपुट विधि कर्सर ऊपर</string>
+ <string name="label_action_volume_panel">वॉल्यूम पैनल</string>
+ <string name="label_action_clear_notifications">सूचनाएं हटाए</string>
+ <string name="label_action_split_screen">विभाजित स्क्रीन</string>
+ <string name="label_action_one_handed_mode_left">एक हाथ मोड (बाईं ओर)</string>
+ <string name="label_action_one_handed_mode_right">एक हाथ मोड (दाईं ओर)</string>
+ <string name="label_action_media_left">पिछला ट्रैक</string>
+ <string name="label_action_media_right">अगला ट्रैक</string>
+ <string name="label_action_assistant_sound_search">Google ध्वनि खोज</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s बंद कर दिया</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-hr-rHR/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-hr-rHR/custom_strings.xml
new file mode 100644
index 0000000..2b4a1f7
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-hr-rHR/custom_strings.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Bez radnje</string>
+ <string name="label_action_settings_panel">Ploča postavki</string>
+ <string name="label_action_notification_panel">Ploča obavijesti</string>
+ <string name="label_action_screenshot">Snimka zaslona</string>
+ <string name="label_action_region_screenshot">Djelomična snimka zaslona</string>
+ <string name="label_action_screenrecord">Snimanje zaslona</string>
+ <string name="label_action_expanded_desktop">Proširena radna površina</string>
+ <string name="label_action_screen_off">Isključi zaslon</string>
+ <string name="label_action_force_close_app">Prisilno zatvori aplikaciju</string>
+ <string name="label_action_search_assistant">Pomoćnik u pretraživanju</string>
+ <string name="label_action_google_now_on_tap">Google Now na dodir</string>
+ <string name="label_action_voice_search">Glasovno pretraživanje</string>
+ <string name="label_action_in_app_search">Pretraživanje u aplikaciji</string>
+ <string name="label_action_flashlight">Svjetiljka</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">Wi-Fi</string>
+ <string name="label_action_hotspot">Žarišna točka</string>
+ <string name="label_action_last_app">Zadnja aplikacija</string>
+ <string name="label_action_overview">Nedavne aplikacije</string>
+ <string name="label_action_power_menu">Izbornik napajanja</string>
+ <string name="label_action_menu">Izbornik</string>
+ <string name="label_action_back">Natrag</string>
+ <string name="label_action_home">Početna</string>
+ <string name="label_action_ime_switcher">Promjena načina unosa</string>
+ <string name="label_action_stop_screenpinning">Zaustavi prikvačivanje zaslona</string>
+ <string name="label_action_ime_down">Način unosa - strelica za dolje</string>
+ <string name="label_action_ime_left">Način unosa - strelica ulijevo</string>
+ <string name="label_action_ime_right">Način unosa - strelica udesno</string>
+ <string name="label_action_ime_up">Način unosa - strelica za gore</string>
+ <string name="label_action_volume_panel">Ploča glasnoće</string>
+ <string name="label_action_clear_notifications">Izbriši obavijesti</string>
+ <string name="label_action_split_screen">Podijeljeni zaslon</string>
+ <string name="label_action_one_handed_mode_left">Način rada jednom rukom (lijeva strana)</string>
+ <string name="label_action_one_handed_mode_right">Način rada jednom rukom (desna strana)</string>
+ <string name="label_action_media_left">Prethodna pjesma</string>
+ <string name="label_action_media_right">Sljedeća pjesma</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">Aplikacija %s je zaustavljena</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-hr/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-hr/custom_strings.xml
new file mode 100644
index 0000000..b949f49
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-hr/custom_strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Bez radnje</string>
+ <string name="label_action_settings_panel">Ploča postavki</string>
+ <string name="label_action_notification_panel">Ploča obavijesti</string>
+ <string name="label_action_screenshot">Snimka zaslona</string>
+ <string name="label_action_region_screenshot">Djelomična snimka zaslona</string>
+ <string name="label_action_screenrecord">Snimanje zaslona</string>
+ <string name="label_action_expanded_desktop">Proširena radna površina</string>
+ <string name="label_action_screen_off">Isključi zaslon</string>
+ <string name="label_action_force_close_app">Prisilno zatvori aplikaciju</string>
+ <string name="label_action_google_assistant">Google pomoćnik</string>
+ <string name="label_action_in_app_search">Pretraživanje u aplikaciji</string>
+ <string name="label_action_flashlight">Svjetiljka</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">Wi-Fi</string>
+ <string name="label_action_hotspot">Žarišna točka</string>
+ <string name="label_action_last_app">Zadnja aplikacija</string>
+ <string name="label_action_overview">Nedavne aplikacije</string>
+ <string name="label_action_power_menu">Izbornik napajanja</string>
+ <string name="label_action_menu">Izbornik</string>
+ <string name="label_action_back">Natrag</string>
+ <string name="label_action_home">Početna</string>
+ <string name="label_action_ime_switcher">Promjena načina unosa</string>
+ <string name="label_action_stop_screenpinning">Zaustavi prikvačivanje zaslona</string>
+ <string name="label_action_ime_down">Način unosa - strelica za dolje</string>
+ <string name="label_action_ime_left">Način unosa - strelica ulijevo</string>
+ <string name="label_action_ime_right">Način unosa - strelica udesno</string>
+ <string name="label_action_ime_up">Način unosa - strelica za gore</string>
+ <string name="label_action_volume_panel">Ploča glasnoće</string>
+ <string name="label_action_clear_notifications">Izbriši obavijesti</string>
+ <string name="label_action_split_screen">Podijeljeni zaslon</string>
+ <string name="label_action_one_handed_mode_left">Način rada jednom rukom (lijeva strana)</string>
+ <string name="label_action_one_handed_mode_right">Način rada jednom rukom (desna strana)</string>
+ <string name="label_action_media_left">Prethodna pjesma</string>
+ <string name="label_action_media_right">Sljedeća pjesma</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">Aplikacija %s je zaustavljena</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-hu-rHU/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-hu-rHU/custom_strings.xml
new file mode 100644
index 0000000..8a72beb
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-hu-rHU/custom_strings.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Nincs művelet</string>
+ <string name="label_action_settings_panel">Beállítások panel</string>
+ <string name="label_action_notification_panel">Értesítési panel</string>
+ <string name="label_action_screenshot">Képernyőmentés</string>
+ <string name="label_action_region_screenshot">Részleges képernyőmentés</string>
+ <string name="label_action_screenrecord">Képernyő felvétel</string>
+ <string name="label_action_expanded_desktop">Kiterjesztett képernyő</string>
+ <string name="label_action_screen_off">Képernyő kikapcsolása</string>
+ <string name="label_action_force_close_app">Alkalmazás kényszerített bezárása</string>
+ <string name="label_action_search_assistant">Keresési segéd</string>
+ <string name="label_action_google_now_on_tap">Google Now On Tap</string>
+ <string name="label_action_voice_search">Hangalapú keresés</string>
+ <string name="label_action_in_app_search">Alkalmazáson belüli keresés</string>
+ <string name="label_action_flashlight">Zseblámpa</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Hotspot</string>
+ <string name="label_action_last_app">Utolsó alkalmazás</string>
+ <string name="label_action_overview">Előzmények</string>
+ <string name="label_action_power_menu">Kikapcsoló menü</string>
+ <string name="label_action_menu">Menü</string>
+ <string name="label_action_back">Vissza</string>
+ <string name="label_action_home">Kezdőlap</string>
+ <string name="label_action_ime_switcher">Bill. váltó</string>
+ <string name="label_action_stop_screenpinning">Képernyő rögzítés feloldása</string>
+ <string name="label_action_ime_down">Beviteli mód - kurzor le</string>
+ <string name="label_action_ime_left">Beviteli mód - kurzor balra</string>
+ <string name="label_action_ime_right">Beviteli mód - kurzor jobbra</string>
+ <string name="label_action_ime_up">Beviteli mód - kurzor fel</string>
+ <string name="label_action_volume_panel">Hangerő panel</string>
+ <string name="label_action_clear_notifications">Értesítések törlése</string>
+ <string name="label_action_split_screen">Osztott képernyő</string>
+ <string name="label_action_one_handed_mode_left">Egykezes üzemmód (bal oldalon)</string>
+ <string name="label_action_one_handed_mode_right">Egykezes üzemmód (jobb oldalon)</string>
+ <string name="label_action_media_left">Előző szám</string>
+ <string name="label_action_media_right">Következő szám</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s kilőve</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-hu/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-hu/custom_strings.xml
new file mode 100644
index 0000000..2c07532
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-hu/custom_strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Nincs teendő</string>
+ <string name="label_action_settings_panel">Beállítások panel</string>
+ <string name="label_action_notification_panel">Értesítési panel</string>
+ <string name="label_action_screenshot">Képernyőmentés</string>
+ <string name="label_action_region_screenshot">Részleges képernyőmentés</string>
+ <string name="label_action_screenrecord">Képernyő felvétel</string>
+ <string name="label_action_expanded_desktop">Kiterjesztett képernyő</string>
+ <string name="label_action_screen_off">Képernyő kikapcsolása</string>
+ <string name="label_action_force_close_app">Alkalmazás kényszerített bezárása</string>
+ <string name="label_action_google_assistant">Google asszisztens</string>
+ <string name="label_action_in_app_search">Alkalmazáson belüli keresés</string>
+ <string name="label_action_flashlight">Zseblámpa</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Hotspot</string>
+ <string name="label_action_last_app">Utolsó alkalmazás</string>
+ <string name="label_action_overview">Előzmények</string>
+ <string name="label_action_power_menu">Kikapcsoló menü</string>
+ <string name="label_action_menu">Menü</string>
+ <string name="label_action_back">Vissza</string>
+ <string name="label_action_home">Kezdőlap</string>
+ <string name="label_action_ime_switcher">Bill. váltó</string>
+ <string name="label_action_stop_screenpinning">Képernyő rögzítés feloldása</string>
+ <string name="label_action_ime_down">Beviteli mód - kurzor le</string>
+ <string name="label_action_ime_left">Beviteli mód - kurzor balra</string>
+ <string name="label_action_ime_right">Beviteli mód - kurzor jobbra</string>
+ <string name="label_action_ime_up">Beviteli mód - kurzor fel</string>
+ <string name="label_action_volume_panel">Hangerő panel</string>
+ <string name="label_action_clear_notifications">Értesítések törlése</string>
+ <string name="label_action_split_screen">Osztott képernyő</string>
+ <string name="label_action_one_handed_mode_left">Egykezes üzemmód (bal oldalon)</string>
+ <string name="label_action_one_handed_mode_right">Egykezes üzemmód (jobb oldalon)</string>
+ <string name="label_action_media_left">Előző szám</string>
+ <string name="label_action_media_right">Következő szám</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s kilőve</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-hy-rAM/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-hy-rAM/custom_strings.xml
new file mode 100644
index 0000000..f64c1b3
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-hy-rAM/custom_strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-in-rID/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-in-rID/custom_strings.xml
new file mode 100644
index 0000000..bdcf57b
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-in-rID/custom_strings.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Tidak ada tindakan</string>
+ <string name="label_action_settings_panel">Panel setelan</string>
+ <string name="label_action_notification_panel">Panel pemberitahuan</string>
+ <string name="label_action_screenshot">Screenshot</string>
+ <string name="label_action_region_screenshot">Menangkap sebagian layar</string>
+ <string name="label_action_screenrecord">Rekam layar</string>
+ <string name="label_action_expanded_desktop">Desktop diperluas</string>
+ <string name="label_action_screen_off">Matikan layar</string>
+ <string name="label_action_force_close_app">Paksa tutup aplikasi</string>
+ <string name="label_action_search_assistant">Asisten pencarian</string>
+ <string name="label_action_google_now_on_tap">Google Now On Tap</string>
+ <string name="label_action_voice_search">Pencarian suara</string>
+ <string name="label_action_in_app_search">Pencarian di-app</string>
+ <string name="label_action_flashlight">Senter</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Hotspot</string>
+ <string name="label_action_last_app">Aplikasi terakhir</string>
+ <string name="label_action_overview">Terbaru</string>
+ <string name="label_action_power_menu">Menu daya</string>
+ <string name="label_action_menu">Menu</string>
+ <string name="label_action_back">Kembali</string>
+ <string name="label_action_home">Home</string>
+ <string name="label_action_ime_switcher">Pengganti IME</string>
+ <string name="label_action_stop_screenpinning">Berhenti menyemat layar</string>
+ <string name="label_action_ime_down">Metode masukan kursor ke bawah</string>
+ <string name="label_action_ime_left">Metode masukan kursor ke kiri</string>
+ <string name="label_action_ime_right">Metode masukan kursor ke kanan</string>
+ <string name="label_action_ime_up">Metode masukan kursor ke atas</string>
+ <string name="label_action_volume_panel">Panel volume</string>
+ <string name="label_action_clear_notifications">Bersihkan notifikasi</string>
+ <string name="label_action_split_screen">Pisah layar</string>
+ <string name="label_action_one_handed_mode_left">Mode satu tangan (sisi kiri)</string>
+ <string name="label_action_one_handed_mode_right">Mode satu tangan (sisi kanan)</string>
+ <string name="label_action_media_left">Trek sebelumnya</string>
+ <string name="label_action_media_right">Trek berikutnya</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s dimatikan</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-in/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-in/custom_strings.xml
new file mode 100644
index 0000000..50ed44f
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-in/custom_strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Tidak ada tindakan</string>
+ <string name="label_action_settings_panel">Panel Setelan Cepat</string>
+ <string name="label_action_notification_panel">Panel pemberitahuan</string>
+ <string name="label_action_screenshot">Tangkapan layar</string>
+ <string name="label_action_region_screenshot">Tangkapan layar sebagian</string>
+ <string name="label_action_screenrecord">Rekam layar</string>
+ <string name="label_action_expanded_desktop">Desktop diperluas</string>
+ <string name="label_action_screen_off">Matikan layar</string>
+ <string name="label_action_force_close_app">Paksa tutup aplikasi</string>
+ <string name="label_action_google_assistant">Asisten Google</string>
+ <string name="label_action_in_app_search">Pencarian di dalam aplikasi</string>
+ <string name="label_action_flashlight">Senter</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Hotspot</string>
+ <string name="label_action_last_app">Aplikasi terakhir</string>
+ <string name="label_action_overview">Terbaru</string>
+ <string name="label_action_power_menu">Menu tombol daya</string>
+ <string name="label_action_menu">Menu</string>
+ <string name="label_action_back">Kembali</string>
+ <string name="label_action_home">Home</string>
+ <string name="label_action_ime_switcher">Pengganti IME</string>
+ <string name="label_action_stop_screenpinning">Berhenti menyemat layar</string>
+ <string name="label_action_ime_down">Saat memasukan kursor dari bawah</string>
+ <string name="label_action_ime_left">Saat memasukan kursor dari kiri</string>
+ <string name="label_action_ime_right">Saat memasukan kursor dari kanan</string>
+ <string name="label_action_ime_up">Saat memasukan kursor dari atas</string>
+ <string name="label_action_volume_panel">Panel volume</string>
+ <string name="label_action_clear_notifications">Bersihkan pemberitahuan</string>
+ <string name="label_action_split_screen">Layar terpisah</string>
+ <string name="label_action_one_handed_mode_left">Modus satu tangan (sisi kiri)</string>
+ <string name="label_action_one_handed_mode_right">Modus satu tangan (sisi kanan)</string>
+ <string name="label_action_media_left">Trek sebelumnya</string>
+ <string name="label_action_media_right">Trek berikutnya</string>
+ <string name="label_action_assistant_sound_search">Pencarian suara Google</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s dimatikan</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-it-rIT/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-it-rIT/custom_strings.xml
new file mode 100644
index 0000000..82d853955
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-it-rIT/custom_strings.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Nessuna azione</string>
+ <string name="label_action_settings_panel">Pannello impostazioni</string>
+ <string name="label_action_notification_panel">Pannello notifiche</string>
+ <string name="label_action_screenshot">Screenshot</string>
+ <string name="label_action_region_screenshot">Screenshot parziale</string>
+ <string name="label_action_screenrecord">Registra schermo</string>
+ <string name="label_action_expanded_desktop">Schermo esteso</string>
+ <string name="label_action_screen_off">Spegni lo schermo</string>
+ <string name="label_action_force_close_app">Chiusura forzata app</string>
+ <string name="label_action_search_assistant">Assistente di ricerca</string>
+ <string name="label_action_google_now_on_tap">Google Now al tocco</string>
+ <string name="label_action_voice_search">Ricerca vocale</string>
+ <string name="label_action_in_app_search">Ricerca in app</string>
+ <string name="label_action_flashlight">Torcia</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Hotspot</string>
+ <string name="label_action_last_app">Ultima app</string>
+ <string name="label_action_overview">Recenti</string>
+ <string name="label_action_power_menu">Menù di spegnimento</string>
+ <string name="label_action_menu">Menù</string>
+ <string name="label_action_back">Indietro</string>
+ <string name="label_action_home">Home</string>
+ <string name="label_action_ime_switcher">Cambio metodo d\'immissione</string>
+ <string name="label_action_stop_screenpinning">Interrompi blocco sullo schermo</string>
+ <string name="label_action_ime_down">Cursore d\'inserimento verso il basso</string>
+ <string name="label_action_ime_left">Cursore d\'inserimento verso sinistra</string>
+ <string name="label_action_ime_right">Cursore d\'inserimento verso destra</string>
+ <string name="label_action_ime_up">Cursore d\'inserimento verso l\'alto</string>
+ <string name="label_action_volume_panel">Pannello volume</string>
+ <string name="label_action_clear_notifications">Cancella le notifiche</string>
+ <string name="label_action_split_screen">Dividi schermo</string>
+ <string name="label_action_one_handed_mode_left">Modalità a una mano (lato sinistro)</string>
+ <string name="label_action_one_handed_mode_right">Modalità a una mano (lato destro)</string>
+ <string name="label_action_media_left">Brano precedente</string>
+ <string name="label_action_media_right">Brano successivo</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s terminato</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-it/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-it/custom_strings.xml
new file mode 100644
index 0000000..744c7b0
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-it/custom_strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Nessuna azione</string>
+ <string name="label_action_settings_panel">Pannello impostazioni</string>
+ <string name="label_action_notification_panel">Pannello notifiche</string>
+ <string name="label_action_screenshot">Screenshot</string>
+ <string name="label_action_region_screenshot">Screenshot parziale</string>
+ <string name="label_action_screenrecord">Registra schermo</string>
+ <string name="label_action_expanded_desktop">Schermo esteso</string>
+ <string name="label_action_screen_off">Spegni lo schermo</string>
+ <string name="label_action_force_close_app">Chiusura forzata app</string>
+ <string name="label_action_google_assistant">Google assistant</string>
+ <string name="label_action_in_app_search">Ricerca in app</string>
+ <string name="label_action_flashlight">Torcia</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Hotspot</string>
+ <string name="label_action_last_app">Ultima app</string>
+ <string name="label_action_overview">Recenti</string>
+ <string name="label_action_power_menu">Menù di spegnimento</string>
+ <string name="label_action_menu">Menù</string>
+ <string name="label_action_back">Indietro</string>
+ <string name="label_action_home">Home</string>
+ <string name="label_action_ime_switcher">Cambio metodo d\'immissione</string>
+ <string name="label_action_stop_screenpinning">Interrompi blocco sullo schermo</string>
+ <string name="label_action_ime_down">Cursore d\'inserimento verso il basso</string>
+ <string name="label_action_ime_left">Cursore d\'inserimento verso sinistra</string>
+ <string name="label_action_ime_right">Cursore d\'inserimento verso destra</string>
+ <string name="label_action_ime_up">Cursore d\'inserimento verso l\'alto</string>
+ <string name="label_action_volume_panel">Pannello volume</string>
+ <string name="label_action_clear_notifications">Cancella le notifiche</string>
+ <string name="label_action_split_screen">Dividi schermo</string>
+ <string name="label_action_one_handed_mode_left">Modalità a una mano (lato sinistro)</string>
+ <string name="label_action_one_handed_mode_right">Modalità a una mano (lato destro)</string>
+ <string name="label_action_media_left">Brano precedente</string>
+ <string name="label_action_media_right">Brano successivo</string>
+ <string name="label_action_assistant_sound_search">Ricerca audio Google</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s terminato</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-iw-rIL/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-iw-rIL/custom_strings.xml
new file mode 100644
index 0000000..2fa4df4
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-iw-rIL/custom_strings.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">ללא פעולה</string>
+ <string name="label_action_settings_panel">הגדרות</string>
+ <string name="label_action_notification_panel">התראות</string>
+ <string name="label_action_screenshot">צילום מסך</string>
+ <string name="label_action_region_screenshot">צילום מסך חלקי</string>
+ <string name="label_action_screenrecord">הקלט מסך</string>
+ <string name="label_action_expanded_desktop">שולחן עבודה מורחב</string>
+ <string name="label_action_screen_off">כבה מסך</string>
+ <string name="label_action_force_close_app">אלץ סגירת אפליקציה</string>
+ <string name="label_action_search_assistant">עוזר חיפוש</string>
+ <string name="label_action_google_now_on_tap">גוגל עכשיו בלחיצה</string>
+ <string name="label_action_voice_search">חיפוש קולי</string>
+ <string name="label_action_in_app_search">חיפוש בתוך היישום</string>
+ <string name="label_action_flashlight">פנס</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">נקודה חמה</string>
+ <string name="label_action_last_app">מעבר ליישום אחרון</string>
+ <string name="label_action_overview">יישומים אחרונים</string>
+ <string name="label_action_power_menu">תפריט כיבוי</string>
+ <string name="label_action_menu">תפריט</string>
+ <string name="label_action_back">חזור</string>
+ <string name="label_action_home">בית</string>
+ <string name="label_action_ime_switcher">שינוי אמצעי קלט</string>
+ <string name="label_action_stop_screenpinning">הפסקת הצמדת מסך</string>
+ <string name="label_action_ime_down">שיטת קלט מצביע למטה</string>
+ <string name="label_action_ime_left">שיטת קלט מצביע שמאלה</string>
+ <string name="label_action_ime_right">שיטת קלט מצביע ימינה</string>
+ <string name="label_action_ime_up">שיטת קלט מצביע למעלה</string>
+ <string name="label_action_volume_panel">לוח עוצמת השמע</string>
+ <string name="label_action_clear_notifications">נקה את כל ההתראות</string>
+ <string name="label_action_split_screen">פיצול מסך</string>
+ <string name="label_action_one_handed_mode_left">מצב שימוש ביד אחד (צד שמאל)</string>
+ <string name="label_action_one_handed_mode_right">מצב שימוש ביד אחד (צד ימין)</string>
+ <string name="label_action_media_left">שיר קודם</string>
+ <string name="label_action_media_right">שיר הבא</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s נסגר</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-iw/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-iw/custom_strings.xml
new file mode 100644
index 0000000..9ee6b92
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-iw/custom_strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">ללא פעולה</string>
+ <string name="label_action_settings_panel">הגדרות</string>
+ <string name="label_action_notification_panel">התראות</string>
+ <string name="label_action_screenshot">צילום מסך</string>
+ <string name="label_action_region_screenshot">צילום מסך חלקי</string>
+ <string name="label_action_screenrecord">הקלט מסך</string>
+ <string name="label_action_expanded_desktop">שולחן עבודה מורחב</string>
+ <string name="label_action_screen_off">כבה מסך</string>
+ <string name="label_action_force_close_app">אלץ סגירת אפליקציה</string>
+ <string name="label_action_google_assistant">עוזרת קולית</string>
+ <string name="label_action_in_app_search">חיפוש בתוך היישום</string>
+ <string name="label_action_flashlight">פנס</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">נקודה חמה</string>
+ <string name="label_action_last_app">מעבר ליישום אחרון</string>
+ <string name="label_action_overview">יישומים אחרונים</string>
+ <string name="label_action_power_menu">תפריט כיבוי</string>
+ <string name="label_action_menu">תפריט</string>
+ <string name="label_action_back">חזור</string>
+ <string name="label_action_home">בית</string>
+ <string name="label_action_ime_switcher">שינוי אמצעי קלט</string>
+ <string name="label_action_stop_screenpinning">הפסקת הצמדת מסך</string>
+ <string name="label_action_ime_down">שיטת קלט מצביע למטה</string>
+ <string name="label_action_ime_left">שיטת קלט מצביע שמאלה</string>
+ <string name="label_action_ime_right">שיטת קלט מצביע ימינה</string>
+ <string name="label_action_ime_up">שיטת קלט מצביע למעלה</string>
+ <string name="label_action_volume_panel">לוח עוצמת השמע</string>
+ <string name="label_action_clear_notifications">נקה את כל ההתראות</string>
+ <string name="label_action_split_screen">פיצול מסך</string>
+ <string name="label_action_one_handed_mode_left">מצב שימוש ביד אחד (צד שמאל)</string>
+ <string name="label_action_one_handed_mode_right">מצב שימוש ביד אחד (צד ימין)</string>
+ <string name="label_action_media_left">שיר קודם</string>
+ <string name="label_action_media_right">שיר הבא</string>
+ <string name="label_action_assistant_sound_search">חיפוש קולי של גוגל</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s נסגר</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-ja-rJP/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-ja-rJP/custom_strings.xml
new file mode 100644
index 0000000..327c273
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-ja-rJP/custom_strings.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">行わない</string>
+ <string name="label_action_settings_panel">設定パネル</string>
+ <string name="label_action_notification_panel">通知パネル</string>
+ <string name="label_action_screenshot">スクリーンショット</string>
+ <string name="label_action_region_screenshot">範囲を選択してスクリーンショット</string>
+ <string name="label_action_screenrecord">画面を録画</string>
+ <string name="label_action_expanded_desktop">拡張デスクトップ</string>
+ <string name="label_action_screen_off">画面をオフにする</string>
+ <string name="label_action_force_close_app">アプリを強制終了</string>
+ <string name="label_action_search_assistant">検索アシスタント</string>
+ <string name="label_action_google_now_on_tap">Google Now On Tap</string>
+ <string name="label_action_voice_search">音声検索</string>
+ <string name="label_action_in_app_search">アプリ内検索</string>
+ <string name="label_action_flashlight">フラッシュライト</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">公衆無線LAN</string>
+ <string name="label_action_last_app">最後に使用したアプリ</string>
+ <string name="label_action_overview">最近</string>
+ <string name="label_action_power_menu">電源メニュー</string>
+ <string name="label_action_menu">メニュー</string>
+ <string name="label_action_back">戻る</string>
+ <string name="label_action_home">ホーム</string>
+ <string name="label_action_ime_switcher">IMEの変更</string>
+ <string name="label_action_stop_screenpinning">画面の固定を停止</string>
+ <string name="label_action_ime_down">カーソル下移動</string>
+ <string name="label_action_ime_left">カーソル左移動</string>
+ <string name="label_action_ime_right">カーソル右移動</string>
+ <string name="label_action_ime_up">カーソル上移動</string>
+ <string name="label_action_volume_panel">音量パネル</string>
+ <string name="label_action_clear_notifications">通知を消去</string>
+ <string name="label_action_split_screen">画面分割</string>
+ <string name="label_action_one_handed_mode_left">片手操作モード (左寄り)</string>
+ <string name="label_action_one_handed_mode_right">片手操作モード (右寄り)</string>
+ <string name="label_action_media_left">前のトラック</string>
+ <string name="label_action_media_right">次のトラック</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s を終了しました</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-ja/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-ja/custom_strings.xml
new file mode 100644
index 0000000..a2b998c
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-ja/custom_strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">何もしない</string>
+ <string name="label_action_settings_panel">クイック設定パネル</string>
+ <string name="label_action_notification_panel">通知パネル</string>
+ <string name="label_action_screenshot">スクリーンショット</string>
+ <string name="label_action_region_screenshot">範囲を選択してスクリーンショット</string>
+ <string name="label_action_screenrecord">画面を録画</string>
+ <string name="label_action_expanded_desktop">拡張デスクトップ</string>
+ <string name="label_action_screen_off">画面をオフにする</string>
+ <string name="label_action_force_close_app">アプリを強制終了</string>
+ <string name="label_action_google_assistant">Googleアシスタント</string>
+ <string name="label_action_in_app_search">アプリ内検索</string>
+ <string name="label_action_flashlight">フラッシュライト</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">公衆無線LAN</string>
+ <string name="label_action_last_app">最後に使用したアプリ</string>
+ <string name="label_action_overview">アプリ履歴</string>
+ <string name="label_action_power_menu">電源メニュー</string>
+ <string name="label_action_menu">メニュー</string>
+ <string name="label_action_back">戻る</string>
+ <string name="label_action_home">ホーム</string>
+ <string name="label_action_ime_switcher">IMEの変更</string>
+ <string name="label_action_stop_screenpinning">画面の固定を停止</string>
+ <string name="label_action_ime_down">カーソル下移動</string>
+ <string name="label_action_ime_left">カーソル左移動</string>
+ <string name="label_action_ime_right">カーソル右移動</string>
+ <string name="label_action_ime_up">カーソル上移動</string>
+ <string name="label_action_volume_panel">音量パネル</string>
+ <string name="label_action_clear_notifications">通知を消去</string>
+ <string name="label_action_split_screen">画面分割</string>
+ <string name="label_action_one_handed_mode_left">片手操作モード(左寄り)</string>
+ <string name="label_action_one_handed_mode_right">片手操作モード(右寄り)</string>
+ <string name="label_action_media_left">前のトラック</string>
+ <string name="label_action_media_right">次のトラック</string>
+ <string name="label_action_assistant_sound_search">Google音声検索</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s を終了しました</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-kab-rDZ/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-kab-rDZ/custom_strings.xml
new file mode 100644
index 0000000..2a7adbb
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-kab-rDZ/custom_strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Ulac tigawt</string>
+ <string name="label_action_settings_panel">Agalis n iɣewwaṛen</string>
+ <string name="label_action_notification_panel">Agalis n yilɣa</string>
+ <string name="label_action_screenshot">Tuṭṭfa n ugdil</string>
+ <string name="label_action_region_screenshot">Tuṭfa abruyan n wagdil </string>
+ <string name="label_action_screenrecord">Agdil n usekles</string>
+ <string name="label_action_expanded_desktop">Lbiru hrawen</string>
+ <string name="label_action_screen_off">Sens agdil</string>
+ <string name="label_action_force_close_app">Hettem aseḥbes n usnas</string>
+ <string name="label_action_google_assistant">Adhal n Google</string>
+ <string name="label_action_in_app_search">Anadi deg wasnas</string>
+ <string name="label_action_flashlight">Taftilt n lǧib</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Tineqiṭ n unekcum</string>
+ <string name="label_action_last_app">Asnas aneggaru</string>
+ <string name="label_action_overview">Isnasen ineggura</string>
+ <string name="label_action_power_menu">Umuɣ Tiddit/Asensi</string>
+ <string name="label_action_menu">Umuɣ</string>
+ <string name="label_action_back">Ar deffir</string>
+ <string name="label_action_home">Agdil agejdan</string>
+ <string name="label_action_ime_switcher">Imbeddel IME</string>
+ <string name="label_action_stop_screenpinning">Sefsex tawaṭfa n wagdil</string>
+ <string name="label_action_ime_down">Taḥnacaṭ s wadda</string>
+ <string name="label_action_ime_left">Taḥnacaṭ s azelmaḍ</string>
+ <string name="label_action_ime_right">Taḥnacaṭ s ayefus</string>
+ <string name="label_action_ime_up">Taḥnacaṭ ad asawen </string>
+ <string name="label_action_volume_panel">Agalis n ubleɣ</string>
+ <string name="label_action_clear_notifications">Sfeḍ ilɣa</string>
+ <string name="label_action_split_screen">Agdil yettwabḍa</string>
+ <string name="label_action_one_handed_mode_left">Aseqdec s yiwen ufus (azelmaḍ)</string>
+ <string name="label_action_one_handed_mode_right">Aseqdec s yiwen ufus (ayefus)</string>
+ <string name="label_action_media_left">Azwel amezwaru</string>
+ <string name="label_action_media_right">Azwel nniḍen</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">Imdel %s</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-kl-rGL/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-kl-rGL/custom_strings.xml
new file mode 100644
index 0000000..f64c1b3
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-kl-rGL/custom_strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-kn-rIN/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-kn-rIN/custom_strings.xml
new file mode 100644
index 0000000..2c5c8d8
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-kn-rIN/custom_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">ಯಾವುದೇ ಕ್ರಿಯೆ ಇಲ್ಲ</string>
+ <string name="label_action_notification_panel">ನೋಟಿಫಿಕೇಶನ್ ಫಲಕ</string>
+ <string name="label_action_screenshot">ಸ್ಕ್ರೀನ್ಶಾಟ್</string>
+ <string name="label_action_region_screenshot">ಭಾಗಶಃ/ಬೇಕಾಗಿರುವಸ್ಟು ಮಾತ್ರ ಸ್ಕ್ರೀನ್ಶಾಟ್</string>
+ <string name="label_action_screenrecord">ಸ್ಕ್ರೀನ್ರೆ ಕಾರ್ಡ್ ಮಾಡಿ</string>
+ <string name="label_action_expanded_desktop">ವಿಸ್ತೃತ ಡೆಸ್ಕ್ಟಾಪ್</string>
+ <string name="label_action_screen_off">ಸ್ಕ್ರೀನ್ರೆ ಆಫ್ ಮಾಡಿ</string>
+ <string name="label_action_force_close_app">ಅಪ್ಲಿಕೇಶನ್ ಪೂರ್ಣವಾಗಿ ಒತ್ತಾಯಿಸಿ ಮುಚ್ಚಿ</string>
+ <string name="label_action_google_assistant">ಧ್ವನಿ ಸಹಾಯಕ</string>
+ <string name="label_action_in_app_search">ಇನ್-ಅಪ್ಲಿಕೇಶನ್ ಸರ್ಚ್</string>
+ <string name="label_action_flashlight">ಫ್ಲಾಶ್ ಬೆಳಕು</string>
+ <string name="label_action_bluetooth">ಬ್ಲೂಟೂತ್</string>
+ <string name="label_action_wifi">ವೈಫೈ</string>
+ <string name="label_action_hotspot">ಹಾಟ್ಸ್ಪಾಟ್</string>
+ <string name="label_action_last_app">ಕೊನೆಯ ಅಪ್ಲಿಕೇಶನ್</string>
+ <string name="label_action_overview">ರಿಸೆಂಟ್</string>
+ <string name="label_action_power_menu">ಪವರ್ ಮೆನು</string>
+ <string name="label_action_menu">ಮೆನು</string>
+ <string name="label_action_back">ಹಿಂದೆ</string>
+ <string name="label_action_home">ಮುಖಪುಟ</string>
+ <string name="label_action_volume_panel">ವಾಲ್ಯೂಂ ಪ್ಯಾನೆಲ್</string>
+ <string name="label_action_clear_notifications">ಪ್ರಕಟಣೆಗಳನ್ನು ತೆರವುಗೊಳಿಸಿ</string>
+ <string name="label_action_split_screen">ಸೀಳು ಪರದೆ</string>
+ <string name="label_action_one_handed_mode_left">ಒಂದು ಕೈಯ ಮೋಡ್ (ಎಡಭಾಗ)</string>
+ <string name="label_action_one_handed_mode_right">ಒಂದು ಕೈಯ ಮೋಡ್ (ಬಲಭಾಗ)</string>
+ <string name="label_action_media_left">ಹಿಂದಿನ ಹಾಡು</string>
+ <string name="label_action_media_right">ಮುಂದಿನ ಹಾಡು</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s ಮುಚ್ಚಲಾಗಿದೆ</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-ko-rKR/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-ko-rKR/custom_strings.xml
new file mode 100644
index 0000000..36967ea
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-ko-rKR/custom_strings.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">동작 없음</string>
+ <string name="label_action_settings_panel">설정 패널</string>
+ <string name="label_action_notification_panel">알림 패널</string>
+ <string name="label_action_screenshot">스크린샷</string>
+ <string name="label_action_region_screenshot">부분 스크린샷</string>
+ <string name="label_action_screenrecord">화면 녹화</string>
+ <string name="label_action_expanded_desktop">확장 데스크탑</string>
+ <string name="label_action_screen_off">화면 끄기</string>
+ <string name="label_action_force_close_app">앱 강제종료</string>
+ <string name="label_action_search_assistant">검색 도우미</string>
+ <string name="label_action_google_now_on_tap">구글 나우 온 탭</string>
+ <string name="label_action_voice_search">음성 검색</string>
+ <string name="label_action_in_app_search">앱 내 검색</string>
+ <string name="label_action_flashlight">손전등</string>
+ <string name="label_action_bluetooth">블루투스</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">핫스팟</string>
+ <string name="label_action_last_app">마지막으로 사용한 앱</string>
+ <string name="label_action_overview">최근 실행 목록</string>
+ <string name="label_action_power_menu">전원 메뉴</string>
+ <string name="label_action_menu">메뉴</string>
+ <string name="label_action_back">뒤로가기</string>
+ <string name="label_action_home">홈</string>
+ <string name="label_action_ime_switcher">IME 체인저</string>
+ <string name="label_action_stop_screenpinning">화면 고정 중지</string>
+ <string name="label_action_ime_down">입력 방법 커서를 아래로 내림</string>
+ <string name="label_action_ime_left">입력 커서를 왼쪽으로 이동</string>
+ <string name="label_action_ime_right">입력 커서를 오른쪽으로 이동</string>
+ <string name="label_action_ime_up">입력 커서를 위로 올림</string>
+ <string name="label_action_volume_panel">볼륨 패널</string>
+ <string name="label_action_clear_notifications">알림 지우기</string>
+ <string name="label_action_split_screen">화면 분할</string>
+ <string name="label_action_one_handed_mode_left">한손모드(왼쪽)</string>
+ <string name="label_action_one_handed_mode_right">한손모드(오른쪽)</string>
+ <string name="label_action_media_left">이전 트랙</string>
+ <string name="label_action_media_right">다음 트랙</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s 종료됨</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-ko/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-ko/custom_strings.xml
new file mode 100644
index 0000000..cd663be
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-ko/custom_strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">동작 없음</string>
+ <string name="label_action_settings_panel">빠른 설정 패널</string>
+ <string name="label_action_notification_panel">알림 패널</string>
+ <string name="label_action_screenshot">스크린샷</string>
+ <string name="label_action_region_screenshot">부분 스크린샷</string>
+ <string name="label_action_screenrecord">화면 녹화</string>
+ <string name="label_action_expanded_desktop">확장 데스크탑</string>
+ <string name="label_action_screen_off">화면 끄기</string>
+ <string name="label_action_force_close_app">앱 강제종료</string>
+ <string name="label_action_google_assistant">Google 어시스턴트</string>
+ <string name="label_action_in_app_search">앱에서 검색</string>
+ <string name="label_action_flashlight">손전등</string>
+ <string name="label_action_bluetooth">블루투스</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">핫스팟</string>
+ <string name="label_action_last_app">마지막에 사용한 앱</string>
+ <string name="label_action_overview">최근 실행 목록</string>
+ <string name="label_action_power_menu">전원 메뉴</string>
+ <string name="label_action_menu">메뉴</string>
+ <string name="label_action_back">뒤로가기</string>
+ <string name="label_action_home">홈</string>
+ <string name="label_action_ime_switcher">IME 체인저</string>
+ <string name="label_action_stop_screenpinning">화면 고정 중지</string>
+ <string name="label_action_ime_down">입력 커서 아래로</string>
+ <string name="label_action_ime_left">입력 커서 왼쪽으로</string>
+ <string name="label_action_ime_right">입력 커서 오른쪽으로</string>
+ <string name="label_action_ime_up">입력 커서 위로</string>
+ <string name="label_action_volume_panel">볼륨 패널</string>
+ <string name="label_action_clear_notifications">알림 지우기</string>
+ <string name="label_action_split_screen">화면 분할</string>
+ <string name="label_action_one_handed_mode_left">한손모드(왼쪽)</string>
+ <string name="label_action_one_handed_mode_right">한손모드(오른쪽)</string>
+ <string name="label_action_media_left">이전 트랙</string>
+ <string name="label_action_media_right">다음 트랙</string>
+ <string name="label_action_assistant_sound_search">Google 음성 검색</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s 종료됨</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-lb/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-lb/custom_strings.xml
new file mode 100644
index 0000000..f64c1b3
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-lb/custom_strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-lt-rLT/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-lt-rLT/custom_strings.xml
new file mode 100644
index 0000000..f64c1b3
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-lt-rLT/custom_strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-lt/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-lt/custom_strings.xml
new file mode 100644
index 0000000..f64c1b3
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-lt/custom_strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-lv-rLV/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-lv-rLV/custom_strings.xml
new file mode 100644
index 0000000..f64c1b3
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-lv-rLV/custom_strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-lv/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-lv/custom_strings.xml
new file mode 100644
index 0000000..ac08872
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-lv/custom_strings.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Nav darbība</string>
+ <string name="label_action_notification_panel">Paziņojumu vadība</string>
+ <string name="label_action_screenshot">Ekrānuzņēmums</string>
+ <string name="label_action_screenrecord">Ierakstīt ekrānu</string>
+ <string name="label_action_expanded_desktop">Paplašināta darbvirsma</string>
+ <string name="label_action_screen_off">Izslēgt ekrānu</string>
+ <string name="label_action_force_close_app">Piespiedu apturēšana</string>
+ <string name="label_action_google_assistant">Google palīgs</string>
+ <string name="label_action_in_app_search">Meklēšana lietotnē</string>
+ <string name="label_action_flashlight">Lukturītis</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Tīklājs</string>
+ <string name="label_action_last_app">Pēdējā lietotne</string>
+ <string name="label_action_overview">Nesenie</string>
+ <string name="label_action_power_menu">Barošanas izvēlne</string>
+ <string name="label_action_menu">Izvēlne</string>
+ <string name="label_action_back">Atpakaļ</string>
+ <string name="label_action_home">Sākums</string>
+ <string name="label_action_ime_switcher">IME mainītājs</string>
+ <string name="label_action_volume_panel">Skaņas izvelne</string>
+ <string name="label_action_clear_notifications">Notīrīt paziņojumus</string>
+ <string name="label_action_split_screen">Dalīt ekrānu</string>
+ <string name="label_action_one_handed_mode_left">Vienas rokas režīms (kreisā puse)</string>
+ <string name="label_action_one_handed_mode_right">Vienas rokas režīms (labā puse)</string>
+ <string name="label_action_media_left">Iepriekšējā dziesma</string>
+ <string name="label_action_media_right">Nākamā dziesma</string>
+ <string name="label_action_assistant_sound_search">Google skaņas meklētājs</string>
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-ml-rIN/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-ml-rIN/custom_strings.xml
new file mode 100644
index 0000000..418642f
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-ml-rIN/custom_strings.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">ഒന്നും ചെയ്യാനില്ല</string>
+ <string name="label_action_screenshot">സ്ക്രീൻഷോട്ട്</string>
+ <string name="label_action_region_screenshot">ഭാഗികമായ സ്ക്രീൻഷോട്ട്</string>
+ <string name="label_action_screenrecord">സ്ക്രീൻ റെക്കോർഡ് ചെയ്യുക</string>
+ <string name="label_action_expanded_desktop">വികസിച്ച ഡെസ്ക്ടോപ്പ്</string>
+ <string name="label_action_screen_off">സ്ക്രീൻ ഓഫ് ചെയ്യുക</string>
+ <string name="label_action_force_close_app">ബലമായി ആപ്പ് നിർത്തുക</string>
+ <string name="label_action_google_assistant">ഗൂഗിൾ സഹായി</string>
+ <string name="label_action_in_app_search">ആപ്പിനുള്ളിൽ തിരയുക</string>
+ <string name="label_action_flashlight">ടോർച്ച്</string>
+ <string name="label_action_bluetooth">ബ്ലൂടൂത്ത്</string>
+ <string name="label_action_wifi">വൈഫൈ</string>
+ <string name="label_action_hotspot">ഹോട്ട്സ്പോട്ട്</string>
+ <string name="label_action_last_app">അവസാന ആപ്പ്</string>
+ <string name="label_action_overview">അവസാനം ഉപയോഗിച്ചവ</string>
+ <string name="label_action_power_menu">പവർ മെനു</string>
+ <string name="label_action_menu">മെനു</string>
+ <string name="label_action_back">തിരികെ</string>
+ <string name="label_action_home">ഹോം</string>
+ <string name="label_action_ime_switcher">IME മാറ്റുക</string>
+ <string name="label_action_stop_screenpinning">സ്ക്രീൻ പിൻ ഓഫ് ചെയ്യുക</string>
+ <string name="label_action_volume_panel">വോളിയം പാനൽ</string>
+ <string name="label_action_clear_notifications">അറിയിപ്പുകൾ മാറ്റുക</string>
+ <string name="label_action_split_screen">സ്ക്രീൻ പകുത്തെടുക്കുക</string>
+ <string name="label_action_one_handed_mode_left">ഇടതു കയ്യാൽ മാത്രം ഉപയോഗിക്കാം</string>
+ <string name="label_action_one_handed_mode_right">വലതു കയ്യാൽ മാത്രം ഉപയോഗിക്കാം</string>
+ <string name="label_action_media_left">കഴിഞ്ഞു പോയ ഗാനം</string>
+ <string name="label_action_media_right">അടുത്ത ഗാനം</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s അവസാനിച്ചു</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-mr-rIN/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-mr-rIN/custom_strings.xml
new file mode 100644
index 0000000..2976cec
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-mr-rIN/custom_strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">कृतीविना</string>
+ <string name="label_action_settings_panel">क्यु एस पॅनेल</string>
+ <string name="label_action_notification_panel">नोतिफ़िकेशन पेनेल</string>
+ <string name="label_action_screenshot">स्क्रीनशॉट</string>
+ <string name="label_action_region_screenshot">अर्धवट स्क्रीनशॉट</string>
+ <string name="label_action_screenrecord">स्क्रीन रेकोर्ड</string>
+ <string name="label_action_expanded_desktop">विस्तृत केलेले डेस्कटॉप</string>
+ <string name="label_action_screen_off">स्क्रीन बंद करा</string>
+ <string name="label_action_force_close_app">अॅप सक्तीने बंद करा</string>
+ <string name="label_action_google_assistant">गुगल सहाय्यक</string>
+ <string name="label_action_in_app_search">अॅप-मधील शोध</string>
+ <string name="label_action_flashlight">फ्लॅशलाइट</string>
+ <string name="label_action_bluetooth">ब्लुटुथ</string>
+ <string name="label_action_wifi">वाय फ़ाय</string>
+ <string name="label_action_hotspot">हॉटस्पॉट</string>
+ <string name="label_action_last_app">शेवट्चे अॅप</string>
+ <string name="label_action_overview">रिसेन्ट</string>
+ <string name="label_action_power_menu">पॉवर मेनू</string>
+ <string name="label_action_menu">मेनू</string>
+ <string name="label_action_back">मागे</string>
+ <string name="label_action_home">घर</string>
+ <string name="label_action_ime_switcher">आय एम इ बदल</string>
+ <string name="label_action_stop_screenpinning">स्क्रीन पिन करणे थांबवा</string>
+ <string name="label_action_ime_down">इनपुट पद्धत कर्सर खाली</string>
+ <string name="label_action_ime_left">इनपुट पद्धत कर्सर डविकडे</string>
+ <string name="label_action_ime_right">इनपुट पद्धत कर्सर उजविकडे</string>
+ <string name="label_action_ime_up">इनपुट पद्धत कर्सर वर</string>
+ <string name="label_action_volume_panel">व्हॉल्यूम पॅनेल</string>
+ <string name="label_action_clear_notifications">नोटिफ़िकेशन साफ करा</string>
+ <string name="label_action_split_screen">स्प्लिट स्क्रीन</string>
+ <string name="label_action_one_handed_mode_left">एक हाताने मोड (डावी बाजू)</string>
+ <string name="label_action_one_handed_mode_right">एक हाताने मोड (उजवी बाजू)</string>
+ <string name="label_action_media_left">मागील ट्रॅक</string>
+ <string name="label_action_media_right">पुढील ट्रॅक</string>
+ <string name="label_action_assistant_sound_search">Google ध्वनी शोध</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s ब्न्द केले</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-ms-rMY/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-ms-rMY/custom_strings.xml
new file mode 100644
index 0000000..cc010e8
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-ms-rMY/custom_strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Tiada tindakan</string>
+ <string name="label_action_settings_panel">Panel QS</string>
+ <string name="label_action_notification_panel">Panel notifikasi</string>
+ <string name="label_action_screenshot">Screenshot</string>
+ <string name="label_action_region_screenshot">Screenshot separa</string>
+ <string name="label_action_screenrecord">Rakam skrin</string>
+ <string name="label_action_expanded_desktop">Desktop diperluaskan</string>
+ <string name="label_action_screen_off">Matikan skrin</string>
+ <string name="label_action_force_close_app">Paksa tutup aplikasi</string>
+ <string name="label_action_google_assistant">Google assistant</string>
+ <string name="label_action_in_app_search">Carian dalam aplikasi</string>
+ <string name="label_action_flashlight">Lampu suluh</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Hotspot</string>
+ <string name="label_action_last_app">Aplikasi terakhir</string>
+ <string name="label_action_overview">Terdahulu</string>
+ <string name="label_action_power_menu">Menu kuasa</string>
+ <string name="label_action_menu">Menu</string>
+ <string name="label_action_back">Kembali</string>
+ <string name="label_action_home">Skrin utama</string>
+ <string name="label_action_ime_switcher">Pengurup IME</string>
+ <string name="label_action_stop_screenpinning">Hentikan screen pinning</string>
+ <string name="label_action_ime_down">Kaedah input kursor turun</string>
+ <string name="label_action_ime_left">Kaedah input kursor kiri</string>
+ <string name="label_action_ime_right">Kaedah input kursor kanan</string>
+ <string name="label_action_ime_up">Kaedah input kursor atas</string>
+ <string name="label_action_volume_panel">Panel Suara</string>
+ <string name="label_action_clear_notifications">Padam notifikasi</string>
+ <string name="label_action_split_screen">Split screen</string>
+ <string name="label_action_one_handed_mode_left">Mod satu tangan (sebelah kiri)</string>
+ <string name="label_action_one_handed_mode_right">Mod satu tangan (sebelah kanan)</string>
+ <string name="label_action_media_left">Trek sebelumnya</string>
+ <string name="label_action_media_right">Trek kemudian</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s dimatikan</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-my-rMM/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-my-rMM/custom_strings.xml
new file mode 100644
index 0000000..f64c1b3
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-my-rMM/custom_strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-nb-rNO/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-nb-rNO/custom_strings.xml
new file mode 100644
index 0000000..df25687
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-nb-rNO/custom_strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_flashlight">Blitz</string>
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-nb/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-nb/custom_strings.xml
new file mode 100644
index 0000000..df25687
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-nb/custom_strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_flashlight">Blitz</string>
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-ne-rNP/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-ne-rNP/custom_strings.xml
new file mode 100644
index 0000000..f64c1b3
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-ne-rNP/custom_strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-nl-rNL/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-nl-rNL/custom_strings.xml
new file mode 100644
index 0000000..56bf539
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-nl-rNL/custom_strings.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Geen actie</string>
+ <string name="label_action_settings_panel">Instellingenpaneel</string>
+ <string name="label_action_notification_panel">Notificatie paneel</string>
+ <string name="label_action_screenshot">Schermafbeelding</string>
+ <string name="label_action_region_screenshot">Gedeeltelijke schermafbeelding</string>
+ <string name="label_action_screenrecord">Scherm opnemen</string>
+ <string name="label_action_expanded_desktop">Uitgebreid bureaublad</string>
+ <string name="label_action_screen_off">Scherm uitzetten</string>
+ <string name="label_action_force_close_app">App geforceerd afsluiten</string>
+ <string name="label_action_search_assistant">Zoek assistent</string>
+ <string name="label_action_google_now_on_tap">Google Now On Tap</string>
+ <string name="label_action_voice_search">Spraakgestuurd zoeken</string>
+ <string name="label_action_in_app_search">In-app zoeken</string>
+ <string name="label_action_flashlight">Zaklamp</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Hotspot</string>
+ <string name="label_action_last_app">Laatste app</string>
+ <string name="label_action_overview">Recente apps</string>
+ <string name="label_action_power_menu">Aan-/uit menu</string>
+ <string name="label_action_menu">Menu</string>
+ <string name="label_action_back">Terug</string>
+ <string name="label_action_home">Thuis</string>
+ <string name="label_action_ime_switcher">Invoermethode</string>
+ <string name="label_action_stop_screenpinning">Stop met scherm vastzetten</string>
+ <string name="label_action_ime_down">Invoermethode cursor omlaag</string>
+ <string name="label_action_ime_left">Invoermethode cursor links</string>
+ <string name="label_action_ime_right">Invoermethode cursor rechts</string>
+ <string name="label_action_ime_up">Invoermethode cursor omhoog</string>
+ <string name="label_action_volume_panel">Volume paneel</string>
+ <string name="label_action_clear_notifications">Meldingen wissen</string>
+ <string name="label_action_split_screen">Scherm opsplitsen</string>
+ <string name="label_action_one_handed_mode_left">Éen hand modus (linker kant)</string>
+ <string name="label_action_one_handed_mode_right">Éen hand modus (rechter kant)</string>
+ <string name="label_action_media_left">Vorig nummer</string>
+ <string name="label_action_media_right">Volgende nummer</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s afgesloten</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-nl/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-nl/custom_strings.xml
new file mode 100644
index 0000000..7154d3e
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-nl/custom_strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Geen actie</string>
+ <string name="label_action_settings_panel">Instellingenpaneel</string>
+ <string name="label_action_notification_panel">Notificatie paneel</string>
+ <string name="label_action_screenshot">Schermafbeelding</string>
+ <string name="label_action_region_screenshot">Gedeeltelijke schermafbeelding</string>
+ <string name="label_action_screenrecord">Scherm opnemen</string>
+ <string name="label_action_expanded_desktop">Uitgebreid bureaublad</string>
+ <string name="label_action_screen_off">Scherm uitzetten</string>
+ <string name="label_action_force_close_app">App geforceerd afsluiten</string>
+ <string name="label_action_google_assistant">Google Assistant</string>
+ <string name="label_action_in_app_search">In-app zoeken</string>
+ <string name="label_action_flashlight">Zaklamp</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Hotspot</string>
+ <string name="label_action_last_app">Laatste app</string>
+ <string name="label_action_overview">Recente apps</string>
+ <string name="label_action_power_menu">Aan-/uit menu</string>
+ <string name="label_action_menu">Menu</string>
+ <string name="label_action_back">Terug</string>
+ <string name="label_action_home">Thuis</string>
+ <string name="label_action_ime_switcher">Invoermethode</string>
+ <string name="label_action_stop_screenpinning">Stop met scherm vastzetten</string>
+ <string name="label_action_ime_down">Invoermethode cursor omlaag</string>
+ <string name="label_action_ime_left">Invoermethode cursor links</string>
+ <string name="label_action_ime_right">Invoermethode cursor rechts</string>
+ <string name="label_action_ime_up">Invoermethode cursor omhoog</string>
+ <string name="label_action_volume_panel">Volume paneel</string>
+ <string name="label_action_clear_notifications">Meldingen wissen</string>
+ <string name="label_action_split_screen">Scherm opsplitsen</string>
+ <string name="label_action_one_handed_mode_left">Éen hand modus (linker kant)</string>
+ <string name="label_action_one_handed_mode_right">Éen hand modus (rechter kant)</string>
+ <string name="label_action_media_left">Vorig nummer</string>
+ <string name="label_action_media_right">Volgende nummer</string>
+ <string name="label_action_assistant_sound_search">Google muziek zoeken</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s afgesloten</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-no-rNO/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-no-rNO/custom_strings.xml
new file mode 100644
index 0000000..df25687
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-no-rNO/custom_strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_flashlight">Blitz</string>
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-or-rIN/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-or-rIN/custom_strings.xml
new file mode 100644
index 0000000..f64c1b3
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-or-rIN/custom_strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-pl-rPL/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-pl-rPL/custom_strings.xml
new file mode 100644
index 0000000..91705f9
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-pl-rPL/custom_strings.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Brak akcji</string>
+ <string name="label_action_settings_panel">Panel ustawień</string>
+ <string name="label_action_notification_panel">Panel powiadomień</string>
+ <string name="label_action_screenshot">Zrzut ekranu</string>
+ <string name="label_action_region_screenshot">Częściowy zrzut ekranu</string>
+ <string name="label_action_screenrecord">Nagrywanie ekranu</string>
+ <string name="label_action_expanded_desktop">Rozszerzony pulpit</string>
+ <string name="label_action_screen_off">Wyłączanie ekranu</string>
+ <string name="label_action_force_close_app">Wymuś zamknięcie aplikacji</string>
+ <string name="label_action_search_assistant">Asystent wyszukiwania</string>
+ <string name="label_action_google_now_on_tap">Google Now On Tap</string>
+ <string name="label_action_voice_search">Wyszukiwanie głosowe</string>
+ <string name="label_action_in_app_search">Wyszukiwanie w aplikacji</string>
+ <string name="label_action_flashlight">Latarka</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Hotspot</string>
+ <string name="label_action_last_app">Ostatnia aplikacja</string>
+ <string name="label_action_overview">Ostatnie</string>
+ <string name="label_action_power_menu">Menu zasilania</string>
+ <string name="label_action_menu">Menu</string>
+ <string name="label_action_back">Wstecz</string>
+ <string name="label_action_home">Strona główna</string>
+ <string name="label_action_ime_switcher">Zmiana metody wprowadzania</string>
+ <string name="label_action_stop_screenpinning">Zatrzymaj przypinanie ekranu</string>
+ <string name="label_action_ime_down">Metoda wprowadzania kursor w dół</string>
+ <string name="label_action_ime_left">Metoda wprowadzania kursor w lewo</string>
+ <string name="label_action_ime_right">Metoda wprowadzania kursor w prawo</string>
+ <string name="label_action_ime_up">Metoda wprowadzania kursor w górę</string>
+ <string name="label_action_volume_panel">Panel głośności</string>
+ <string name="label_action_clear_notifications">Wyczyść powiadomienia</string>
+ <string name="label_action_split_screen">Podzielony ekran</string>
+ <string name="label_action_one_handed_mode_left">Tryb jednej ręki (lewa strona)</string>
+ <string name="label_action_one_handed_mode_right">Tryb jednej ręki (prawa strona)</string>
+ <string name="label_action_media_left">Poprzedni utwór</string>
+ <string name="label_action_media_right">Następny utwór</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s zabitych</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-pl/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-pl/custom_strings.xml
new file mode 100644
index 0000000..ba34d59
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-pl/custom_strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Brak akcji</string>
+ <string name="label_action_settings_panel">Panel ustawień</string>
+ <string name="label_action_notification_panel">Panel powiadomień</string>
+ <string name="label_action_screenshot">Zrzut ekranu</string>
+ <string name="label_action_region_screenshot">Częściowy zrzut ekranu</string>
+ <string name="label_action_screenrecord">Nagrywanie ekranu</string>
+ <string name="label_action_expanded_desktop">Rozszerzony pulpit</string>
+ <string name="label_action_screen_off">Wyłącz ekran</string>
+ <string name="label_action_force_close_app">Wymuś zamknięcie aplikacji</string>
+ <string name="label_action_google_assistant">Asystent Google</string>
+ <string name="label_action_in_app_search">Wyszukiwanie w aplikacji</string>
+ <string name="label_action_flashlight">Latarka</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Punkt dostępu</string>
+ <string name="label_action_last_app">Ostatnia aplikacja</string>
+ <string name="label_action_overview">Ostatnie</string>
+ <string name="label_action_power_menu">Menu zasilania</string>
+ <string name="label_action_menu">Menu</string>
+ <string name="label_action_back">Wstecz</string>
+ <string name="label_action_home">Strona główna</string>
+ <string name="label_action_ime_switcher">Zmiana metody wprowadzania</string>
+ <string name="label_action_stop_screenpinning">Zatrzymaj przypinanie ekranu</string>
+ <string name="label_action_ime_down">Metoda wprowadzania kursor w dół</string>
+ <string name="label_action_ime_left">Metoda wprowadzania kursor w lewo</string>
+ <string name="label_action_ime_right">Metoda wprowadzania kursor w prawo</string>
+ <string name="label_action_ime_up">Metoda wprowadzania kursor w górę</string>
+ <string name="label_action_volume_panel">Panel głośności</string>
+ <string name="label_action_clear_notifications">Wyczyść powiadomienia</string>
+ <string name="label_action_split_screen">Podzielony ekran</string>
+ <string name="label_action_one_handed_mode_left">Tryb jednej ręki (lewa strona)</string>
+ <string name="label_action_one_handed_mode_right">Tryb jednej ręki (prawa strona)</string>
+ <string name="label_action_media_left">Poprzedni utwór</string>
+ <string name="label_action_media_right">Następny utwór</string>
+ <string name="label_action_assistant_sound_search">Wyszukiwarka dźwięku Google</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s zabitych</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-pt-rBR/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-pt-rBR/custom_strings.xml
new file mode 100644
index 0000000..768c4be
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-pt-rBR/custom_strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Nenhuma ação</string>
+ <string name="label_action_settings_panel">Painel de configurações</string>
+ <string name="label_action_notification_panel">Painel de notificação</string>
+ <string name="label_action_screenshot">Captura de tela</string>
+ <string name="label_action_region_screenshot">Captura de tela parcial</string>
+ <string name="label_action_screenrecord">Gravar tela</string>
+ <string name="label_action_expanded_desktop">Área de trabalho expandida</string>
+ <string name="label_action_screen_off">Desligar a tela</string>
+ <string name="label_action_force_close_app">Forçar fechamento do app</string>
+ <string name="label_action_google_assistant">Google Assistente</string>
+ <string name="label_action_in_app_search">Busca interna do app</string>
+ <string name="label_action_flashlight">Lanterna</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">Wi-Fi</string>
+ <string name="label_action_hotspot">Ponto de acesso</string>
+ <string name="label_action_last_app">Último aplicativo</string>
+ <string name="label_action_overview">Recentes</string>
+ <string name="label_action_power_menu">Menu de energia</string>
+ <string name="label_action_menu">Menu</string>
+ <string name="label_action_back">Voltar</string>
+ <string name="label_action_home">Início</string>
+ <string name="label_action_ime_switcher">Método de entrada</string>
+ <string name="label_action_stop_screenpinning">Sair do modo de fixação de tela</string>
+ <string name="label_action_ime_down">Cursor do método de entrada para baixo</string>
+ <string name="label_action_ime_left">Cursor do método de entrada para esquerda</string>
+ <string name="label_action_ime_right">Cursor do método de entrada para direita</string>
+ <string name="label_action_ime_up">Cursor do método de entrada para cima</string>
+ <string name="label_action_volume_panel">Painel de volume</string>
+ <string name="label_action_clear_notifications">Limpar notificações</string>
+ <string name="label_action_split_screen">Dividir a tela</string>
+ <string name="label_action_one_handed_mode_left">Modo de uma mão (lado esquerdo)</string>
+ <string name="label_action_one_handed_mode_right">Modo de uma mão (lado direito)</string>
+ <string name="label_action_media_left">Faixa anterior</string>
+ <string name="label_action_media_right">Próxima faixa</string>
+ <string name="label_action_assistant_sound_search">Pesquisa de som do Google</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s encerrado</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-pt-rPT/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-pt-rPT/custom_strings.xml
new file mode 100644
index 0000000..6521ecc
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-pt-rPT/custom_strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Sem ação</string>
+ <string name="label_action_settings_panel">Painel de definições</string>
+ <string name="label_action_notification_panel">Painel de notificações</string>
+ <string name="label_action_screenshot">Captura de ecrã</string>
+ <string name="label_action_region_screenshot">Captura parcial de ecrã</string>
+ <string name="label_action_screenrecord">Gravar ecrã</string>
+ <string name="label_action_expanded_desktop">Área de trabalho expandida</string>
+ <string name="label_action_screen_off">Desligar o ecrã</string>
+ <string name="label_action_force_close_app">Forçar encerramento da aplicação</string>
+ <string name="label_action_google_assistant">Assistente Google</string>
+ <string name="label_action_in_app_search">Pesquisa na aplicação</string>
+ <string name="label_action_flashlight">Lanterna</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">Wi-Fi</string>
+ <string name="label_action_hotspot">Zona Wi-Fi</string>
+ <string name="label_action_last_app">Última aplicação</string>
+ <string name="label_action_overview">Aplicações recentes</string>
+ <string name="label_action_power_menu">Menu de ligar/desligar</string>
+ <string name="label_action_menu">Menu</string>
+ <string name="label_action_back">Voltar</string>
+ <string name="label_action_home">Página Inicial</string>
+ <string name="label_action_ime_switcher">Método de entrada</string>
+ <string name="label_action_stop_screenpinning">Sair da fixação do ecrã</string>
+ <string name="label_action_ime_down">Cursor para baixo</string>
+ <string name="label_action_ime_left">Cursor para a esquerda</string>
+ <string name="label_action_ime_right">Cursor para a direita</string>
+ <string name="label_action_ime_up">Cursor para cima</string>
+ <string name="label_action_volume_panel">Painel de volume</string>
+ <string name="label_action_clear_notifications">Limpar notificações</string>
+ <string name="label_action_split_screen">Dividir ecrã</string>
+ <string name="label_action_one_handed_mode_left">Modo de uma mão (esquerda)</string>
+ <string name="label_action_one_handed_mode_right">Modo de uma mão (direita)</string>
+ <string name="label_action_media_left">Faixa anterior</string>
+ <string name="label_action_media_right">Próxima faixa</string>
+ <string name="label_action_assistant_sound_search">Pesquisa de som no Google</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s terminada</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-ro-rRO/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-ro-rRO/custom_strings.xml
new file mode 100644
index 0000000..c74e187
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-ro-rRO/custom_strings.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Nicio acțiune</string>
+ <string name="label_action_settings_panel">Panoul de setări</string>
+ <string name="label_action_notification_panel">Panou notificări</string>
+ <string name="label_action_screenshot">Captură ecran</string>
+ <string name="label_action_region_screenshot">Captură parțială de ecran</string>
+ <string name="label_action_screenrecord">Înregistrare de ecran</string>
+ <string name="label_action_expanded_desktop">Desktop extins</string>
+ <string name="label_action_screen_off">Oprește ecranul</string>
+ <string name="label_action_force_close_app">Forțează închiderea aplicației</string>
+ <string name="label_action_search_assistant">Asistent căutare</string>
+ <string name="label_action_google_now_on_tap">Google Now la apăsare</string>
+ <string name="label_action_voice_search">Căutare vocală</string>
+ <string name="label_action_in_app_search">Căutare în aplicație</string>
+ <string name="label_action_flashlight">Lanternă</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Hotspot</string>
+ <string name="label_action_last_app">Ultima aplicație</string>
+ <string name="label_action_overview">Recente</string>
+ <string name="label_action_power_menu">Meniu pornire</string>
+ <string name="label_action_menu">Meniu</string>
+ <string name="label_action_back">Înapoi</string>
+ <string name="label_action_home">Acasă</string>
+ <string name="label_action_ime_switcher">Schimbător IME</string>
+ <string name="label_action_stop_screenpinning">Oprire fixare ecran</string>
+ <string name="label_action_ime_down">Metodă de introducere cursor în jos</string>
+ <string name="label_action_ime_left">Metodă de introducere cursor stânga</string>
+ <string name="label_action_ime_right">Metodă de introducere cursor dreapta</string>
+ <string name="label_action_ime_up">Metodă de introducere cursor sus</string>
+ <string name="label_action_volume_panel">Panou de volum</string>
+ <string name="label_action_clear_notifications">Ștergeți notificări</string>
+ <string name="label_action_split_screen">Ecran divizat</string>
+ <string name="label_action_one_handed_mode_left">Mod cu o mână (stânga)</string>
+ <string name="label_action_one_handed_mode_right">Mod cu o mână (dreapta)</string>
+ <string name="label_action_media_left">Melodia anterioară</string>
+ <string name="label_action_media_right">Piesa următoare</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s oprită</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-ro/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-ro/custom_strings.xml
new file mode 100644
index 0000000..e88f417
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-ro/custom_strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Nici o acțiune</string>
+ <string name="label_action_settings_panel">Panoul de setări</string>
+ <string name="label_action_notification_panel">Panou notificări</string>
+ <string name="label_action_screenshot">Captură ecran</string>
+ <string name="label_action_region_screenshot">Captură parțială de ecran</string>
+ <string name="label_action_screenrecord">Înregistrare de ecran</string>
+ <string name="label_action_expanded_desktop">Desktop extins</string>
+ <string name="label_action_screen_off">Oprește ecranul</string>
+ <string name="label_action_force_close_app">Forțează închiderea aplicației</string>
+ <string name="label_action_google_assistant">Asistent Google</string>
+ <string name="label_action_in_app_search">Căutare în aplicație</string>
+ <string name="label_action_flashlight">Lanternă</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Hotspot</string>
+ <string name="label_action_last_app">Ultima aplicație</string>
+ <string name="label_action_overview">Recente</string>
+ <string name="label_action_power_menu">Meniu pornire</string>
+ <string name="label_action_menu">Meniu</string>
+ <string name="label_action_back">Înapoi</string>
+ <string name="label_action_home">Acasă</string>
+ <string name="label_action_ime_switcher">Schimbător IME</string>
+ <string name="label_action_stop_screenpinning">Oprire fixare ecran</string>
+ <string name="label_action_ime_down">Metodă de introducere cursor în jos</string>
+ <string name="label_action_ime_left">Metodă de introducere cursor stânga</string>
+ <string name="label_action_ime_right">Metodă de introducere cursor dreapta</string>
+ <string name="label_action_ime_up">Metodă de introducere cursor sus</string>
+ <string name="label_action_volume_panel">Panou de volum</string>
+ <string name="label_action_clear_notifications">Ștergeți notificări</string>
+ <string name="label_action_split_screen">Ecran divizat</string>
+ <string name="label_action_one_handed_mode_left">Mod cu o mână (stânga)</string>
+ <string name="label_action_one_handed_mode_right">Mod cu o mână (dreapta)</string>
+ <string name="label_action_media_left">Melodia anterioară</string>
+ <string name="label_action_media_right">Piesa următoare</string>
+ <string name="label_action_assistant_sound_search">Google cautare sunet</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s oprită</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-ru-rRU/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-ru-rRU/custom_strings.xml
new file mode 100644
index 0000000..56c9e84
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-ru-rRU/custom_strings.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Нет действия</string>
+ <string name="label_action_settings_panel">Панель настроек</string>
+ <string name="label_action_notification_panel">Панель уведомлений</string>
+ <string name="label_action_screenshot">Скриншот</string>
+ <string name="label_action_region_screenshot">Скриншот выбранной области экрана</string>
+ <string name="label_action_screenrecord">Запись экрана</string>
+ <string name="label_action_expanded_desktop">Расширенный рабочий стол</string>
+ <string name="label_action_screen_off">Выключить экран</string>
+ <string name="label_action_force_close_app">Принудительно закрыть приложение</string>
+ <string name="label_action_search_assistant">Поисковый помощник</string>
+ <string name="label_action_google_now_on_tap">Google Now On Tap</string>
+ <string name="label_action_voice_search">Голосовой поиск</string>
+ <string name="label_action_in_app_search">Поиск в приложении</string>
+ <string name="label_action_flashlight">Фонарик</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">Wi-Fi</string>
+ <string name="label_action_hotspot">Точка доступа</string>
+ <string name="label_action_last_app">Последнее приложение</string>
+ <string name="label_action_overview">Меню недавних приложений</string>
+ <string name="label_action_power_menu">Меню кнопки питания</string>
+ <string name="label_action_menu">Меню</string>
+ <string name="label_action_back">Назад</string>
+ <string name="label_action_home">Домой</string>
+ <string name="label_action_ime_switcher">Выбор способа ввода</string>
+ <string name="label_action_stop_screenpinning">Остановить закрепление экрана</string>
+ <string name="label_action_ime_down">Курсор вниз при вводе</string>
+ <string name="label_action_ime_left">Курсор влево при вводе</string>
+ <string name="label_action_ime_right">Курсор вправо при вводе</string>
+ <string name="label_action_ime_up">Курсор вверх при вводе</string>
+ <string name="label_action_volume_panel">Панель громкости</string>
+ <string name="label_action_clear_notifications">Очистить уведомления</string>
+ <string name="label_action_split_screen">Разделить экран</string>
+ <string name="label_action_one_handed_mode_left">Режим «Управление одной рукой» (левая сторона)</string>
+ <string name="label_action_one_handed_mode_right">Режим «Управление одной рукой» (правая сторона)</string>
+ <string name="label_action_media_left">Предыдущий трек</string>
+ <string name="label_action_media_right">Следующий трек</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s закрыто</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-ru/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-ru/custom_strings.xml
new file mode 100644
index 0000000..7c18e37
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-ru/custom_strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Нет действия</string>
+ <string name="label_action_settings_panel">Панель быстрых настроек</string>
+ <string name="label_action_notification_panel">Панель уведомлений</string>
+ <string name="label_action_screenshot">Снимок экрана</string>
+ <string name="label_action_region_screenshot">Скриншот выбранной области экрана</string>
+ <string name="label_action_screenrecord">Запись экрана</string>
+ <string name="label_action_expanded_desktop">Расширенный рабочий стол</string>
+ <string name="label_action_screen_off">Выключить экран</string>
+ <string name="label_action_force_close_app">Принудительно закрыть приложение</string>
+ <string name="label_action_google_assistant">Google Ассистент</string>
+ <string name="label_action_in_app_search">Поиск в приложении</string>
+ <string name="label_action_flashlight">Фонарик</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">Wi-Fi</string>
+ <string name="label_action_hotspot">Точка доступа</string>
+ <string name="label_action_last_app">Последнее приложение</string>
+ <string name="label_action_overview">Меню недавних приложений</string>
+ <string name="label_action_power_menu">Меню кнопки питания</string>
+ <string name="label_action_menu">Меню</string>
+ <string name="label_action_back">Назад</string>
+ <string name="label_action_home">Домой</string>
+ <string name="label_action_ime_switcher">Выбор способа ввода</string>
+ <string name="label_action_stop_screenpinning">Остановить закрепление экрана</string>
+ <string name="label_action_ime_down">При вводе курсор снизу</string>
+ <string name="label_action_ime_left">При вводе курсор справа</string>
+ <string name="label_action_ime_right">При вводе курсор справа</string>
+ <string name="label_action_ime_up">При вводе курсор сверху</string>
+ <string name="label_action_volume_panel">Панель громкости</string>
+ <string name="label_action_clear_notifications">Очистить уведомления</string>
+ <string name="label_action_split_screen">Разделить экран</string>
+ <string name="label_action_one_handed_mode_left">Режим «Управление одной рукой» (левая сторона)</string>
+ <string name="label_action_one_handed_mode_right">Режим «Управление одной рукой» (правая сторона)</string>
+ <string name="label_action_media_left">Предыдущий трек</string>
+ <string name="label_action_media_right">Следующий трек</string>
+ <string name="label_action_assistant_sound_search">Голосовой поиск Google</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s закрыто</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-si-rLK/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-si-rLK/custom_strings.xml
new file mode 100644
index 0000000..f64c1b3
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-si-rLK/custom_strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-sk-rSK/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-sk-rSK/custom_strings.xml
new file mode 100644
index 0000000..d555eca
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-sk-rSK/custom_strings.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Žiadna akcia</string>
+ <string name="label_action_settings_panel">Panel nastavení</string>
+ <string name="label_action_notification_panel">Panel upozornení</string>
+ <string name="label_action_screenshot">Snímka obrazovky</string>
+ <string name="label_action_region_screenshot">Čiastočná snímka obrazovky</string>
+ <string name="label_action_screenrecord">Nahrávanie obrazovky</string>
+ <string name="label_action_expanded_desktop">Rozšírená plocha</string>
+ <string name="label_action_screen_off">Vypnutie obrazovky</string>
+ <string name="label_action_force_close_app">Vynútené ukončenie aplikácií</string>
+ <string name="label_action_search_assistant">Asistent vyhľadávania</string>
+ <string name="label_action_google_now_on_tap">Asistent Google Now na kliknutie</string>
+ <string name="label_action_voice_search">Hlasové vyhľadávanie</string>
+ <string name="label_action_in_app_search">Vyhľadávanie v aplikáciách</string>
+ <string name="label_action_flashlight">Baterka</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">Wi-Fi</string>
+ <string name="label_action_hotspot">Hotspot</string>
+ <string name="label_action_last_app">Posledná aplikácia</string>
+ <string name="label_action_overview">Nedávne</string>
+ <string name="label_action_power_menu">Ponuka tlačidla Napájanie</string>
+ <string name="label_action_menu">Menu</string>
+ <string name="label_action_back">Späť</string>
+ <string name="label_action_home">Domov</string>
+ <string name="label_action_ime_switcher">Prepínač metódy vstupu (IME)</string>
+ <string name="label_action_stop_screenpinning">Ukončenie pripnutia obrazovky</string>
+ <string name="label_action_ime_down">IME - kurzor nadol</string>
+ <string name="label_action_ime_left">IME - kurzor vľavo</string>
+ <string name="label_action_ime_right">IME - kurzor vpravo</string>
+ <string name="label_action_ime_up">IME - kurzor nahor</string>
+ <string name="label_action_volume_panel">Panel hlasitosti</string>
+ <string name="label_action_clear_notifications">Vymazať upozornenia</string>
+ <string name="label_action_split_screen">Rozdelenie obrazovky</string>
+ <string name="label_action_one_handed_mode_left">Režim jednou rukou (vľavo)</string>
+ <string name="label_action_one_handed_mode_right">Režim jednou rukou (vpravo)</string>
+ <string name="label_action_media_left">Predchádzajúca skladba</string>
+ <string name="label_action_media_right">Ďalšia skladba</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s bola ukončená</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-sk/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-sk/custom_strings.xml
new file mode 100644
index 0000000..f9bef66
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-sk/custom_strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Žiadna akcia</string>
+ <string name="label_action_settings_panel">Panel rýchlych nastavení</string>
+ <string name="label_action_notification_panel">Panel upozornení</string>
+ <string name="label_action_screenshot">Snímka obrazovky</string>
+ <string name="label_action_region_screenshot">Čiastočná snímka obrazovky</string>
+ <string name="label_action_screenrecord">Nahrávanie obrazovky</string>
+ <string name="label_action_expanded_desktop">Rozšírená plocha</string>
+ <string name="label_action_screen_off">Vypnúť obrazovku</string>
+ <string name="label_action_force_close_app">Vynútené ukončenie aplikácie</string>
+ <string name="label_action_google_assistant">Asistent Google</string>
+ <string name="label_action_in_app_search">Vyhľadávanie v aplikáciách</string>
+ <string name="label_action_flashlight">Baterka</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Hotspot</string>
+ <string name="label_action_last_app">Posledná aplikácia</string>
+ <string name="label_action_overview">Nedávne</string>
+ <string name="label_action_power_menu">Ponuka tlačidla Napájanie</string>
+ <string name="label_action_menu">Menu</string>
+ <string name="label_action_back">Späť</string>
+ <string name="label_action_home">Domov</string>
+ <string name="label_action_ime_switcher">Prepínač metódy vstupu (IME)</string>
+ <string name="label_action_stop_screenpinning">Ukončenie pripnutia obrazovky</string>
+ <string name="label_action_ime_down">IME - kurzor nadol</string>
+ <string name="label_action_ime_left">IME - kurzor vľavo</string>
+ <string name="label_action_ime_right">IME - kurzor vpravo</string>
+ <string name="label_action_ime_up">IME - kurzor nahor</string>
+ <string name="label_action_volume_panel">Panel hlasitosti</string>
+ <string name="label_action_clear_notifications">Vymazať upozornenia</string>
+ <string name="label_action_split_screen">Rozdelenie obrazovky</string>
+ <string name="label_action_one_handed_mode_left">Režim jednou rukou (vľavo)</string>
+ <string name="label_action_one_handed_mode_right">Režim jednou rukou (vpravo)</string>
+ <string name="label_action_media_left">Predchádzajúca skladba</string>
+ <string name="label_action_media_right">Ďalšia skladba</string>
+ <string name="label_action_assistant_sound_search">Vyhľadávanie zvuku Google</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s bola ukončená</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-sl-rSI/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-sl-rSI/custom_strings.xml
new file mode 100644
index 0000000..f64c1b3
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-sl-rSI/custom_strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-sl/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-sl/custom_strings.xml
new file mode 100644
index 0000000..f64c1b3
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-sl/custom_strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-sq-rAL/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-sq-rAL/custom_strings.xml
new file mode 100644
index 0000000..f64c1b3
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-sq-rAL/custom_strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-sr-rSP/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-sr-rSP/custom_strings.xml
new file mode 100644
index 0000000..890ef91
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-sr-rSP/custom_strings.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Нема радње</string>
+ <string name="label_action_settings_panel">Панел поставки</string>
+ <string name="label_action_notification_panel">Панел обавештења</string>
+ <string name="label_action_screenshot">Снимак слике екрана</string>
+ <string name="label_action_region_screenshot">Делимичан снимак слике екрана</string>
+ <string name="label_action_screenrecord">Снимање екрана</string>
+ <string name="label_action_expanded_desktop">Проширена радна површина</string>
+ <string name="label_action_screen_off">Искључи екран</string>
+ <string name="label_action_force_close_app">Присилно затвори апликацију</string>
+ <string name="label_action_search_assistant">Помоћник у претрази</string>
+ <string name="label_action_google_now_on_tap">Google Now на додир</string>
+ <string name="label_action_voice_search">Гласовна претрага</string>
+ <string name="label_action_in_app_search">Претрага унутар апликације</string>
+ <string name="label_action_flashlight">Лампа</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">Wi-Fi</string>
+ <string name="label_action_hotspot">Hotspot</string>
+ <string name="label_action_last_app">Последња апликација</string>
+ <string name="label_action_overview">Недавне</string>
+ <string name="label_action_power_menu">Мени напајања</string>
+ <string name="label_action_menu">Мени</string>
+ <string name="label_action_back">Назад</string>
+ <string name="label_action_home">Почетна</string>
+ <string name="label_action_ime_switcher">Промена начина уноса</string>
+ <string name="label_action_stop_screenpinning">Заустави откачињање екрана</string>
+ <string name="label_action_ime_down">Начин уноса - стрелица за доле</string>
+ <string name="label_action_ime_left">Начин уноза - стрелица лево</string>
+ <string name="label_action_ime_right">Начин уноса - стрелица десно</string>
+ <string name="label_action_ime_up">Начин уноса - стрелица за горе</string>
+ <string name="label_action_volume_panel">Панел јачине звука</string>
+ <string name="label_action_clear_notifications">Избриши обавештења</string>
+ <string name="label_action_split_screen">Подељени екран</string>
+ <string name="label_action_one_handed_mode_left">Режим коришћења једне руке (лева страна)</string>
+ <string name="label_action_one_handed_mode_right">Режим коришћења једне руке (десна страна)</string>
+ <string name="label_action_media_left">Предходна нумера</string>
+ <string name="label_action_media_right">Следећа нумера</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s заустављена</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-sr/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-sr/custom_strings.xml
new file mode 100644
index 0000000..377a8d7
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-sr/custom_strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Без акције</string>
+ <string name="label_action_settings_panel">Панел поставки</string>
+ <string name="label_action_notification_panel">Панел обавештења</string>
+ <string name="label_action_screenshot">Снимак слике екрана</string>
+ <string name="label_action_region_screenshot">Делимичан снимак слике екрана</string>
+ <string name="label_action_screenrecord">Снимање екрана</string>
+ <string name="label_action_expanded_desktop">Проширена радна површина</string>
+ <string name="label_action_screen_off">Искључи екран</string>
+ <string name="label_action_force_close_app">Присилно затвори апликацију</string>
+ <string name="label_action_google_assistant">Гугл асистент</string>
+ <string name="label_action_in_app_search">Претрага унутар апликације</string>
+ <string name="label_action_flashlight">Лампа</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">Wi-Fi</string>
+ <string name="label_action_hotspot">Приступна тачка</string>
+ <string name="label_action_last_app">Последња апликација</string>
+ <string name="label_action_overview">Мени недавних апликација</string>
+ <string name="label_action_power_menu">Мени напајања</string>
+ <string name="label_action_menu">Мени</string>
+ <string name="label_action_back">Назад</string>
+ <string name="label_action_home">Почетна</string>
+ <string name="label_action_ime_switcher">Промена начина уноса</string>
+ <string name="label_action_stop_screenpinning">Заустави откачињање екрана</string>
+ <string name="label_action_ime_down">Начин уноса - стрелица за доле</string>
+ <string name="label_action_ime_left">Начин уноза - стрелица лево</string>
+ <string name="label_action_ime_right">Начин уноса - стрелица десно</string>
+ <string name="label_action_ime_up">Начин уноса - стрелица за горе</string>
+ <string name="label_action_volume_panel">Панел јачине звука</string>
+ <string name="label_action_clear_notifications">Избриши обавештења</string>
+ <string name="label_action_split_screen">Подељени екран</string>
+ <string name="label_action_one_handed_mode_left">Режим коришћења једном руком (лева страна)</string>
+ <string name="label_action_one_handed_mode_right">Режим коришћења једном руком (десна страна)</string>
+ <string name="label_action_media_left">Предходна нумера</string>
+ <string name="label_action_media_right">Следећа нумера</string>
+ <string name="label_action_assistant_sound_search">Gугл гласовно претраживање</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s заустављена</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-sv-rSE/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-sv-rSE/custom_strings.xml
new file mode 100644
index 0000000..bbce0f3
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-sv-rSE/custom_strings.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Ingen åtgärd</string>
+ <string name="label_action_settings_panel">Inställningspanel</string>
+ <string name="label_action_notification_panel">Notifieringspanel</string>
+ <string name="label_action_screenshot">Skärmdump</string>
+ <string name="label_action_region_screenshot">Partiell skärmdump</string>
+ <string name="label_action_screenrecord">Spela in skärmen</string>
+ <string name="label_action_expanded_desktop">Utökat skrivbord</string>
+ <string name="label_action_screen_off">Stäng av skärm</string>
+ <string name="label_action_force_close_app">Tvinga stängning av app</string>
+ <string name="label_action_search_assistant">Sökassistenten</string>
+ <string name="label_action_google_now_on_tap">Google Now vid klick</string>
+ <string name="label_action_voice_search">Röstsökning</string>
+ <string name="label_action_in_app_search">Sökning i app</string>
+ <string name="label_action_flashlight">Ficklampa</string>
+ <string name="label_action_bluetooth">Blåtand</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Trådlös surfzon</string>
+ <string name="label_action_last_app">Senaste app</string>
+ <string name="label_action_overview">Senaste appar</string>
+ <string name="label_action_power_menu">Avstängningsmeny</string>
+ <string name="label_action_menu">Meny</string>
+ <string name="label_action_back">Tillbaka</string>
+ <string name="label_action_home">Hem</string>
+ <string name="label_action_ime_switcher">IME-växlare</string>
+ <string name="label_action_stop_screenpinning">Stoppa fastlåsning av skärm</string>
+ <string name="label_action_ime_down">Inmatningsmetod pil nedåt</string>
+ <string name="label_action_ime_left">Inmatningsmetod pil vänster</string>
+ <string name="label_action_ime_right">Inmatningsmetod pil höger</string>
+ <string name="label_action_ime_up">Inmatningsmetod pil uppåt</string>
+ <string name="label_action_volume_panel">Volympanel</string>
+ <string name="label_action_clear_notifications">Rensa aviseringar.</string>
+ <string name="label_action_split_screen">Dela skärm</string>
+ <string name="label_action_one_handed_mode_left">Enhandsläge (vänster sida)</string>
+ <string name="label_action_one_handed_mode_right">Enhandsläge (höger sida)</string>
+ <string name="label_action_media_left">Föregående spår</string>
+ <string name="label_action_media_right">Nästa spår</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s tvångsavslutades</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-sv/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-sv/custom_strings.xml
new file mode 100644
index 0000000..6f17c5a
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-sv/custom_strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Ingen åtgärd</string>
+ <string name="label_action_settings_panel">Inställningspanel</string>
+ <string name="label_action_notification_panel">Notifieringspanel</string>
+ <string name="label_action_screenshot">Skärmdump</string>
+ <string name="label_action_region_screenshot">Partiell skärmdump</string>
+ <string name="label_action_screenrecord">Spela in skärmen</string>
+ <string name="label_action_expanded_desktop">Utökat skrivbord</string>
+ <string name="label_action_screen_off">Stäng av skärm</string>
+ <string name="label_action_force_close_app">Tvinga stängning av app</string>
+ <string name="label_action_google_assistant">Google assistent</string>
+ <string name="label_action_in_app_search">Sök i app</string>
+ <string name="label_action_flashlight">Ficklampa</string>
+ <string name="label_action_bluetooth">Blåtand</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Trådlös surfzon</string>
+ <string name="label_action_last_app">Senaste app</string>
+ <string name="label_action_overview">Senaste appar</string>
+ <string name="label_action_power_menu">Avstängningsmeny</string>
+ <string name="label_action_menu">Meny</string>
+ <string name="label_action_back">Tillbaka</string>
+ <string name="label_action_home">Hem</string>
+ <string name="label_action_ime_switcher">IME-växlare</string>
+ <string name="label_action_stop_screenpinning">Stoppa fastlåsning av skärm</string>
+ <string name="label_action_ime_down">Inmatningsmetod pil nedåt</string>
+ <string name="label_action_ime_left">Inmatningsmetod pil vänster</string>
+ <string name="label_action_ime_right">Inmatningsmetod pil höger</string>
+ <string name="label_action_ime_up">Inmatningsmetod pil uppåt</string>
+ <string name="label_action_volume_panel">Volympanel</string>
+ <string name="label_action_clear_notifications">Rensa aviseringar.</string>
+ <string name="label_action_split_screen">Dela skärm</string>
+ <string name="label_action_one_handed_mode_left">Enhandsläge (vänster sida)</string>
+ <string name="label_action_one_handed_mode_right">Enhandsläge (höger sida)</string>
+ <string name="label_action_media_left">Föregående spår</string>
+ <string name="label_action_media_right">Nästa spår</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s tvångsavslutades</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-sw/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-sw/custom_strings.xml
new file mode 100644
index 0000000..f64c1b3
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-sw/custom_strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-ta-rIN/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-ta-rIN/custom_strings.xml
new file mode 100644
index 0000000..8bee59a
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-ta-rIN/custom_strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">செயல்பாடு இல்லை</string>
+ <string name="label_action_settings_panel">QS பேனல்</string>
+ <string name="label_action_notification_panel">அறிவிப்புப் பலகை</string>
+ <string name="label_action_screenshot">திரைப்பிடிப்பு</string>
+ <string name="label_action_region_screenshot">பகுதி திரைச்சொட்டு</string>
+ <string name="label_action_screenrecord">திரை பதிவு</string>
+ <string name="label_action_expanded_desktop">விரிவுபடுத்தப்பட்ட டெஸ்க்டாப்</string>
+ <string name="label_action_screen_off">திரையை முடக்கு</string>
+ <string name="label_action_force_close_app">நெருங்கிய பயன்பாடு பயன்படுகிறது</string>
+ <string name="label_action_google_assistant">குரல் உதவியாளர்</string>
+ <string name="label_action_in_app_search">ஆப்-உள் தேடல்</string>
+ <string name="label_action_flashlight">விளக்கு</string>
+ <string name="label_action_bluetooth">புளூடூத்</string>
+ <string name="label_action_wifi">வைஃபை</string>
+ <string name="label_action_hotspot">ஹாட்ஸ்பாட்</string>
+ <string name="label_action_last_app">கடைசி செயலி</string>
+ <string name="label_action_overview">சமீபத்திய</string>
+ <string name="label_action_power_menu">பவர் பட்டியல்</string>
+ <string name="label_action_menu">மெனு</string>
+ <string name="label_action_back">பின்செல்</string>
+ <string name="label_action_home">முகப்பு</string>
+ <string name="label_action_ime_switcher">IME மாற்றி</string>
+ <string name="label_action_stop_screenpinning">திரை பொருத்துதல் நிறுத்து</string>
+ <string name="label_action_ime_down">உள்ளீட்டு முறை கர்சர் கீழே</string>
+ <string name="label_action_ime_left">உள்ளீட்டு முறை கர்சர் இடது</string>
+ <string name="label_action_ime_right">உள்ளீட்டு முறை கர்சர் வலது</string>
+ <string name="label_action_ime_up">உள்ளீட்டு முறை கர்சர் கீழே</string>
+ <string name="label_action_volume_panel">வால்யூம் பேனல்</string>
+ <string name="label_action_clear_notifications">அறிவிப்பை அகற்றவும்</string>
+ <string name="label_action_split_screen">பிரிக்கப்பட்ட திரை</string>
+ <string name="label_action_one_handed_mode_left">ஒரு கைமுறை முறை (இடது பக்கம்)</string>
+ <string name="label_action_one_handed_mode_right">ஒரு கைமுறை முறை (இடது பக்கம்)</string>
+ <string name="label_action_media_left">முந்தைய பாடல்</string>
+ <string name="label_action_media_right">அடுத்த பாடல்</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s மூடப்பட்டது</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-te-rIN/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-te-rIN/custom_strings.xml
new file mode 100644
index 0000000..3b636ecf
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-te-rIN/custom_strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">చర్య తీసుకోలేదు</string>
+ <string name="label_action_settings_panel">QS ప్యానెల్</string>
+ <string name="label_action_notification_panel">నోటిఫికేషన్ ప్యానెల్</string>
+ <string name="label_action_screenshot">స్క్రీన్షాట్</string>
+ <string name="label_action_region_screenshot">పాక్షిక స్క్రీన్షాట్</string>
+ <string name="label_action_screenrecord">స్క్రీన్ ని రికార్డు చేయండి</string>
+ <string name="label_action_expanded_desktop">విస్తరించిన డెస్క్టాప్</string>
+ <string name="label_action_screen_off">స్క్రీన్ను ఆపివేయి</string>
+ <string name="label_action_force_close_app">అప్లికేషన్ను మూసివేయండి</string>
+ <string name="label_action_google_assistant">Google అసిస్టెంట్</string>
+ <string name="label_action_in_app_search">అప్ లో వెతకండి</string>
+ <string name="label_action_flashlight">ఫ్లాష్ లైట్</string>
+ <string name="label_action_bluetooth">బ్లూటూత్</string>
+ <string name="label_action_wifi">వైఫై</string>
+ <string name="label_action_hotspot">హాట్స్పాట్</string>
+ <string name="label_action_last_app">చివరి యాప్</string>
+ <string name="label_action_overview">ఇటీవలి</string>
+ <string name="label_action_power_menu">పవర్ మెను</string>
+ <string name="label_action_menu">మెనూ</string>
+ <string name="label_action_back">వెనక్కు</string>
+ <string name="label_action_home">ఇల్లు</string>
+ <string name="label_action_ime_switcher">IME మారకం</string>
+ <string name="label_action_stop_screenpinning">స్క్రీన్ పిన్ చేయడాన్ని ఆపివేయి</string>
+ <string name="label_action_ime_down">ఇన్పుట్ పద్ధతి కర్సర్ కింద</string>
+ <string name="label_action_ime_left">ఇన్పుట్ పద్ధతి కర్సర్ వదిలి</string>
+ <string name="label_action_ime_right">ఇన్పుట్ పద్ధతి కర్సర్ కుడి</string>
+ <string name="label_action_ime_up">ఇన్పుట్ పద్ధతి కర్సర్ పైని</string>
+ <string name="label_action_volume_panel">వాల్యూమ్ ప్యానెల్</string>
+ <string name="label_action_clear_notifications">ప్రకటనలను క్లియర్ చేయండి</string>
+ <string name="label_action_split_screen">విభజించిన తెర</string>
+ <string name="label_action_one_handed_mode_left">ఒక చేతి మోడ్ (ఎడమ)</string>
+ <string name="label_action_one_handed_mode_right">ఒక చేతి మోడ్ (కుడి వైపు)</string>
+ <string name="label_action_media_left">మునుపటి ట్రాక్</string>
+ <string name="label_action_media_right">తదుపరి ట్రాక్</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s చంపా</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-th-rTH/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-th-rTH/custom_strings.xml
new file mode 100644
index 0000000..70449c4
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-th-rTH/custom_strings.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">ไม่มีการกระทำ</string>
+ <string name="label_action_settings_panel">แผงตั้งค่า</string>
+ <string name="label_action_notification_panel">แผงการแจ้งเตือน</string>
+ <string name="label_action_screenshot">ภาพหน้าจอ</string>
+ <string name="label_action_region_screenshot">บางส่วนของภาพหน้าจอ</string>
+ <string name="label_action_screenrecord">บันทึกหน้าจอ</string>
+ <string name="label_action_expanded_desktop">เต็มจอ</string>
+ <string name="label_action_screen_off">ปิดหน้าจอ</string>
+ <string name="label_action_force_close_app">บังคับปิดแอป</string>
+ <string name="label_action_search_assistant">ผู้ช่วยช่วยค้นหา</string>
+ <string name="label_action_google_now_on_tap">แตะบน Google Now</string>
+ <string name="label_action_voice_search">ค้นหาด้วยเสียง</string>
+ <string name="label_action_in_app_search">ค้นหาในแอป</string>
+ <string name="label_action_flashlight">ไฟฉาย</string>
+ <string name="label_action_bluetooth">บลูทูธ</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">ฮอตสปอต</string>
+ <string name="label_action_last_app">แอปล่าสุด</string>
+ <string name="label_action_overview">ล่าสุด</string>
+ <string name="label_action_power_menu">เมนูเพาว์เวอร์</string>
+ <string name="label_action_menu">เมนู</string>
+ <string name="label_action_back">กลับ</string>
+ <string name="label_action_home">หน้าแรก</string>
+ <string name="label_action_ime_switcher">เปลี่ยน IME</string>
+ <string name="label_action_stop_screenpinning">หยุดการปักหมุดหน้าจอ</string>
+ <string name="label_action_ime_down">วิธีการป้อนข้อมูลลง</string>
+ <string name="label_action_ime_left">วิธีการป้อนข้อมูลไปทางซ้าย</string>
+ <string name="label_action_ime_right">วิธีการป้อนข้อมูลไปทางขวา</string>
+ <string name="label_action_ime_up">วิธีการป้อนข้อมูลขึ้น</string>
+ <string name="label_action_volume_panel">แผงควบคุมระดับเสียง</string>
+ <string name="label_action_clear_notifications">ล้างการแจ้งเตือน</string>
+ <string name="label_action_split_screen">แยกหน้าจอ</string>
+ <string name="label_action_one_handed_mode_left">โหมดมือเดียว (ซ้าย)</string>
+ <string name="label_action_one_handed_mode_right">โหมดมือเดียว (ขวา)</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%sปิดแอป</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-th/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-th/custom_strings.xml
new file mode 100644
index 0000000..c4a48d8
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-th/custom_strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">ไม่มีการกระทำ</string>
+ <string name="label_action_settings_panel">แผงตั้งค่า</string>
+ <string name="label_action_notification_panel">แผงการแจ้งเตือน</string>
+ <string name="label_action_screenshot">ภาพหน้าจอ</string>
+ <string name="label_action_region_screenshot">บางส่วนของภาพหน้าจอ</string>
+ <string name="label_action_screenrecord">บันทึกหน้าจอ</string>
+ <string name="label_action_expanded_desktop">เต็มจอ</string>
+ <string name="label_action_screen_off">ปิดหน้าจอ</string>
+ <string name="label_action_force_close_app">บังคับปิดแอป</string>
+ <string name="label_action_google_assistant">Google assistant</string>
+ <string name="label_action_in_app_search">ค้นหาในแอป</string>
+ <string name="label_action_flashlight">ไฟฉาย</string>
+ <string name="label_action_bluetooth">บลูทูธ</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">ฮอตสปอต</string>
+ <string name="label_action_last_app">แอปล่าสุด</string>
+ <string name="label_action_overview">ล่าสุด</string>
+ <string name="label_action_power_menu">เมนูเพาว์เวอร์</string>
+ <string name="label_action_menu">เมนู</string>
+ <string name="label_action_back">กลับ</string>
+ <string name="label_action_home">หน้าแรก</string>
+ <string name="label_action_ime_switcher">เปลี่ยน IME</string>
+ <string name="label_action_stop_screenpinning">หยุดการปักหมุดหน้าจอ</string>
+ <string name="label_action_ime_down">วิธีการป้อนข้อมูลลง</string>
+ <string name="label_action_ime_left">วิธีการป้อนข้อมูลไปทางซ้าย</string>
+ <string name="label_action_ime_right">วิธีการป้อนข้อมูลไปทางขวา</string>
+ <string name="label_action_ime_up">วิธีการป้อนข้อมูลขึ้น</string>
+ <string name="label_action_volume_panel">แผงควบคุมระดับเสียง</string>
+ <string name="label_action_clear_notifications">ล้างการแจ้งเตือน</string>
+ <string name="label_action_split_screen">แยกหน้าจอ</string>
+ <string name="label_action_one_handed_mode_left">โหมดมือเดียว (ซ้าย)</string>
+ <string name="label_action_one_handed_mode_right">โหมดมือเดียว (ขวา)</string>
+ <string name="label_action_media_left">แทร็กก่อนหน้า</string>
+ <string name="label_action_media_right">แทร็คถัดไป</string>
+ <string name="label_action_assistant_sound_search">การค้นหาด้วยเสียงของ Google</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%sปิดแอป</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-tl/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-tl/custom_strings.xml
new file mode 100644
index 0000000..f64c1b3
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-tl/custom_strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-tr-rTR/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-tr-rTR/custom_strings.xml
new file mode 100644
index 0000000..127b4d4
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-tr-rTR/custom_strings.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Eylem yok</string>
+ <string name="label_action_settings_panel">Ayarlar paneli</string>
+ <string name="label_action_notification_panel">Bildirim paneli</string>
+ <string name="label_action_screenshot">Ekran görüntüsü</string>
+ <string name="label_action_region_screenshot">Kısmi ekran görüntüsü</string>
+ <string name="label_action_screenrecord">Ekranı kaydet</string>
+ <string name="label_action_expanded_desktop">Genişletilmiş masaüstü</string>
+ <string name="label_action_screen_off">Ekranı kapat</string>
+ <string name="label_action_force_close_app">Uygulamayı kapatmaya zorla</string>
+ <string name="label_action_search_assistant">Arama yardımcısı</string>
+ <string name="label_action_google_now_on_tap">Google Asistan\'a Dokunun
+</string>
+ <string name="label_action_voice_search">Sesli arama</string>
+ <string name="label_action_in_app_search">Uygulama içi arama</string>
+ <string name="label_action_flashlight">El feneri</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">Kablosuz</string>
+ <string name="label_action_hotspot">Erişim noktası</string>
+ <string name="label_action_last_app">Son uygulama</string>
+ <string name="label_action_overview">Son uygulamalar</string>
+ <string name="label_action_power_menu">Güç menüsü</string>
+ <string name="label_action_menu">Menü</string>
+ <string name="label_action_back">Geri</string>
+ <string name="label_action_home">Ana sayfa</string>
+ <string name="label_action_ime_switcher">Klavye Değiştirici</string>
+ <string name="label_action_stop_screenpinning">Ekran sabitlemeyi durdur</string>
+ <string name="label_action_ime_down">Aşagı imleç giriş yöntemi</string>
+ <string name="label_action_ime_left">Sol imleç giriş yontemi</string>
+ <string name="label_action_ime_right">Sağ imleç giriş yöntemi</string>
+ <string name="label_action_ime_up">Yukarı imleç giriş yöntemi</string>
+ <string name="label_action_volume_panel">Ses paneli</string>
+ <string name="label_action_clear_notifications">Bildirimleri temizle</string>
+ <string name="label_action_split_screen">Bölünmüş ekran</string>
+ <string name="label_action_one_handed_mode_left">Tek el modu (sol taraf)</string>
+ <string name="label_action_one_handed_mode_right">Tek el modu (sağ taraf)</string>
+ <string name="label_action_media_left">Önceki parça</string>
+ <string name="label_action_media_right">Sonraki parça</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s sonlandırıldı</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-tr/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-tr/custom_strings.xml
new file mode 100644
index 0000000..d8af093
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-tr/custom_strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Eylem yok</string>
+ <string name="label_action_settings_panel">Hızlı ayarlar paneli</string>
+ <string name="label_action_notification_panel">Bildirim paneli</string>
+ <string name="label_action_screenshot">Ekran görüntüsü</string>
+ <string name="label_action_region_screenshot">Kısmi ekran görüntüsü</string>
+ <string name="label_action_screenrecord">Ekranı kaydet</string>
+ <string name="label_action_expanded_desktop">Genişletilmiş masaüstü</string>
+ <string name="label_action_screen_off">Ekranı kapat</string>
+ <string name="label_action_force_close_app">Uygulamayı kapatmaya zorla</string>
+ <string name="label_action_google_assistant">Google asistan</string>
+ <string name="label_action_in_app_search">Uygulama içi arama</string>
+ <string name="label_action_flashlight">El feneri</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFİ</string>
+ <string name="label_action_hotspot">Erişim noktası</string>
+ <string name="label_action_last_app">Son uygulama</string>
+ <string name="label_action_overview">Son uygulamalar</string>
+ <string name="label_action_power_menu">Güç menüsü</string>
+ <string name="label_action_menu">Menü</string>
+ <string name="label_action_back">Geri</string>
+ <string name="label_action_home">Ana sayfa</string>
+ <string name="label_action_ime_switcher">Klavye değiştirici</string>
+ <string name="label_action_stop_screenpinning">Ekran sabitlemeyi durdur</string>
+ <string name="label_action_ime_down">Giriş yöntemi imleç aşağı</string>
+ <string name="label_action_ime_left">Giriş yöntemi imleç sola</string>
+ <string name="label_action_ime_right">Giriş yöntemi imleç sağa</string>
+ <string name="label_action_ime_up">Giriş yöntemi imleç yukarı</string>
+ <string name="label_action_volume_panel">Ses paneli</string>
+ <string name="label_action_clear_notifications">Bildirimleri temizle</string>
+ <string name="label_action_split_screen">Bölünmüş ekran</string>
+ <string name="label_action_one_handed_mode_left">Tek el modu (sol taraf)</string>
+ <string name="label_action_one_handed_mode_right">Tek el modu (sağ taraf)</string>
+ <string name="label_action_media_left">Önceki parça</string>
+ <string name="label_action_media_right">Sonraki parça</string>
+ <string name="label_action_assistant_sound_search">Google sesli arama</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s sonlandırıldı</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-ug-rCN/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-ug-rCN/custom_strings.xml
new file mode 100644
index 0000000..f64c1b3
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-ug-rCN/custom_strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-ug/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-ug/custom_strings.xml
new file mode 100644
index 0000000..f64c1b3
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-ug/custom_strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-uk-rUA/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-uk-rUA/custom_strings.xml
new file mode 100644
index 0000000..7bcaaad
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-uk-rUA/custom_strings.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Немає дій</string>
+ <string name="label_action_settings_panel">Панель налаштувань</string>
+ <string name="label_action_notification_panel">Панель сповіщень</string>
+ <string name="label_action_screenshot">Знімок екрану</string>
+ <string name="label_action_region_screenshot">Частковий скріншот</string>
+ <string name="label_action_screenrecord">Записати екран</string>
+ <string name="label_action_expanded_desktop">Розширений робочий стіл</string>
+ <string name="label_action_screen_off">Вимкнути екран</string>
+ <string name="label_action_force_close_app">Закрити примусово</string>
+ <string name="label_action_search_assistant">Пошуковий асистент</string>
+ <string name="label_action_google_now_on_tap">Google Now On Tap</string>
+ <string name="label_action_voice_search">Голосовий пошук</string>
+ <string name="label_action_in_app_search">Пошук у додатку</string>
+ <string name="label_action_flashlight">Ліхтарик</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Точка доступу</string>
+ <string name="label_action_last_app">Останній додаток</string>
+ <string name="label_action_overview">Нещодавні</string>
+ <string name="label_action_power_menu">Меню вимкнення</string>
+ <string name="label_action_menu">Меню</string>
+ <string name="label_action_back">Назад</string>
+ <string name="label_action_home">Додому</string>
+ <string name="label_action_ime_switcher">IME перемикач</string>
+ <string name="label_action_stop_screenpinning">Зупинити закріплення екрану</string>
+ <string name="label_action_ime_down">Метод введення курсор вниз</string>
+ <string name="label_action_ime_left">Метод введення курсор вліво</string>
+ <string name="label_action_ime_right">Метод введення курсор вправо</string>
+ <string name="label_action_ime_up">Метод введення курсор вгору</string>
+ <string name="label_action_volume_panel">Панель гучності</string>
+ <string name="label_action_clear_notifications">Очистити сповіщення</string>
+ <string name="label_action_split_screen">Розділення екрану</string>
+ <string name="label_action_one_handed_mode_left">Режим однієї руки (зліва)</string>
+ <string name="label_action_one_handed_mode_right">Режим однієї руки (справа)</string>
+ <string name="label_action_media_left">Попередня композиція</string>
+ <string name="label_action_media_right">Наступна композиція</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s закрито</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-uk/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-uk/custom_strings.xml
new file mode 100644
index 0000000..c413cdd
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-uk/custom_strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Немає дій</string>
+ <string name="label_action_settings_panel">Панель налаштувань</string>
+ <string name="label_action_notification_panel">Панель сповіщень</string>
+ <string name="label_action_screenshot">Знімок екрану</string>
+ <string name="label_action_region_screenshot">Частковий скріншот</string>
+ <string name="label_action_screenrecord">Записати екран</string>
+ <string name="label_action_expanded_desktop">Розширений робочий стіл</string>
+ <string name="label_action_screen_off">Вимкнути екран</string>
+ <string name="label_action_force_close_app">Закрити примусово</string>
+ <string name="label_action_google_assistant">Google Помічник</string>
+ <string name="label_action_in_app_search">Пошук у додатку</string>
+ <string name="label_action_flashlight">Ліхтарик</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Точка доступу</string>
+ <string name="label_action_last_app">Останній додаток</string>
+ <string name="label_action_overview">Нещодавні</string>
+ <string name="label_action_power_menu">Меню вимкнення</string>
+ <string name="label_action_menu">Меню</string>
+ <string name="label_action_back">Назад</string>
+ <string name="label_action_home">Додому</string>
+ <string name="label_action_ime_switcher">IME перемикач</string>
+ <string name="label_action_stop_screenpinning">Зупинити закріплення екрану</string>
+ <string name="label_action_ime_down">Метод введення курсор вниз</string>
+ <string name="label_action_ime_left">Метод введення курсор вліво</string>
+ <string name="label_action_ime_right">Метод введення курсор вправо</string>
+ <string name="label_action_ime_up">Метод введення курсор вгору</string>
+ <string name="label_action_volume_panel">Панель гучності</string>
+ <string name="label_action_clear_notifications">Очистити сповіщення</string>
+ <string name="label_action_split_screen">Розділення екрану</string>
+ <string name="label_action_one_handed_mode_left">Режим однієї руки (зліва)</string>
+ <string name="label_action_one_handed_mode_right">Режим однієї руки (справа)</string>
+ <string name="label_action_media_left">Попередня композиція</string>
+ <string name="label_action_media_right">Наступна композиція</string>
+ <string name="label_action_assistant_sound_search">Голосовий пошук Google</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s закрито</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-ur-rPK/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-ur-rPK/custom_strings.xml
new file mode 100644
index 0000000..f64c1b3
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-ur-rPK/custom_strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-vi-rVN/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-vi-rVN/custom_strings.xml
new file mode 100644
index 0000000..e3de297
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-vi-rVN/custom_strings.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Không có hành động</string>
+ <string name="label_action_settings_panel">Bảng cài đặt</string>
+ <string name="label_action_notification_panel">Bảng thông báo</string>
+ <string name="label_action_screenshot">Chụp ảnh màn hình</string>
+ <string name="label_action_region_screenshot">Ảnh chụp màn hình một phần</string>
+ <string name="label_action_screenrecord">Ghi lại màn hình</string>
+ <string name="label_action_expanded_desktop">Mở rộng màn hình</string>
+ <string name="label_action_screen_off">Tắt màn hình</string>
+ <string name="label_action_force_close_app">Buộc dừng ứng dụng</string>
+ <string name="label_action_search_assistant">Trợ lý tìm kiếm</string>
+ <string name="label_action_google_now_on_tap">Google Now On Tap</string>
+ <string name="label_action_voice_search">Tìm kiếm bằng giọng nói</string>
+ <string name="label_action_in_app_search">Tìm kiếm trong ứng dụng</string>
+ <string name="label_action_flashlight">Đèn pin</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Điểm phát sóng</string>
+ <string name="label_action_last_app">Ứng dụng cuối</string>
+ <string name="label_action_overview">Gần đây</string>
+ <string name="label_action_power_menu">Trình đơn nguồn</string>
+ <string name="label_action_menu">Trình đơn</string>
+ <string name="label_action_back">Quay lại</string>
+ <string name="label_action_home">Trang chủ</string>
+ <string name="label_action_ime_switcher">Thay đổi IME</string>
+ <string name="label_action_stop_screenpinning">Dừng ghim màn hình</string>
+ <string name="label_action_ime_down">Phương thức nhập con trỏ xuống</string>
+ <string name="label_action_ime_left">Phương thức nhập con trỏ trái</string>
+ <string name="label_action_ime_right">Phương thức nhập con trỏ phải</string>
+ <string name="label_action_ime_up">Phương thức nhập con trỏ lên</string>
+ <string name="label_action_volume_panel">Bảng điều chỉnh âm lượng</string>
+ <string name="label_action_clear_notifications">Xóa thông báo</string>
+ <string name="label_action_split_screen">Chia màn hình</string>
+ <string name="label_action_one_handed_mode_left">Chế độ một tay (bên trái)</string>
+ <string name="label_action_one_handed_mode_right">Chế độ một tay (bên phải)</string>
+ <string name="label_action_media_left">Bản nhạc trước</string>
+ <string name="label_action_media_right">Bản nhạc tiếp theo</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s đã dừng</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-vi/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-vi/custom_strings.xml
new file mode 100644
index 0000000..9031cb0
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-vi/custom_strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">Không có hành động</string>
+ <string name="label_action_settings_panel">Bảng cài đặt</string>
+ <string name="label_action_notification_panel">Bảng thông báo</string>
+ <string name="label_action_screenshot">Chụp ảnh màn hình</string>
+ <string name="label_action_region_screenshot">Chụp một phần màn hình</string>
+ <string name="label_action_screenrecord">Ghi lại màn hình</string>
+ <string name="label_action_expanded_desktop">Mở rộng màn hình</string>
+ <string name="label_action_screen_off">Tắt màn hình</string>
+ <string name="label_action_force_close_app">Buộc dừng ứng dụng</string>
+ <string name="label_action_google_assistant">Google Assistant</string>
+ <string name="label_action_in_app_search">Tìm kiếm trong ứng dụng</string>
+ <string name="label_action_flashlight">Đèn pin</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Điểm phát sóng</string>
+ <string name="label_action_last_app">Ứng dụng cuối</string>
+ <string name="label_action_overview">Gần đây</string>
+ <string name="label_action_power_menu">Trình đơn nguồn</string>
+ <string name="label_action_menu">Trình đơn</string>
+ <string name="label_action_back">Quay lại</string>
+ <string name="label_action_home">Trang chủ</string>
+ <string name="label_action_ime_switcher">Thay đổi IME</string>
+ <string name="label_action_stop_screenpinning">Dừng ghim màn hình</string>
+ <string name="label_action_ime_down">Phương thức nhập con trỏ xuống</string>
+ <string name="label_action_ime_left">Phương thức nhập con trỏ trái</string>
+ <string name="label_action_ime_right">Phương thức nhập con trỏ phải</string>
+ <string name="label_action_ime_up">Phương thức nhập con trỏ lên</string>
+ <string name="label_action_volume_panel">Bảng điều chỉnh âm lượng</string>
+ <string name="label_action_clear_notifications">Xóa thông báo</string>
+ <string name="label_action_split_screen">Chia màn hình</string>
+ <string name="label_action_one_handed_mode_left">Chế độ một tay (bên trái)</string>
+ <string name="label_action_one_handed_mode_right">Chế độ một tay (bên phải)</string>
+ <string name="label_action_media_left">Bản nhạc trước</string>
+ <string name="label_action_media_right">Bản nhạc tiếp theo</string>
+ <string name="label_action_assistant_sound_search">Tìm kiếm âm thanh bằng Google</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s đã dừng</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-zh-rCN/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-zh-rCN/custom_strings.xml
new file mode 100644
index 0000000..5276607
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-zh-rCN/custom_strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">无操作</string>
+ <string name="label_action_settings_panel">快速设置面板</string>
+ <string name="label_action_notification_panel">通知面板</string>
+ <string name="label_action_screenshot">屏幕截图</string>
+ <string name="label_action_region_screenshot">局部截图</string>
+ <string name="label_action_screenrecord">屏幕录制</string>
+ <string name="label_action_expanded_desktop">扩展桌面</string>
+ <string name="label_action_screen_off">关闭屏幕</string>
+ <string name="label_action_force_close_app">强制关闭应用</string>
+ <string name="label_action_google_assistant">Google Assistant</string>
+ <string name="label_action_in_app_search">应用内搜索</string>
+ <string name="label_action_flashlight">手电筒</string>
+ <string name="label_action_bluetooth">蓝牙</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">热点</string>
+ <string name="label_action_last_app">最后使用的应用</string>
+ <string name="label_action_overview">最近任务</string>
+ <string name="label_action_power_menu">电源菜单</string>
+ <string name="label_action_menu">菜单</string>
+ <string name="label_action_back">返回</string>
+ <string name="label_action_home">主屏幕</string>
+ <string name="label_action_ime_switcher">输入法切换器</string>
+ <string name="label_action_stop_screenpinning">停止屏幕固定</string>
+ <string name="label_action_ime_down">输入法光标向下</string>
+ <string name="label_action_ime_left">输入法光标向左</string>
+ <string name="label_action_ime_right">输入法光标向右</string>
+ <string name="label_action_ime_up">输入法光标向上</string>
+ <string name="label_action_volume_panel">音量面板</string>
+ <string name="label_action_clear_notifications">清除通知</string>
+ <string name="label_action_split_screen">分屏</string>
+ <string name="label_action_one_handed_mode_left">单手模式(左侧)</string>
+ <string name="label_action_one_handed_mode_right">单手模式(右侧)</string>
+ <string name="label_action_media_left">上一曲</string>
+ <string name="label_action_media_right">下一曲</string>
+ <string name="label_action_assistant_sound_search">Google 语音搜索</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">已停止\"%s\"</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-zh-rHK/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-zh-rHK/custom_strings.xml
new file mode 100644
index 0000000..a70cbac
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-zh-rHK/custom_strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">無動作</string>
+ <string name="label_action_settings_panel">設定面板</string>
+ <string name="label_action_notification_panel">通知面板</string>
+ <string name="label_action_screenshot">截圖</string>
+ <string name="label_action_region_screenshot">部分截圖</string>
+ <string name="label_action_screenrecord">錄製螢幕</string>
+ <string name="label_action_expanded_desktop">擴展桌面</string>
+ <string name="label_action_screen_off">關閉螢幕</string>
+ <string name="label_action_force_close_app">強制關閉應用程式</string>
+ <string name="label_action_google_assistant">Google語音助手</string>
+ <string name="label_action_in_app_search">應用程式內搜尋</string>
+ <string name="label_action_flashlight">手電筒</string>
+ <string name="label_action_bluetooth">藍芽</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">熱點</string>
+ <string name="label_action_last_app">最後一個應用程式</string>
+ <string name="label_action_overview">最近使用的應用程式</string>
+ <string name="label_action_power_menu">電源選單</string>
+ <string name="label_action_menu">功能表</string>
+ <string name="label_action_back">返回</string>
+ <string name="label_action_home">首頁</string>
+ <string name="label_action_ime_switcher">輸入法切換</string>
+ <string name="label_action_stop_screenpinning">停止螢幕固定</string>
+ <string name="label_action_ime_down">輸入游標向下</string>
+ <string name="label_action_ime_left">輸入游標向左</string>
+ <string name="label_action_ime_right">輸入游標向右</string>
+ <string name="label_action_ime_up">輸入游標向上</string>
+ <string name="label_action_volume_panel">音量面板</string>
+ <string name="label_action_clear_notifications">清除通知</string>
+ <string name="label_action_split_screen">分割視窗</string>
+ <string name="label_action_one_handed_mode_left">單手模式 (左側)</string>
+ <string name="label_action_one_handed_mode_right">單手模式 (右側)</string>
+ <string name="label_action_media_left">上一首曲目</string>
+ <string name="label_action_media_right">下一首曲目</string>
+ <string name="label_action_assistant_sound_search">Google 聲音搜尋</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s 已終止</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-zh-rSG/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-zh-rSG/custom_strings.xml
new file mode 100644
index 0000000..35ec159
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-zh-rSG/custom_strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">無操作</string>
+ <string name="label_action_settings_panel">設定面板</string>
+ <string name="label_action_notification_panel">通知面板</string>
+ <string name="label_action_screenshot">截圖</string>
+ <string name="label_action_region_screenshot">部分截圖</string>
+ <string name="label_action_screenrecord">錄製螢幕</string>
+ <string name="label_action_expanded_desktop">延伸桌面</string>
+ <string name="label_action_screen_off">關閉螢幕</string>
+ <string name="label_action_force_close_app">強制關閉應用程式</string>
+ <string name="label_action_google_assistant">Google 個人助理</string>
+ <string name="label_action_in_app_search">應用程式內搜尋</string>
+ <string name="label_action_flashlight">手電筒</string>
+ <string name="label_action_bluetooth">藍牙</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">熱點</string>
+ <string name="label_action_last_app">最後一個應用程式</string>
+ <string name="label_action_overview">最近的應用程式</string>
+ <string name="label_action_power_menu">電源選單</string>
+ <string name="label_action_menu">選單</string>
+ <string name="label_action_back">返回</string>
+ <string name="label_action_home">主畫面</string>
+ <string name="label_action_ime_switcher">輸入法切換</string>
+ <string name="label_action_stop_screenpinning">停止螢幕固定</string>
+ <string name="label_action_ime_down">輸入法游標向下</string>
+ <string name="label_action_ime_left">輸入法游標向左</string>
+ <string name="label_action_ime_right">輸入法游標向右</string>
+ <string name="label_action_ime_up">輸入法游標向上</string>
+ <string name="label_action_volume_panel">音量面板</string>
+ <string name="label_action_clear_notifications">清除通知</string>
+ <string name="label_action_split_screen">分割畫面</string>
+ <string name="label_action_one_handed_mode_left">單手模式 (左側)</string>
+ <string name="label_action_one_handed_mode_right">單手模式 (右側)</string>
+ <string name="label_action_media_left">上一首曲目</string>
+ <string name="label_action_media_right">下一首曲目</string>
+ <string name="label_action_assistant_sound_search">Google 聲音搜尋</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s 已終止</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-zh-rTW/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-zh-rTW/custom_strings.xml
new file mode 100644
index 0000000..427cc41
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-zh-rTW/custom_strings.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">無動作</string>
+ <string name="label_action_settings_panel">設定面板</string>
+ <string name="label_action_notification_panel">通知面板</string>
+ <string name="label_action_screenshot">擷取螢幕畫面</string>
+ <string name="label_action_region_screenshot">部分螢幕截圖</string>
+ <string name="label_action_screenrecord">錄製螢幕</string>
+ <string name="label_action_expanded_desktop">延伸桌面</string>
+ <string name="label_action_screen_off">關閉螢幕</string>
+ <string name="label_action_force_close_app">強制關閉應用程式</string>
+ <string name="label_action_google_assistant">Google 個人助理</string>
+ <string name="label_action_in_app_search">應用程式內搜尋</string>
+ <string name="label_action_flashlight">手電筒</string>
+ <string name="label_action_bluetooth">藍牙</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">熱點</string>
+ <string name="label_action_last_app">最後一個應用程式</string>
+ <string name="label_action_overview">總覽</string>
+ <string name="label_action_power_menu">電源選單</string>
+ <string name="label_action_menu">選單</string>
+ <string name="label_action_back">返回</string>
+ <string name="label_action_home">主畫面</string>
+ <string name="label_action_ime_switcher">輸入法切換</string>
+ <string name="label_action_stop_screenpinning">停止螢幕固定</string>
+ <string name="label_action_ime_down">輸入法游標向下</string>
+ <string name="label_action_ime_left">輸入法游標向左</string>
+ <string name="label_action_ime_right">輸入法游標向右</string>
+ <string name="label_action_ime_up">輸入法游標向上</string>
+ <string name="label_action_volume_panel">音量面板</string>
+ <string name="label_action_clear_notifications">清除通知</string>
+ <string name="label_action_split_screen">分割畫面</string>
+ <string name="label_action_one_handed_mode_left">單手模式 (左側)</string>
+ <string name="label_action_one_handed_mode_right">單手模式 (右側)</string>
+ <string name="label_action_media_left">上一首曲目</string>
+ <string name="label_action_media_right">下一首曲目</string>
+ <string name="label_action_assistant_sound_search">Google 聲音搜尋</string>
+ <!-- App killed message -->
+ <string name="app_killed_message">%s 已終止</string>
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values-zu/custom_strings.xml b/packages/SystemUI/res-hwkeys/values-zu/custom_strings.xml
new file mode 100644
index 0000000..f64c1b3
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values-zu/custom_strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--Generated by crowdin.com-->
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Bindable action labels -->
+ <!-- App killed message -->
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values/custom_colors.xml b/packages/SystemUI/res-hwkeys/values/custom_colors.xml
new file mode 100644
index 0000000..9ce6be3
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values/custom_colors.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The DirtyUnicorns 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.
+-->
+<resources>
+ <!-- SmartBar icon colors -->
+ <color name="icon_color_default">#fff</color>
+ <color name="icon_color_dark">@android:color/black</color>
+ <color name="icon_color_no_action">@color/icon_color_default</color>
+ <color name="icon_color_settings_panel">@color/icon_color_default</color>
+ <color name="icon_color_notification_panel">@color/icon_color_default</color>
+ <color name="icon_color_screenshot">@color/icon_color_default</color>
+ <color name="icon_color_region_screenshot">@color/icon_color_default</color>
+ <color name="icon_color_screenrecord">@color/icon_color_default</color>
+ <color name="icon_color_expanded_desktop">@color/icon_color_default</color>
+ <color name="icon_color_screen_off">@color/icon_color_default</color>
+ <color name="icon_color_force_close_app">@color/icon_color_default</color>
+ <color name="icon_color_search_assistant">@color/icon_color_default</color>
+ <color name="icon_color_google_assistant">@color/icon_color_default</color>
+ <color name="icon_color_voice_search">@color/icon_color_default</color>
+ <color name="icon_color_in_app_search">@color/icon_color_default</color>
+ <color name="icon_color_flashlight">@color/icon_color_default</color>
+ <color name="icon_color_bluetooth">@color/icon_color_default</color>
+ <color name="icon_color_wifi">@color/icon_color_default</color>
+ <color name="icon_color_hotspot">@color/icon_color_default</color>
+ <color name="icon_color_last_app">@color/icon_color_default</color>
+ <color name="icon_color_overview">@color/icon_color_default</color>
+ <color name="icon_color_power_menu">@color/icon_color_default</color>
+ <color name="icon_color_menu">@color/icon_color_default</color>
+ <color name="icon_color_back">@color/icon_color_default</color>
+ <color name="icon_color_home">@color/icon_color_default</color>
+ <color name="icon_color_ime_switcher">@color/icon_color_default</color>
+ <color name="icon_color_stop_screenpinning">@color/icon_color_default</color>
+ <color name="icon_color_ime_down">@color/icon_color_default</color>
+ <color name="icon_color_ime_left">@color/icon_color_default</color>
+ <color name="icon_color_ime_right">@color/icon_color_default</color>
+ <color name="icon_color_ime_up">@color/icon_color_default</color>
+ <color name="icon_color_volume_panel">@color/icon_color_default</color>
+ <color name="icon_color_clear_notifications">@color/icon_color_default</color>
+ <color name="icon_color_editing_smartbar">@color/icon_color_default</color>
+ <color name="icon_color_split_screen">@color/icon_color_default</color>
+ <color name="icon_color_one_handed_mode">@color/icon_color_default</color>
+
+</resources>
diff --git a/packages/SystemUI/res-hwkeys/values/custom_strings.xml b/packages/SystemUI/res-hwkeys/values/custom_strings.xml
new file mode 100644
index 0000000..c2d2a92
--- /dev/null
+++ b/packages/SystemUI/res-hwkeys/values/custom_strings.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014-2015 The Dirty Unicorns Project
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ -->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- Bindable action labels -->
+ <string name="label_action_no_action">No action</string>
+ <string name="label_action_settings_panel">QS panel</string>
+ <string name="label_action_notification_panel">Notification panel</string>
+ <string name="label_action_screenshot">Screenshot</string>
+ <string name="label_action_region_screenshot">Partial screenshot</string>
+ <string name="label_action_screenrecord">Record screen</string>
+ <string name="label_action_expanded_desktop">Expanded desktop</string>
+ <string name="label_action_screen_off">Turn off screen</string>
+ <string name="label_action_force_close_app">Force close app</string>
+ <string name="label_action_google_assistant">Google assistant</string>
+ <string name="label_action_in_app_search">In-app search</string>
+ <string name="label_action_flashlight">Flashlight</string>
+ <string name="label_action_bluetooth">Bluetooth</string>
+ <string name="label_action_wifi">WiFi</string>
+ <string name="label_action_hotspot">Hotspot</string>
+ <string name="label_action_last_app">Last app</string>
+ <string name="label_action_overview">Recents</string>
+ <string name="label_action_power_menu">Power menu</string>
+ <string name="label_action_menu">Menu</string>
+ <string name="label_action_back">Back</string>
+ <string name="label_action_home">Home</string>
+ <string name="label_action_ime_switcher">IME changer</string>
+ <string name="label_action_stop_screenpinning">Stop screen pinning</string>
+ <string name="label_action_ime_down">Input method cursor down</string>
+ <string name="label_action_ime_left">Input method cursor left</string>
+ <string name="label_action_ime_right">Input method cursor right</string>
+ <string name="label_action_ime_up">Input method cursor up</string>
+ <string name="label_action_volume_panel">Volume panel</string>
+ <string name="label_action_clear_notifications">Clear notifications</string>
+ <string name="label_action_split_screen">Split screen</string>
+ <string name="label_action_one_handed_mode_left">One handed mode (left side)</string>
+ <string name="label_action_one_handed_mode_right">One handed mode (right side)</string>
+ <string name="label_action_media_left">Previous track</string>
+ <string name="label_action_media_right">Next track</string>
+ <string name="label_action_assistant_sound_search">Google sound search</string>
+
+ <!-- App killed message -->
+ <string name="app_killed_message">%s killed</string>
+
+</resources>
diff --git a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/binary_thumbnail.png b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/binary_thumbnail.png
new file mode 100644
index 0000000..3fd5a11
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/binary_thumbnail.png
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/bliss_thumbnail.png b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/bliss_thumbnail.png
new file mode 100644
index 0000000..aaedfe4
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/bliss_thumbnail.png
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/custom_num_clock_thumbnail.png b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/custom_num_clock_thumbnail.png
new file mode 100644
index 0000000..6e193ff
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/custom_num_clock_thumbnail.png
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/default_bold_thumbnail.png b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/default_bold_thumbnail.png
new file mode 100644
index 0000000..53d9df6
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/default_bold_thumbnail.png
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/divided_lines_thumbnail.png b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/divided_lines_thumbnail.png
new file mode 100644
index 0000000..8e5e5e4
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/divided_lines_thumbnail.png
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/dot_thumbnail.png b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/dot_thumbnail.png
new file mode 100644
index 0000000..0c8385e
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/dot_thumbnail.png
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/mmnl_box.png b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/mmnl_box.png
new file mode 100644
index 0000000..1bec777
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/mmnl_box.png
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/mmnl_minimal.png b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/mmnl_minimal.png
new file mode 100644
index 0000000..75541f5
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/mmnl_minimal.png
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/oneplus_minimal_thumbnail.png b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/oneplus_minimal_thumbnail.png
new file mode 100644
index 0000000..d2c9c36
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/oneplus_minimal_thumbnail.png
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/oneplus_numbers_thumbnail.png b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/oneplus_numbers_thumbnail.png
new file mode 100644
index 0000000..cb96b12
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/oneplus_numbers_thumbnail.png
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/oneplus_roman_thumbnail.png b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/oneplus_roman_thumbnail.png
new file mode 100644
index 0000000..9d45505
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/oneplus_roman_thumbnail.png
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/op_analog_thumbnail.png b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/op_analog_thumbnail.png
new file mode 100644
index 0000000..657df3d
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/op_analog_thumbnail.png
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/op_minimalism_thumbnail.png b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/op_minimalism_thumbnail.png
new file mode 100644
index 0000000..13dac3c
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/op_minimalism_thumbnail.png
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/samsung_bold_thumbnail.png b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/samsung_bold_thumbnail.png
new file mode 100644
index 0000000..d52733d
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/samsung_bold_thumbnail.png
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/samsung_thumbnail.png b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/samsung_thumbnail.png
new file mode 100644
index 0000000..447ce2f
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/samsung_thumbnail.png
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/sfuny.png b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/sfuny.png
new file mode 100644
index 0000000..73ee180
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/sfuny.png
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/sneeky_thumbnail.png b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/sneeky_thumbnail.png
new file mode 100644
index 0000000..805bdeb
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/sneeky_thumbnail.png
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/spectrum_thumbnail.png b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/spectrum_thumbnail.png
new file mode 100644
index 0000000..d61948c
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/spectrum_thumbnail.png
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/spidey_thumbnail.png b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/spidey_thumbnail.png
new file mode 100644
index 0000000..3ce7d81
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/spidey_thumbnail.png
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable-xxxhdpi/type_thumbnail.png b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/type_thumbnail.png
new file mode 100644
index 0000000..2bfd655
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable-xxxhdpi/type_thumbnail.png
Binary files differ
diff --git a/packages/SystemUI/res-keyguard/drawable/analog_clock_background.xml b/packages/SystemUI/res-keyguard/drawable/analog_clock_background.xml
new file mode 100644
index 0000000..cdc7a55
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/analog_clock_background.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="oval" >
+
+ <solid android:color="@color/analog_clock_bg_color" />
+ <stroke android:width="3dp"
+ android:color="@android:color/black" />
+ <stroke android:width="2dp"
+ android:color="@android:color/white" />
+</shape>
diff --git a/packages/SystemUI/res-keyguard/drawable/analog_clock_background_dark.xml b/packages/SystemUI/res-keyguard/drawable/analog_clock_background_dark.xml
new file mode 100644
index 0000000..a4b4d83
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/analog_clock_background_dark.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="oval" >
+
+ <solid android:color="@android:color/black" />
+ <stroke android:width="3dp"
+ android:color="@android:color/black" />
+ <stroke android:width="2dp"
+ android:color="@android:color/white" />
+</shape>
diff --git a/packages/SystemUI/res-keyguard/drawable/bliss_clock_dial.xml b/packages/SystemUI/res-keyguard/drawable/bliss_clock_dial.xml
new file mode 100644
index 0000000..72cf4a8
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/bliss_clock_dial.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014-2020 The BlissRoms 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 android:height="150dp" android:viewportHeight="512"
+ android:viewportWidth="512" android:width="150dp"
+ xmlns:aapt="http://schemas.android.com/aapt" xmlns:android="http://schemas.android.com/apk/res/android">
+ <path android:fillType="nonZero" android:pathData="M19.161,256C19.161,125.197 125.197,19.161 256,19.161C386.804,19.161 492.839,125.197 492.839,256C492.839,386.804 386.804,492.839 256,492.839C125.197,492.839 19.161,386.804 19.161,256Z">
+ <aapt:attr name="android:fillColor">
+ <gradient android:centerX="255.99673"
+ android:centerY="255.99959"
+ android:gradientRadius="256.00308" android:type="radial">
+ <item android:color="#FF000000" android:offset="0"/>
+ <item android:color="@*android:color/accent_device_default_light" android:offset="0.67"/>
+ <item android:color="@*android:color/accent_device_default_light" android:offset="0.85"/>
+ <item android:color="@*android:color/accent_device_default_light" android:offset="1"/>
+ </gradient>
+ </aapt:attr>
+ </path>
+ <path android:fillColor="#ffffff" android:fillType="nonZero" android:pathData="M19.955,256.381C20.06,321.437 46.447,380.256 89.091,422.912C131.829,465.639 190.796,492.043 256.001,492.048C321.206,492.043 380.173,465.639 422.912,422.912C465.639,380.173 492.043,321.206 492.048,256.001C492.043,190.796 465.639,131.829 422.912,89.091C380.173,46.364 321.206,19.957 256.001,19.954C190.796,19.957 131.829,46.364 89.091,89.091C46.364,131.829 19.957,190.796 19.954,256.001L19.955,256.381ZM257.49,487.854L256.466,487.854C254.588,487.854 253.066,486.33 253.066,484.452L253.066,472.668C253.066,470.79 254.588,469.266 256.466,469.266L257.49,469.266C259.368,469.266 260.892,470.79 260.892,472.668L260.892,484.452C260.892,486.33 259.368,487.854 257.49,487.854ZM244.032,451.202C240.77,447.938 238.801,443.444 238.801,434.764L238.801,434.642C238.801,421.473 245.079,411.191 257.264,411.191C261.695,411.191 265.205,412.358 268.039,414.267C269.208,415.007 269.943,415.993 269.943,417.531C269.943,419.5 268.281,421.041 266.313,421.041C265.634,421.041 264.961,420.794 264.407,420.484C262.066,418.946 259.91,418.085 257.02,418.085C250.615,418.085 247.046,423.87 246.68,431.747C248.955,429.533 251.909,427.439 257.02,427.439C265.329,427.439 272.035,432.364 272.035,440.984L272.035,441.103C272.035,449.661 265.083,455.754 256.034,455.754C250.74,455.754 246.927,454.094 244.032,451.202ZM139.57,450.497C138.642,451.908 139.032,453.805 140.443,454.733C141.854,455.665 143.751,455.275 144.683,453.864L149.734,446.198C150.666,444.785 150.276,442.888 148.86,441.96C147.452,441.033 145.557,441.42 144.625,442.831L139.57,450.497ZM366.34,453.559C367.162,455.033 369.026,455.559 370.503,454.742C371.979,453.918 372.508,452.054 371.688,450.577L367.216,442.559C366.396,441.08 364.532,440.552 363.055,441.373C361.578,442.197 361.05,444.059 361.872,445.536L366.34,453.559ZM264.468,441.411L264.468,441.289C264.468,436.983 261.019,433.78 255.663,433.78C250.31,433.78 246.927,437.227 246.927,441.35L246.927,441.477C246.927,445.848 250.495,449.168 255.851,449.168C261.206,449.168 264.468,445.848 264.468,441.411ZM450.528,372.559C451.939,373.489 453.836,373.099 454.761,371.691C455.695,370.277 455.306,368.378 453.89,367.448L446.226,362.398C444.818,361.47 442.918,361.858 441.988,363.269C441.059,364.68 441.451,366.577 442.859,367.509L450.528,372.559ZM58.577,366.312C57.101,367.133 56.572,368.998 57.392,370.472C58.216,371.951 60.081,372.477 61.555,371.66L69.574,367.187C71.051,366.366 71.58,364.504 70.759,363.027C69.937,361.55 68.075,361.022 66.597,361.844L58.577,366.312ZM57.798,275.294C56.753,274.615 56.077,273.57 56.077,272.157C56.077,270.185 57.676,268.708 59.647,268.708C60.446,268.708 61.124,268.952 61.738,269.325C64.263,271.107 66.665,271.969 69.618,271.969C75.957,271.969 79.774,266.369 80.022,258.429C77.867,261.014 74.542,262.981 69.925,262.981C60.753,262.981 54.66,257.628 54.66,249.321L54.66,249.197C54.66,240.761 61.185,234.297 70.726,234.297C76.142,234.297 79.65,235.838 82.73,238.857C85.867,242.055 87.899,246.795 87.899,255.29L87.899,255.412C87.899,269.262 81.068,278.862 69.432,278.862C64.571,278.862 61.001,277.447 57.798,275.294ZM423.534,272.896C422.858,272.34 422.301,271.293 422.301,270.185C422.301,268.215 423.964,266.552 425.934,266.552C427.044,266.552 427.842,266.982 428.458,267.536C431.165,270.246 434.243,271.664 438.246,271.664C442.493,271.664 445.693,269.079 445.693,265.137L445.693,265.015C445.693,260.767 441.815,258.368 435.783,258.368L434.243,258.368C432.458,258.368 430.984,256.889 430.984,255.104C430.984,254.118 431.414,253.193 432.583,252.026L442.676,241.256L427.044,241.256C425.199,241.256 423.72,239.78 423.72,237.993C423.72,236.145 425.199,234.668 427.044,234.668L449.079,234.668C451.232,234.668 452.833,235.962 452.833,237.993C452.833,239.78 451.974,240.822 450.68,242.118L440.523,252.641C447.048,253.444 453.204,256.764 453.204,264.705L453.204,264.831C453.204,272.772 447.109,278.494 438.124,278.494C431.782,278.494 427.044,276.28 423.534,272.896ZM38.356,260.892L26.569,260.892C24.691,260.892 23.169,259.37 23.169,257.492L23.169,256.466C23.169,254.588 24.691,253.066 26.569,253.066L38.356,253.066C40.234,253.066 41.756,254.588 41.756,256.466L41.756,257.492C41.756,259.37 40.234,260.892 38.356,260.892ZM484.455,260.892L472.666,260.892C470.788,260.892 469.266,259.37 469.266,257.492L469.266,256.466C469.266,254.588 470.788,253.066 472.666,253.066L484.455,253.066C486.33,253.066 487.854,254.588 487.854,256.466L487.854,257.492C487.854,259.37 486.33,260.892 484.455,260.892ZM79.774,248.887L79.774,248.763C79.774,244.271 76.265,240.822 70.788,240.822C65.433,240.822 62.231,244.396 62.231,248.826L62.231,248.948C62.231,253.444 65.679,256.644 71.033,256.644C76.511,256.644 79.774,253.073 79.774,248.887ZM453.423,146.592C454.899,145.773 455.428,143.909 454.606,142.434C453.787,140.955 451.922,140.427 450.443,141.248L442.425,145.719C440.948,146.541 440.418,148.402 441.242,149.879C442.064,151.356 443.928,151.884 445.4,151.063L453.423,146.592ZM61.475,139.326C60.061,138.396 58.164,138.788 57.238,140.197C56.304,141.608 56.696,143.507 58.106,144.437L65.771,149.485C67.185,150.419 69.079,150.025 70.011,148.616C70.939,147.205 70.55,145.308 69.139,144.378L61.475,139.326ZM236.03,64.835L231.597,66.189C231.165,66.312 230.611,66.373 230.243,66.373C228.458,66.373 226.918,64.897 226.918,63.173C226.918,61.572 227.902,60.341 229.442,59.909L235.969,57.817C237.443,57.387 238.552,57.141 239.658,57.141L239.782,57.141C241.937,57.141 243.539,58.803 243.539,60.893L243.539,97.334C243.539,99.428 241.874,101.09 239.782,101.09C237.751,101.09 236.03,99.428 236.03,97.334L236.03,64.835ZM280.595,100.783L256.156,100.783C253.82,100.783 252.097,99.428 252.097,97.212C252.097,95.735 252.773,94.503 254.066,93.457L267.297,82.192C273.206,77.207 275.362,74.437 275.362,70.559C275.362,66.312 272.347,63.851 268.41,63.851C264.961,63.851 262.559,65.45 259.913,68.65C259.359,69.266 258.497,69.821 257.264,69.821C255.355,69.821 253.82,68.28 253.82,66.373C253.82,65.573 254.125,64.711 254.679,64.033C258.189,59.664 262.19,57.081 268.959,57.081C277.393,57.081 283.178,62.25 283.178,69.944L283.178,70.066C283.178,76.837 279.609,80.531 271.976,86.748L263.113,94.135L280.595,94.135C282.441,94.135 283.92,95.611 283.92,97.457C283.92,99.304 282.441,100.783 280.595,100.783ZM372.428,62.407C373.355,60.996 372.963,59.099 371.552,58.173C370.143,57.241 368.246,57.63 367.316,59.042L362.261,66.708C361.334,68.119 361.726,70.016 363.137,70.945C364.548,71.875 366.445,71.485 367.378,70.075L372.428,62.407ZM145.658,58.33C144.836,56.853 142.974,56.324 141.5,57.146C140.023,57.97 139.49,59.833 140.312,61.309L144.782,69.328C145.606,70.806 147.466,71.335 148.942,70.51C150.419,69.688 150.948,67.825 150.126,66.35L145.658,58.33ZM257.666,42.734L256.025,42.734C254.146,42.734 253.066,41.719 253.066,39.842L253.066,28.066C253.066,26.189 254.146,24.147 256.025,24.147L257.666,24.147C259.544,24.147 260.892,26.189 260.892,28.066L260.892,39.842C260.892,41.719 259.544,42.734 257.666,42.734ZM6,256.001C5.997,186.988 33.994,124.442 79.224,79.224C124.442,33.994 186.988,5.997 256.001,6C325.015,5.997 387.56,33.994 432.778,79.224C478.007,124.442 506.003,186.988 506.001,256.001C506.003,325.015 478.007,387.56 432.778,432.778C387.56,478.007 325.015,506.003 256.001,506.001C186.988,506.003 124.442,478.007 79.224,432.778C33.994,387.56 5.997,325.015 6,256.001Z"/>
+ <path android:fillColor="@*android:color/accent_device_default_light" android:fillType="nonZero" android:pathData="M283.291,346.12C283.424,346.104 283.558,346.095 283.693,346.092C283.012,347.429 282.313,348.756 281.62,350.086C279.946,353.344 277.925,356.44 275.47,359.165C274.614,360.123 273.495,360.791 272.376,361.397C270.731,362.261 268.961,362.864 267.161,363.312C264.052,364.099 260.851,364.472 257.651,364.6C257.192,364.611 256.733,364.647 256.273,364.618C259.604,360.166 263.328,355.957 267.737,352.542C270.006,350.794 272.467,349.282 275.103,348.153C277.075,347.322 279.14,346.73 281.254,346.39C281.929,346.279 282.611,346.208 283.291,346.12ZM228.709,346.12C228.576,346.104 228.441,346.095 228.307,346.092C228.988,347.429 229.686,348.756 230.379,350.086C232.054,353.344 234.074,356.44 236.53,359.165C237.386,360.123 238.504,360.791 239.623,361.397C241.269,362.261 243.039,362.864 244.839,363.312C247.948,364.099 251.149,364.472 254.349,364.6C254.808,364.611 255.267,364.647 255.726,364.618C252.396,360.166 248.672,355.957 244.263,352.542C241.994,350.794 239.533,349.282 236.897,348.153C234.924,347.322 232.859,346.73 230.746,346.39C230.07,346.279 229.388,346.208 228.709,346.12ZM245.326,336.986C245.091,336.79 244.858,336.583 244.584,336.441C244.034,339.727 243.922,343.084 244.219,346.401C244.397,348.311 244.74,350.21 245.304,352.046C245.369,352.242 245.407,352.457 245.54,352.622C245.69,352.84 245.9,353.006 246.104,353.168C246.76,353.683 247.352,354.272 247.984,354.814C248.83,355.61 249.64,356.444 250.454,357.273C251.292,358.142 252.079,359.059 252.853,359.985C253.722,361.014 254.711,362.073 255.573,363.108C255.852,363.423 255.63,358.06 255.573,357.111C254.687,352.203 254.351,351.586 251.996,345.487C250.852,342.527 248.538,340.058 246.269,337.834C245.968,337.536 245.643,337.265 245.326,336.986ZM266.674,336.986C266.909,336.79 267.141,336.583 267.416,336.441C267.966,339.727 268.077,343.084 267.781,346.401C267.603,348.311 267.259,350.21 266.696,352.046C266.63,352.242 266.592,352.457 266.459,352.622C266.309,352.84 266.1,353.006 265.895,353.168C265.239,353.683 264.648,354.272 264.016,354.814C263.17,355.61 262.36,356.444 261.546,357.273C260.707,358.142 259.921,359.059 259.146,359.985C258.277,361.014 257.429,362.06 256.568,363.094C256.289,363.41 256.466,357.984 256.523,357.034C257.239,352.138 257.682,350.783 260.207,345.317C261.369,342.8 263.461,340.058 265.73,337.834C266.031,337.536 266.356,337.265 266.674,336.986ZM256.158,330.683C256.813,331.386 257.35,332.193 257.827,333.026C259.513,335.971 260.227,339.961 260.206,343.692C259.589,344.793 259.377,345.232 258.908,346.406C258.143,348.322 257.422,350.264 256.947,352.275C256.557,353.818 256.349,355.398 256.118,356.971C256.097,357.105 256.066,357.237 256.032,357.369C255.804,355.864 255.56,354.359 255.243,352.87C254.959,351.545 253.461,347.218 253.097,346.356C252.808,345.684 251.979,344 251.996,343.79C252.208,340.014 252.962,335.96 254.784,332.854C255.217,332.115 255.618,331.35 256.158,330.683ZM276.575,338.286C276.834,338.178 277.084,338.044 277.357,337.975C277.346,340.686 276.596,343.343 275.494,345.802C275.265,346.32 275.022,346.831 274.786,347.346C274.709,347.578 274.462,347.661 274.264,347.761C273.255,348.207 272.274,348.713 271.325,349.275C269.989,350.044 268.756,350.974 267.481,351.835C267.673,351.078 267.812,350.308 267.965,349.542C268.31,347.822 268.464,346.068 268.512,344.317C268.527,344.185 268.521,344.032 268.622,343.934C268.911,343.617 269.23,343.328 269.544,343.034C271.104,341.554 272.813,340.216 274.696,339.168C275.299,338.827 275.938,338.556 276.575,338.286ZM235.424,338.286C235.166,338.178 234.916,338.044 234.642,337.975C234.653,340.686 235.403,343.343 236.506,345.802C236.734,346.32 236.977,346.831 237.214,347.346C237.291,347.578 237.538,347.661 237.736,347.761C238.744,348.207 239.726,348.713 240.674,349.275C242.011,350.044 243.243,350.974 244.519,351.835C244.326,351.078 244.187,350.308 244.034,349.542C243.69,347.822 243.536,346.068 243.488,344.317C243.472,344.185 243.478,344.032 243.378,343.934C243.088,343.617 242.77,343.328 242.456,343.034C240.896,341.554 239.187,340.216 237.304,339.168C236.701,338.827 236.062,338.556 235.424,338.286Z"/>
+</vector>
diff --git a/packages/SystemUI/res-keyguard/drawable/bliss_clock_hand_hour.xml b/packages/SystemUI/res-keyguard/drawable/bliss_clock_hand_hour.xml
new file mode 100644
index 0000000..babb490
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/bliss_clock_hand_hour.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014-2020 The BlissRoms 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 android:height="150dp" android:viewportHeight="512"
+ android:viewportWidth="512" android:width="150dp" xmlns:android="http://schemas.android.com/apk/res/android">
+ <path android:fillColor="@*android:color/accent_device_default_light" android:pathData="M253.23,150.93C253.05,149.09 254.03,146.94 255.99,146.53C257.99,146.83 258.92,149.09 258.78,150.9C259.2,182.17 259.66,213.44 260.12,244.71C264.24,246.48 267.54,250.34 267.84,254.93C268.46,260.13 265.09,265.06 260.45,267.18C260.48,271.13 260.55,275.07 260.61,279.02C257.53,279.02 254.46,279.02 251.39,279.02C251.44,275.07 251.51,271.12 251.55,267.17C247.59,265.3 244.43,261.52 244.15,257.04C243.54,251.73 247.05,246.71 251.87,244.71C252.33,213.45 252.81,182.19 253.23,150.93M251.64,247.63C245.29,250.59 244.88,260.56 251,263.99C257.17,268.34 266.56,262.5 265.37,255.04C264.99,248.63 257.21,244.44 251.64,247.63Z"/>
+</vector>
diff --git a/packages/SystemUI/res-keyguard/drawable/bliss_clock_hand_minute.xml b/packages/SystemUI/res-keyguard/drawable/bliss_clock_hand_minute.xml
new file mode 100644
index 0000000..995d4ed
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/bliss_clock_hand_minute.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014-2020 The BlissRoms 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 android:height="150dp" android:viewportHeight="512"
+ android:viewportWidth="512" android:width="150dp" xmlns:android="http://schemas.android.com/apk/res/android">
+ <path android:fillColor="#ffffff" android:pathData="M253.87,106.81C253.93,105.22 254.68,102.57 256.79,103.23C257.5,104.32 258.18,105.53 258.09,106.89C258.8,152.82 259.42,198.76 260.12,244.69C264.21,246.5 267.54,250.31 267.84,254.91C268.48,260.13 265.08,265.04 260.45,267.2C260.48,271.14 260.55,275.08 260.61,279.02C257.53,279.02 254.46,279.02 251.38,279.02C251.44,275.08 251.51,271.14 251.54,267.2C247.61,265.28 244.42,261.55 244.15,257.05C243.53,251.72 247.07,246.74 251.87,244.69C252.56,198.73 253.17,152.77 253.87,106.81M251.63,247.63C245.3,250.6 244.89,260.55 250.99,263.98C257.18,268.36 266.59,262.47 265.37,255C264.97,248.61 257.19,244.44 251.63,247.63Z"/>
+</vector>
diff --git a/packages/SystemUI/res-keyguard/drawable/custom_num_clock_dial.xml b/packages/SystemUI/res-keyguard/drawable/custom_num_clock_dial.xml
new file mode 100644
index 0000000..9167f7d
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/custom_num_clock_dial.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Dirty Unicorns 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="150dp"
+ android:height="150dp"
+ android:viewportWidth="512.000000"
+ android:viewportHeight="512.000000">
+
+ <path
+ android:fillColor="@color/analog_clock_border_color"
+ android:strokeWidth="1"
+ android:pathData="M 226.62569,505.13671 C 198.56805,501.89539 168.99118,492.98183 143.16208,480.01665 67.497678,441.82996 16.143235,367.98896 6.8244942,283.91749 c -1.316804,-11.74971 -1.316804,-43.96019 0,-55.70999 C 19.688484,111.92565 111.86314,19.750933 228.14503,6.8870126 c 11.74982,-1.3168141 43.9603,-1.3168141 55.71002,0 C 400.13693,19.852198 492.21027,111.92565 505.17558,228.2075 c 1.3167,11.7498 1.3167,43.96028 0,55.70999 -12.86399,116.28194 -105.03865,208.45657 -221.32053,221.32057 -10.73687,1.21547 -46.39128,1.11419 -57.22936,-0.10135 z" />
+ <path
+ android:fillColor="@color/analog_clock_face_color"
+ android:strokeWidth="1"
+ android:pathData="M 224.59985,484.37239 C 175.98023,477.7885 131.00706,455.8084 95.555283,421.26818 75.195834,401.31386 61.521518,382.57508 49.366638,357.86008 33.261347,325.14319 26.069735,293.64168 26.069735,256.06278 c 0,-37.57891 7.191612,-69.08035 23.296903,-101.79732 12.15488,-24.71491 25.829196,-43.45377 46.188645,-63.408014 35.856947,-34.945365 80.830107,-56.722924 130.361267,-63.205557 15.4976,-2.025773 44.66931,-2.025773 60.1668,0 49.53126,6.482633 94.50442,28.260192 130.36136,63.205557 20.35945,19.954244 34.03377,38.693104 46.18865,63.408014 16.10519,32.71697 23.2969,64.21841 23.2969,101.79732 0,43.25123 -10.23038,81.23529 -31.7041,117.80128 -12.35741,20.8659 -33.83114,45.78351 -52.87378,61.1797 -32.81828,26.53823 -73.53718,43.96019 -115.26903,49.4299 -14.88981,1.92459 -46.79634,1.82324 -61.4835,-0.10127 z" />
+ <path
+ android:fillColor="@color/analog_clock_border_color"
+ android:pathData="M 256 37.746094 A 2.5 2.5 0 0 0 253.5 40.246094 A 2.5 2.5 0 0 0 256 42.746094 A 2.5 2.5 0 0 0 258.5 40.246094 A 2.5 2.5 0 0 0 256 37.746094 z M 233.43555 38.929688 A 2.5 2.5 0 0 0 233.18555 38.943359 A 2.5 2.5 0 0 0 230.96094 41.689453 A 2.5 2.5 0 0 0 233.70898 43.914062 A 2.5 2.5 0 0 0 235.93359 41.167969 A 2.5 2.5 0 0 0 233.43555 38.929688 z M 278.63672 38.929688 A 2.5 2.5 0 0 0 276.06641 41.167969 A 2.5 2.5 0 0 0 278.29102 43.914062 A 2.5 2.5 0 0 0 281.03906 41.689453 A 2.5 2.5 0 0 0 278.81445 38.943359 A 2.5 2.5 0 0 0 278.63672 38.929688 z M 211.11914 42.460938 A 2.5 2.5 0 0 0 210.62305 42.515625 A 2.5 2.5 0 0 0 208.69727 45.480469 A 2.5 2.5 0 0 0 211.66211 47.40625 A 2.5 2.5 0 0 0 213.58789 44.441406 A 2.5 2.5 0 0 0 211.11914 42.460938 z M 300.95508 42.462891 A 2.5 2.5 0 0 0 298.41211 44.441406 A 2.5 2.5 0 0 0 300.33789 47.40625 A 2.5 2.5 0 0 0 303.30273 45.480469 A 2.5 2.5 0 0 0 301.37695 42.515625 A 2.5 2.5 0 0 0 300.95508 42.462891 z M 189.29297 48.306641 A 2.5 2.5 0 0 0 188.55664 48.429688 A 2.5 2.5 0 0 0 186.95117 51.578125 A 2.5 2.5 0 0 0 190.10156 53.183594 A 2.5 2.5 0 0 0 191.70703 50.033203 A 2.5 2.5 0 0 0 189.29297 48.306641 z M 322.7793 48.308594 A 2.5 2.5 0 0 0 320.29297 50.033203 A 2.5 2.5 0 0 0 321.89844 53.183594 A 2.5 2.5 0 0 0 325.04883 51.578125 A 2.5 2.5 0 0 0 323.44336 48.429688 A 2.5 2.5 0 0 0 322.7793 48.308594 z M 168.19727 56.400391 A 2.5 2.5 0 0 0 167.22852 56.615234 A 2.5 2.5 0 0 0 165.96094 59.916016 A 2.5 2.5 0 0 0 169.26172 61.183594 A 2.5 2.5 0 0 0 170.5293 57.882812 A 2.5 2.5 0 0 0 168.19727 56.400391 z M 343.625 56.402344 A 2.5 2.5 0 0 0 341.4707 57.882812 A 2.5 2.5 0 0 0 342.73828 61.183594 A 2.5 2.5 0 0 0 346.03906 59.916016 A 2.5 2.5 0 0 0 344.77148 56.615234 A 2.5 2.5 0 0 0 343.625 56.402344 z M 148.06445 66.652344 A 2.5 2.5 0 0 0 146.87305 66.986328 A 2.5 2.5 0 0 0 145.95898 70.402344 A 2.5 2.5 0 0 0 149.37305 71.316406 A 2.5 2.5 0 0 0 150.28906 67.902344 A 2.5 2.5 0 0 0 148.06445 66.652344 z M 363.75781 66.654297 A 2.5 2.5 0 0 0 361.71094 67.902344 A 2.5 2.5 0 0 0 362.62695 71.316406 A 2.5 2.5 0 0 0 366.04102 70.402344 A 2.5 2.5 0 0 0 365.12695 66.986328 A 2.5 2.5 0 0 0 363.75781 66.654297 z M 129.11328 78.953125 A 2.5 2.5 0 0 0 127.71484 79.429688 A 2.5 2.5 0 0 0 127.16016 82.921875 A 2.5 2.5 0 0 0 130.65234 83.474609 A 2.5 2.5 0 0 0 131.20508 79.982422 A 2.5 2.5 0 0 0 129.11328 78.953125 z M 382.71094 78.955078 A 2.5 2.5 0 0 0 380.79492 79.982422 A 2.5 2.5 0 0 0 381.34766 83.474609 A 2.5 2.5 0 0 0 384.83984 82.921875 A 2.5 2.5 0 0 0 384.28516 79.429688 A 2.5 2.5 0 0 0 382.71094 78.955078 z M 111.55078 93.166016 A 2.5 2.5 0 0 0 109.96094 93.806641 A 2.5 2.5 0 0 0 109.77539 97.337891 A 2.5 2.5 0 0 0 113.30664 97.521484 A 2.5 2.5 0 0 0 113.49023 93.992188 A 2.5 2.5 0 0 0 111.55078 93.166016 z M 400.27344 93.166016 A 2.5 2.5 0 0 0 398.50977 93.992188 A 2.5 2.5 0 0 0 398.69336 97.521484 A 2.5 2.5 0 0 0 402.22461 97.337891 A 2.5 2.5 0 0 0 402.03906 93.806641 A 2.5 2.5 0 0 0 400.27344 93.166016 z M 95.570312 109.13477 A 2.5 2.5 0 0 0 93.806641 109.96094 A 2.5 2.5 0 0 0 93.992188 113.49023 A 2.5 2.5 0 0 0 97.521484 113.30664 A 2.5 2.5 0 0 0 97.335938 109.77539 A 2.5 2.5 0 0 0 95.570312 109.13477 z M 416.25391 109.13477 A 2.5 2.5 0 0 0 414.66406 109.77539 A 2.5 2.5 0 0 0 414.47852 113.30664 A 2.5 2.5 0 0 0 418.00781 113.49023 A 2.5 2.5 0 0 0 418.19336 109.96094 A 2.5 2.5 0 0 0 416.25391 109.13477 z M 430.47656 126.68359 A 2.5 2.5 0 0 0 429.07812 127.16016 A 2.5 2.5 0 0 0 428.52539 130.65234 A 2.5 2.5 0 0 0 432.01758 131.20508 A 2.5 2.5 0 0 0 432.57031 127.71484 A 2.5 2.5 0 0 0 430.47656 126.68359 z M 81.345703 126.68555 A 2.5 2.5 0 0 0 79.429688 127.71484 A 2.5 2.5 0 0 0 79.982422 131.20508 A 2.5 2.5 0 0 0 83.474609 130.65234 A 2.5 2.5 0 0 0 82.921875 127.16016 A 2.5 2.5 0 0 0 81.345703 126.68555 z M 442.78906 145.625 A 2.5 2.5 0 0 0 441.59766 145.95898 A 2.5 2.5 0 0 0 440.68359 149.37305 A 2.5 2.5 0 0 0 444.09766 150.28906 A 2.5 2.5 0 0 0 445.01367 146.87305 A 2.5 2.5 0 0 0 442.78906 145.625 z M 69.035156 145.62695 A 2.5 2.5 0 0 0 66.986328 146.87305 A 2.5 2.5 0 0 0 67.902344 150.28906 A 2.5 2.5 0 0 0 71.316406 149.37305 A 2.5 2.5 0 0 0 70.402344 145.95898 A 2.5 2.5 0 0 0 69.035156 145.62695 z M 453.05273 165.74609 A 2.5 2.5 0 0 0 452.08398 165.96094 A 2.5 2.5 0 0 0 450.81641 169.26172 A 2.5 2.5 0 0 0 454.11719 170.5293 A 2.5 2.5 0 0 0 455.38477 167.22852 A 2.5 2.5 0 0 0 453.05273 165.74609 z M 58.769531 165.74805 A 2.5 2.5 0 0 0 56.615234 167.22852 A 2.5 2.5 0 0 0 57.882812 170.5293 A 2.5 2.5 0 0 0 61.183594 169.26172 A 2.5 2.5 0 0 0 59.916016 165.96094 A 2.5 2.5 0 0 0 58.769531 165.74805 z M 461.1582 186.82812 A 2.5 2.5 0 0 0 460.42188 186.95117 A 2.5 2.5 0 0 0 458.81641 190.10156 A 2.5 2.5 0 0 0 461.9668 191.70703 A 2.5 2.5 0 0 0 463.57031 188.55664 A 2.5 2.5 0 0 0 461.1582 186.82812 z M 50.914062 186.83008 A 2.5 2.5 0 0 0 48.429688 188.55664 A 2.5 2.5 0 0 0 50.033203 191.70703 A 2.5 2.5 0 0 0 53.183594 190.10156 A 2.5 2.5 0 0 0 51.578125 186.95117 A 2.5 2.5 0 0 0 50.914062 186.83008 z M 467.01562 208.64258 A 2.5 2.5 0 0 0 466.51953 208.69727 A 2.5 2.5 0 0 0 464.59375 211.66211 A 2.5 2.5 0 0 0 467.55859 213.58789 A 2.5 2.5 0 0 0 469.48438 210.62305 A 2.5 2.5 0 0 0 467.01562 208.64258 z M 45.058594 208.64453 A 2.5 2.5 0 0 0 42.515625 210.62305 A 2.5 2.5 0 0 0 44.441406 213.58789 A 2.5 2.5 0 0 0 47.40625 211.66211 A 2.5 2.5 0 0 0 45.480469 208.69727 A 2.5 2.5 0 0 0 45.058594 208.64453 z M 470.55859 230.94727 A 2.5 2.5 0 0 0 470.31055 230.96094 A 2.5 2.5 0 0 0 468.08594 233.70898 A 2.5 2.5 0 0 0 470.83203 235.93359 A 2.5 2.5 0 0 0 473.05859 233.18555 A 2.5 2.5 0 0 0 470.55859 230.94727 z M 41.513672 230.94922 A 2.5 2.5 0 0 0 38.941406 233.18555 A 2.5 2.5 0 0 0 41.167969 235.93359 A 2.5 2.5 0 0 0 43.914062 233.70898 A 2.5 2.5 0 0 0 41.689453 230.96094 A 2.5 2.5 0 0 0 41.513672 230.94922 z M 40.246094 253.5 A 2.5 2.5 0 0 0 37.746094 256 A 2.5 2.5 0 0 0 40.246094 258.5 A 2.5 2.5 0 0 0 42.746094 256 A 2.5 2.5 0 0 0 40.246094 253.5 z M 471.75391 253.5 A 2.5 2.5 0 0 0 469.25391 256 A 2.5 2.5 0 0 0 471.75391 258.5 A 2.5 2.5 0 0 0 474.25391 256 A 2.5 2.5 0 0 0 471.75391 253.5 z M 41.416016 276.05273 A 2.5 2.5 0 0 0 41.167969 276.06641 A 2.5 2.5 0 0 0 38.941406 278.81445 A 2.5 2.5 0 0 0 41.689453 281.03906 A 2.5 2.5 0 0 0 43.914062 278.29102 A 2.5 2.5 0 0 0 41.416016 276.05273 z M 470.65625 276.05469 A 2.5 2.5 0 0 0 468.08594 278.29102 A 2.5 2.5 0 0 0 470.31055 281.03906 A 2.5 2.5 0 0 0 473.05859 278.81445 A 2.5 2.5 0 0 0 470.83203 276.06641 A 2.5 2.5 0 0 0 470.65625 276.05469 z M 44.9375 298.35742 A 2.5 2.5 0 0 0 44.441406 298.41211 A 2.5 2.5 0 0 0 42.515625 301.37695 A 2.5 2.5 0 0 0 45.480469 303.30273 A 2.5 2.5 0 0 0 47.40625 300.33789 A 2.5 2.5 0 0 0 44.9375 298.35742 z M 467.13477 298.35938 A 2.5 2.5 0 0 0 464.59375 300.33789 A 2.5 2.5 0 0 0 466.51953 303.30273 A 2.5 2.5 0 0 0 469.48438 301.37695 A 2.5 2.5 0 0 0 467.55859 298.41211 A 2.5 2.5 0 0 0 467.13477 298.35938 z M 50.771484 320.17188 A 2.5 2.5 0 0 0 50.033203 320.29297 A 2.5 2.5 0 0 0 48.429688 323.44336 A 2.5 2.5 0 0 0 51.578125 325.04883 A 2.5 2.5 0 0 0 53.183594 321.89844 A 2.5 2.5 0 0 0 50.771484 320.17188 z M 461.30273 320.17383 A 2.5 2.5 0 0 0 458.81641 321.89844 A 2.5 2.5 0 0 0 460.42188 325.04883 A 2.5 2.5 0 0 0 463.57031 323.44336 A 2.5 2.5 0 0 0 461.9668 320.29297 A 2.5 2.5 0 0 0 461.30273 320.17383 z M 58.851562 341.25586 A 2.5 2.5 0 0 0 57.882812 341.4707 A 2.5 2.5 0 0 0 56.615234 344.77148 A 2.5 2.5 0 0 0 59.916016 346.03906 A 2.5 2.5 0 0 0 61.183594 342.73828 A 2.5 2.5 0 0 0 58.851562 341.25586 z M 452.9707 341.25781 A 2.5 2.5 0 0 0 450.81641 342.73828 A 2.5 2.5 0 0 0 452.08398 346.03906 A 2.5 2.5 0 0 0 455.38477 344.77148 A 2.5 2.5 0 0 0 454.11719 341.4707 A 2.5 2.5 0 0 0 452.9707 341.25781 z M 69.09375 361.37695 A 2.5 2.5 0 0 0 67.902344 361.71094 A 2.5 2.5 0 0 0 66.986328 365.12695 A 2.5 2.5 0 0 0 70.402344 366.04102 A 2.5 2.5 0 0 0 71.316406 362.62695 A 2.5 2.5 0 0 0 69.09375 361.37695 z M 442.73047 361.37891 A 2.5 2.5 0 0 0 440.68359 362.62695 A 2.5 2.5 0 0 0 441.59766 366.04102 A 2.5 2.5 0 0 0 445.01367 365.12695 A 2.5 2.5 0 0 0 444.09766 361.71094 A 2.5 2.5 0 0 0 442.73047 361.37891 z M 81.380859 380.31836 A 2.5 2.5 0 0 0 79.982422 380.79492 A 2.5 2.5 0 0 0 79.429688 384.28516 A 2.5 2.5 0 0 0 82.921875 384.83984 A 2.5 2.5 0 0 0 83.474609 381.34766 A 2.5 2.5 0 0 0 81.380859 380.31836 z M 430.44141 380.31836 A 2.5 2.5 0 0 0 428.52539 381.34766 A 2.5 2.5 0 0 0 429.07812 384.83984 A 2.5 2.5 0 0 0 432.57031 384.28516 A 2.5 2.5 0 0 0 432.01758 380.79492 A 2.5 2.5 0 0 0 430.44141 380.31836 z M 95.582031 397.86914 A 2.5 2.5 0 0 0 93.992188 398.50977 A 2.5 2.5 0 0 0 93.806641 402.03906 A 2.5 2.5 0 0 0 97.335938 402.22461 A 2.5 2.5 0 0 0 97.521484 398.69336 A 2.5 2.5 0 0 0 95.582031 397.86914 z M 416.24219 397.86914 A 2.5 2.5 0 0 0 414.47852 398.69336 A 2.5 2.5 0 0 0 414.66211 402.22461 A 2.5 2.5 0 0 0 418.19336 402.03906 A 2.5 2.5 0 0 0 418.00781 398.50977 A 2.5 2.5 0 0 0 416.24219 397.86914 z M 111.53906 413.83789 A 2.5 2.5 0 0 0 109.77539 414.66406 A 2.5 2.5 0 0 0 109.96094 418.19336 A 2.5 2.5 0 0 0 113.49023 418.00781 A 2.5 2.5 0 0 0 113.30664 414.47852 A 2.5 2.5 0 0 0 111.53906 413.83789 z M 400.28516 413.83789 A 2.5 2.5 0 0 0 398.69336 414.47852 A 2.5 2.5 0 0 0 398.50977 418.00781 A 2.5 2.5 0 0 0 402.03906 418.19336 A 2.5 2.5 0 0 0 402.22461 414.66406 A 2.5 2.5 0 0 0 400.28516 413.83789 z M 382.74609 428.04883 A 2.5 2.5 0 0 0 381.34766 428.52539 A 2.5 2.5 0 0 0 380.79492 432.01758 A 2.5 2.5 0 0 0 384.28516 432.57031 A 2.5 2.5 0 0 0 384.83984 429.07812 A 2.5 2.5 0 0 0 382.74609 428.04883 z M 129.07812 428.05078 A 2.5 2.5 0 0 0 127.16016 429.07812 A 2.5 2.5 0 0 0 127.71484 432.57031 A 2.5 2.5 0 0 0 131.20508 432.01758 A 2.5 2.5 0 0 0 130.65234 428.52539 A 2.5 2.5 0 0 0 129.07812 428.05078 z M 363.81836 440.34766 A 2.5 2.5 0 0 0 362.62695 440.68359 A 2.5 2.5 0 0 0 361.71094 444.09766 A 2.5 2.5 0 0 0 365.12695 445.01367 A 2.5 2.5 0 0 0 366.04102 441.59766 A 2.5 2.5 0 0 0 363.81836 440.34766 z M 148.00586 440.35156 A 2.5 2.5 0 0 0 145.95898 441.59766 A 2.5 2.5 0 0 0 146.87305 445.01367 A 2.5 2.5 0 0 0 150.28906 444.09766 A 2.5 2.5 0 0 0 149.37305 440.68359 A 2.5 2.5 0 0 0 148.00586 440.35156 z M 343.70703 450.60156 A 2.5 2.5 0 0 0 342.73828 450.81641 A 2.5 2.5 0 0 0 341.4707 454.11719 A 2.5 2.5 0 0 0 344.77148 455.38477 A 2.5 2.5 0 0 0 346.03906 452.08398 A 2.5 2.5 0 0 0 343.70703 450.60156 z M 168.11523 450.60352 A 2.5 2.5 0 0 0 165.96094 452.08398 A 2.5 2.5 0 0 0 167.22852 455.38477 A 2.5 2.5 0 0 0 170.5293 454.11719 A 2.5 2.5 0 0 0 169.26172 450.81641 A 2.5 2.5 0 0 0 168.11523 450.60352 z M 322.63672 458.69336 A 2.5 2.5 0 0 0 321.89844 458.81641 A 2.5 2.5 0 0 0 320.29297 461.9668 A 2.5 2.5 0 0 0 323.44336 463.57031 A 2.5 2.5 0 0 0 325.04883 460.42188 A 2.5 2.5 0 0 0 322.63672 458.69336 z M 189.4375 458.69531 A 2.5 2.5 0 0 0 186.95117 460.42188 A 2.5 2.5 0 0 0 188.55664 463.57031 A 2.5 2.5 0 0 0 191.70703 461.9668 A 2.5 2.5 0 0 0 190.10156 458.81641 A 2.5 2.5 0 0 0 189.4375 458.69531 z M 300.83398 464.53906 A 2.5 2.5 0 0 0 300.33789 464.59375 A 2.5 2.5 0 0 0 298.41211 467.55859 A 2.5 2.5 0 0 0 301.37695 469.48438 A 2.5 2.5 0 0 0 303.30273 466.51953 A 2.5 2.5 0 0 0 300.83398 464.53906 z M 211.23828 464.54102 A 2.5 2.5 0 0 0 208.69727 466.51953 A 2.5 2.5 0 0 0 210.62305 469.48438 A 2.5 2.5 0 0 0 213.58789 467.55859 A 2.5 2.5 0 0 0 211.66211 464.59375 A 2.5 2.5 0 0 0 211.23828 464.54102 z M 233.5332 468.07227 A 2.5 2.5 0 0 0 230.96094 470.31055 A 2.5 2.5 0 0 0 233.18555 473.05859 A 2.5 2.5 0 0 0 235.93359 470.83203 A 2.5 2.5 0 0 0 233.70898 468.08594 A 2.5 2.5 0 0 0 233.5332 468.07227 z M 278.54102 468.07227 A 2.5 2.5 0 0 0 278.29102 468.08594 A 2.5 2.5 0 0 0 276.06641 470.83203 A 2.5 2.5 0 0 0 278.81445 473.05859 A 2.5 2.5 0 0 0 281.03906 470.31055 A 2.5 2.5 0 0 0 278.54102 468.07227 z M 256 469.25391 A 2.5 2.5 0 0 0 253.5 471.75391 A 2.5 2.5 0 0 0 256 474.25391 A 2.5 2.5 0 0 0 258.5 471.75391 A 2.5 2.5 0 0 0 256 469.25391 z " />
+ <path
+ android:fillColor="@color/accent_device_default_light"
+ android:pathData="m 139.48388,71.253494 14.77901,-8.532671 c 0,0 4.29057,5.224501 4.85695,8.412479 0.77655,4.370225 -2.27801,13.119658 -2.27801,13.119658 0,0 -9.10445,-1.72942 -12.501,-4.586987 -2.47769,-2.084495 -4.85695,-8.412479 -4.85695,-8.412479 z m -76.763047,83.009396 8.532661,-14.77901 c 0,0 6.327994,2.37926 8.412479,4.85694 2.857628,3.39646 4.587018,12.50096 4.587018,12.50096 0,0 -8.749404,3.05451 -13.119679,2.27806 -3.187988,-0.56638 -8.412479,-4.85695 -8.412479,-4.85695 z M 37.746771,264.53266 v -17.06533 c 0,0 6.669831,-1.10349 9.713895,0 4.173001,1.5126 10.222952,8.53264 10.222952,8.53264 0,0 -6.049951,7.01998 -10.222952,8.53269 -3.044064,1.1035 -9.713895,0 -9.713895,0 z M 71.253494,372.51611 62.720833,357.7371 c 0,0 5.224491,-4.29057 8.412479,-4.85695 4.370225,-0.77655 13.119658,2.27801 13.119658,2.27801 0,0 -1.72943,9.10446 -4.586997,12.501 -2.084485,2.47769 -8.412479,4.85695 -8.412479,4.85695 z m 83.009396,76.76306 -14.77901,-8.53267 c 0,0 2.37926,-6.32799 4.85695,-8.41248 3.39645,-2.85763 12.50096,-4.58702 12.50096,-4.58702 0,0 3.0545,8.7494 2.27805,13.11969 -0.56638,3.18798 -4.85695,8.41248 -4.85695,8.41248 z m 110.26977,24.97405 h -17.06533 c 0,0 -1.10349,-6.66983 0,-9.7139 1.5126,-4.173 8.53264,-10.22295 8.53264,-10.22295 0,0 7.01999,6.04995 8.53269,10.22295 1.1035,3.04407 0,9.7139 0,9.7139 z m 107.98345,-33.50672 -14.779,8.53267 c 0,0 -4.29057,-5.2245 -4.85695,-8.41248 -0.77656,-4.37023 2.278,-13.11966 2.278,-13.11966 0,0 9.10446,1.72942 12.501,4.58699 2.47769,2.08449 4.85695,8.41248 4.85695,8.41248 z m 76.76306,-83.00939 -8.53266,14.779 c 0,0 -6.328,-2.37926 -8.41248,-4.85695 -2.85763,-3.39645 -4.58702,-12.50095 -4.58702,-12.50095 0,0 8.7494,-3.05452 13.11968,-2.27805 3.18799,0.56637 8.41248,4.85695 8.41248,4.85695 z m 24.97405,-110.26978 v 17.06533 c 0,0 -6.66983,1.1035 -9.7139,0 -4.173,-1.5126 -10.22295,-8.53264 -10.22295,-8.53264 0,0 6.04995,-7.01998 10.22295,-8.53269 3.04407,-1.10349 9.7139,0 9.7139,0 z m -33.50671,-107.98345 8.53266,14.77901 c 0,0 -5.22449,4.29057 -8.41248,4.85695 -4.37023,0.77655 -13.11966,-2.27801 -13.11966,-2.27801 0,0 1.72942,-9.10446 4.587,-12.501 2.08448,-2.47769 8.41248,-4.85695 8.41248,-4.85695 z m -83.0094,-76.763057 14.77901,8.532671 c 0,0 -2.37927,6.327984 -4.85695,8.412479 -3.39645,2.857628 -12.50096,4.587018 -12.50096,4.587018 0,0 -3.05451,-8.749404 -2.27805,-13.119689 0.56638,-3.187978 4.85695,-8.412479 4.85695,-8.412479 z M 247.46733,37.746771 h 17.06534 c 0,0 1.10349,6.669831 0,9.713895 -1.5126,4.173001 -8.53264,10.222952 -8.53264,10.222952 0,0 -7.01999,-6.049951 -8.5327,-10.222952 -1.10349,-3.044064 0,-9.713895 0,-9.713895 z" />
+</vector>
diff --git a/packages/SystemUI/res-keyguard/drawable/custom_num_clock_hand_hour.xml b/packages/SystemUI/res-keyguard/drawable/custom_num_clock_hand_hour.xml
new file mode 100644
index 0000000..07f4b44
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/custom_num_clock_hand_hour.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Dirty Unicorns 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="150.000000dp"
+ android:height="150.000000dp"
+ android:viewportWidth="512.000000"
+ android:viewportHeight="512.000000">
+
+ <path
+ android:fillColor="@*android:color/accent_device_default_light"
+ android:strokeWidth="1"
+ android:pathData="m 249.74023,106.32032 h 12.51954 v 149.67967 h -12.51954 z" />
+</vector>
diff --git a/packages/SystemUI/res-keyguard/drawable/custom_num_clock_hand_minute.xml b/packages/SystemUI/res-keyguard/drawable/custom_num_clock_hand_minute.xml
new file mode 100644
index 0000000..deec0bf
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/custom_num_clock_hand_minute.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Dirty Unicorns 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="150.000000dp"
+ android:height="150.000000dp"
+ android:viewportWidth="512.000000"
+ android:viewportHeight="512.000000">
+
+ <path
+ android:fillColor="@color/analog_clock_hand_minute_color"
+ android:strokeWidth="1"
+ android:pathData="m 252,60.67751 -2.25977,182.79515 c -4.74692,2.37124 -7.74652,7.22111 -7.74804,12.52734 3e-5,7.73629 6.27152,14.00778 14.00781,14.00781 7.73629,-3e-5 14.00778,-6.27152 14.00781,-14.00781 -0.007,-5.3013 -3.00552,-10.14463 -7.74804,-12.51367 L 260,60.67751 Z" />
+</vector>
diff --git a/packages/SystemUI/res-keyguard/drawable/dot_clock_dial.xml b/packages/SystemUI/res-keyguard/drawable/dot_clock_dial.xml
new file mode 100644
index 0000000..7b61e47
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/dot_clock_dial.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The dotOS
+ 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:name="vector"
+ android:width="150.000000dp"
+ android:height="150.000000dp"
+ android:viewportWidth="512"
+ android:viewportHeight="512">
+ <path
+ android:name="path"
+ android:pathData="M 256 5 C 189.456 5 125.57 31.463 78.516 78.516 C 31.463 125.57 5 189.456 5 256 C 5 322.544 31.463 386.43 78.516 433.484 C 125.57 480.537 189.456 507 256 507 C 322.544 507 386.43 480.537 433.484 433.484 C 480.537 386.43 507 322.544 507 256 C 507 189.456 480.537 125.57 433.484 78.516 C 386.43 31.463 322.544 5 256 5 Z"
+ android:fillColor="#ebefee"
+ android:strokeWidth="1"/>
+ <path
+ android:name="path_3"
+ android:pathData="M 256 440.1 C 154.5 440.1 71.9 357.5 71.9 256 C 71.9 154.5 154.5 71.9 256 71.9 C 357.5 71.9 440.1 154.5 440.1 256 C 440.1 357.5 357.5 440.1 256 440.1 Z M 256 116.8 C 179.3 116.8 116.8 179.2 116.8 256 C 116.8 332.8 179.3 395.2 256 395.2 C 332.7 395.2 395.2 332.8 395.2 256 C 395.2 179.2 332.7 116.8 256 116.8 Z"
+ android:fillColor="#d8d8d8"
+ android:strokeWidth="1"/>
+</vector>
diff --git a/packages/SystemUI/res-keyguard/drawable/dot_clock_hand_hour.xml b/packages/SystemUI/res-keyguard/drawable/dot_clock_hand_hour.xml
new file mode 100644
index 0000000..0e3fecb
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/dot_clock_hand_hour.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The dotOS
+ 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:name="vector"
+ android:width="150.000000dp"
+ android:height="150.000000dp"
+ android:viewportWidth="512"
+ android:viewportHeight="512">
+ <path
+ android:name="path"
+ android:pathData="M 247.6 118.5 L 245 120.1 L 245 265.5 L 247.3 267.2 C 250.6 269.7 257.8 269.7 260.8 267.1 L 263 265.2 L 263 120.1 L 260.4 118.5 C 258.8 117.4 256.3 116.8 254 116.8 C 251.7 116.8 249.2 117.5 247.6 118.5 Z"
+ android:fillColor="#999999"
+ android:strokeWidth="1"/>
+ <path
+ android:name="path_2"
+ android:pathData="M 254 101.1 C 249.546 101.1 245.27 102.871 242.121 106.021 C 238.971 109.17 237.2 113.446 237.2 117.9 C 237.2 122.354 238.971 126.63 242.121 129.779 C 245.27 132.929 249.546 134.7 254 134.7 C 258.454 134.7 262.73 132.929 265.879 129.779 C 269.029 126.63 270.8 122.354 270.8 117.9 C 270.8 113.446 269.029 109.17 265.879 106.021 C 262.73 102.871 258.454 101.1 254 101.1 Z"
+ android:fillColor="#000000"
+ android:strokeWidth="1"/>
+</vector>
diff --git a/packages/SystemUI/res-keyguard/drawable/dot_clock_hand_minute.xml b/packages/SystemUI/res-keyguard/drawable/dot_clock_hand_minute.xml
new file mode 100644
index 0000000..098e70c
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/dot_clock_hand_minute.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The dotOS
+ 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:name="vector"
+ android:width="150.000000dp"
+ android:height="150.000000dp"
+ android:viewportWidth="512"
+ android:viewportHeight="512">
+ <path
+ android:name="path_1"
+ android:pathData="M 248.6 59.1 L 246 61.1 L 246 250.2 L 243.5 253.2 C 241.4 255.6 241 257.2 241 262.2 C 241 267.9 241.2 268.5 244.9 272.1 C 248.6 275.8 249.1 276 255 276 C 260.9 276 261.4 275.8 265.1 272.1 C 268.8 268.5 269 267.9 269 262.2 C 269 257.2 268.6 255.6 266.5 253.2 L 264 250.2 L 264 61.1 L 261.4 59.1 C 259.8 57.8 257.3 57 255 57 C 252.7 57 250.2 57.8 248.6 59.1 Z"
+ android:fillColor="#b7b7b7"
+ android:strokeWidth="1"/>
+ <path
+ android:name="path_3"
+ android:pathData="M 255 35 C 247.577 35 240.45 37.952 235.201 43.201 C 229.952 48.45 227 55.577 227 63 C 227 70.423 229.952 77.55 235.201 82.799 C 240.45 88.048 247.577 91 255 91 C 262.423 91 269.55 88.048 274.799 82.799 C 280.048 77.55 283 70.423 283 63 C 283 55.577 280.048 48.45 274.799 43.201 C 269.55 37.952 262.423 35 255 35 Z"
+ android:fillColor="#ff0000"
+ android:strokeWidth="1"/>
+</vector>
diff --git a/packages/SystemUI/res-keyguard/drawable/ic_oneplus_numbers_dial.xml b/packages/SystemUI/res-keyguard/drawable/ic_oneplus_numbers_dial.xml
new file mode 100644
index 0000000..5588c3e
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/ic_oneplus_numbers_dial.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 The BlissRoms 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 android:height="211dp"
+ android:viewportHeight="512"
+ android:viewportWidth="512"
+ android:width="211dp"
+ xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <path
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData="M252.573,483.208L252.573,457.63L259.427,457.63L259.427,483.208L252.573,483.208ZM234.583,467.665L232.992,481.984L231.401,481.862L232.992,467.543L234.583,467.665ZM278.886,481.984L277.417,467.788L279.008,467.665L280.599,481.862L278.886,481.984ZM212.553,464.361L209.494,478.435L208.025,478.068L210.962,463.994L212.553,464.361ZM302.384,478.435L299.447,464.361L301.038,464.116L303.975,478.068L302.384,478.435ZM325.392,472.316L320.987,458.731L322.578,458.242L326.983,471.826L325.392,472.316ZM191.013,458.609L186.608,472.316L185.017,471.826L189.422,458.119L191.013,458.609ZM170.208,450.776L164.333,463.871L162.865,463.259L168.739,450.042L170.208,450.776ZM347.667,463.871L341.792,450.776L343.261,450.164L349.135,463.259L347.667,463.871ZM141.719,452.321L139.489,451.021L152.217,428.992L158.092,432.418L145.364,454.448L142.426,452.734L141.692,452.367L141.719,452.321ZM369.574,452.734L366.636,454.448L353.908,432.418L359.783,428.992L372.511,451.021L370.281,452.322L370.308,452.367L369.574,452.734ZM131.534,428.624L123.09,440.251L121.866,439.272L130.31,427.645L131.534,428.624ZM388.91,440.251L380.466,428.747L381.812,427.768L390.134,439.272L388.91,440.251ZM264.75,393.84L264.301,398.377L264.009,398.355C261.134,398.325 258.64,399.1 256.529,400.68C254.417,402.26 252.762,404.652 251.564,407.857C253.541,405.94 255.795,405.012 258.326,405.071C260.078,405.101 261.568,405.592 262.796,406.543C264.024,407.494 264.923,408.797 265.492,410.451C266.061,412.106 266.255,413.907 266.076,415.854C265.896,417.981 265.274,419.931 264.211,421.706C263.148,423.48 261.759,424.851 260.044,425.817C258.329,426.783 256.454,427.243 254.417,427.198C251.826,427.138 249.722,426.217 248.105,424.435C246.487,422.653 245.566,420.309 245.342,417.404C245.207,415.802 245.379,413.66 245.858,410.979C246.832,405.633 248.91,401.44 252.092,398.4C255.274,395.36 259.322,393.84 264.234,393.84L264.75,393.84ZM114.278,414.673L104.609,425.32L103.386,424.341L113.054,413.571L114.278,414.673ZM407.391,425.32L397.845,414.795L399.068,413.693L408.614,424.341L407.391,425.32ZM256.776,409.452C255.578,409.422 254.454,409.74 253.406,410.407C252.358,411.073 251.474,412.02 250.755,413.248C250.591,414.761 250.516,415.839 250.531,416.483C250.531,418.4 250.883,419.92 251.587,421.043C252.29,422.166 253.301,422.743 254.619,422.773C256.237,422.818 257.611,422.211 258.741,420.953C259.872,419.695 260.55,418.048 260.774,416.011C260.969,414.109 260.707,412.552 259.988,411.339C259.269,410.126 258.198,409.497 256.776,409.452ZM98.368,399.007L87.72,408.553L86.619,407.452L97.389,397.783L98.368,399.007ZM424.28,408.553L413.632,399.007L414.734,397.906L425.381,407.452L424.28,408.553ZM322.274,389.223L326.565,372.802L343.682,372.802L342.941,377.519L330.339,377.519L328.025,385.359C329.552,384.49 331.215,384.056 333.012,384.056C335.782,384.086 337.913,385.104 339.403,387.111C340.893,389.118 341.503,391.716 341.233,394.906C340.964,398.186 339.736,400.866 337.549,402.948C335.363,405.03 332.66,406.04 329.44,405.981C326.714,405.921 324.502,405.045 322.802,403.352C321.102,401.66 320.207,399.429 320.118,396.658L325.217,396.658C325.322,398.186 325.752,399.38 326.509,400.241C327.265,401.102 328.324,401.548 329.687,401.578C331.349,401.623 332.746,401.016 333.877,399.758C335.007,398.5 335.685,396.823 335.91,394.726C336.089,392.869 335.782,391.368 334.989,390.222C334.195,389.077 333.012,388.489 331.439,388.459C330.481,388.429 329.624,388.582 328.867,388.919C328.111,389.256 327.373,389.724 326.655,390.323L322.274,389.223ZM185.784,372.059L168.622,401.464L162.804,401.464L179.899,373.137L163.59,373.137L164.286,368.757L186.301,368.757L185.784,372.059ZM439.333,390.195L427.707,381.751L428.686,380.527L440.312,388.849L439.333,390.195ZM84.293,381.751L72.667,390.195L71.688,388.849L83.437,380.405L84.293,381.751ZM451.082,372.572L428.93,359.844L432.357,353.847L454.387,366.575L451.082,372.572ZM60.918,372.572L57.491,366.575L79.643,353.847L83.07,359.844L60.918,372.572ZM397.772,340.039L401.725,340.039L400.961,344.419L397.03,344.419L395.75,351.697L390.426,351.697L391.684,344.419L377.981,344.419L378.453,340.825L395.75,318.99L401.433,318.99L397.772,340.039ZM134.303,326.671C134.033,329.92 132.117,332.436 128.552,334.218C129.885,335.072 130.877,336.158 131.529,337.476C132.18,338.794 132.446,340.246 132.326,341.834C132.132,344.709 130.956,347.034 128.799,348.809C126.643,350.583 123.97,351.441 120.78,351.381C117.875,351.321 115.565,350.456 113.85,348.786C112.135,347.116 111.375,344.926 111.57,342.216C111.839,338.576 114.018,335.821 118.107,333.949C116.983,333.14 116.152,332.133 115.613,330.928C115.074,329.722 114.849,328.43 114.939,327.053C115.149,324.237 116.257,321.972 118.264,320.257C120.271,318.543 122.764,317.715 125.744,317.775C127.526,317.82 129.095,318.217 130.45,318.966C131.806,319.714 132.82,320.763 133.494,322.111C134.168,323.458 134.438,324.978 134.303,326.671ZM61.897,343.322L48.802,349.196L48.19,347.728L61.285,341.853L61.897,343.322ZM463.198,349.196L450.103,343.322L450.837,341.853L463.81,347.728L463.198,349.196ZM127.07,341.564C127.234,340.052 126.942,338.805 126.194,337.824C125.445,336.843 124.367,336.338 122.959,336.308C121.371,336.278 120.016,336.798 118.893,337.869C117.77,338.94 117.118,340.291 116.939,341.924C116.774,343.466 117.073,344.698 117.837,345.619C118.601,346.54 119.679,347.015 121.072,347.045C122.689,347.075 124.048,346.573 125.149,345.54C126.25,344.507 126.89,343.181 127.07,341.564ZM384.338,340.039L392.448,340.039L394.986,326.314L394.447,327.077L384.338,340.039ZM128.957,326.85C129.091,325.503 128.841,324.387 128.204,323.503C127.568,322.62 126.628,322.163 125.385,322.133C124.022,322.103 122.858,322.567 121.892,323.526C120.926,324.484 120.361,325.727 120.196,327.255C120.061,328.662 120.316,329.793 120.96,330.647C121.604,331.5 122.532,331.942 123.745,331.972C125.123,332.002 126.295,331.53 127.261,330.557C128.227,329.583 128.792,328.348 128.957,326.85ZM471.765,326.922L458.18,322.516L458.67,321.048L472.255,325.454L471.765,326.922ZM53.942,322.516L40.235,326.922L39.745,325.454L53.452,321.048L53.942,322.516ZM478.007,304.036L464.055,301.099L464.422,299.508L478.374,302.445L478.007,304.036ZM48.067,300.977L33.993,304.036L33.626,302.445L47.7,299.508L48.067,300.977ZM481.801,280.538L467.604,279.07L467.849,277.479L482.046,278.947L481.801,280.538ZM44.518,279.07L30.199,280.538L29.954,278.947L44.273,277.479L44.518,279.07ZM410.649,254.155L413.547,254.177C415.299,254.177 416.759,253.706 417.928,252.762C419.096,251.819 419.762,250.561 419.927,248.988C420.092,247.506 419.822,246.341 419.118,245.495C418.414,244.649 417.366,244.211 415.973,244.181C414.566,244.151 413.345,244.563 412.312,245.417C411.278,246.27 410.657,247.393 410.447,248.786L405.123,248.809C405.258,247.056 405.835,245.491 406.853,244.114C407.871,242.736 409.2,241.676 410.84,240.935C412.48,240.194 414.251,239.831 416.153,239.846C419.073,239.906 421.376,240.755 423.061,242.395C424.745,244.035 425.49,246.233 425.296,248.988C425.191,250.486 424.637,251.86 423.633,253.11C422.63,254.361 421.177,255.435 419.275,256.334C421.866,257.532 423.244,259.614 423.409,262.579L423.409,263.657C423.214,266.592 422.012,268.974 419.803,270.801C417.594,272.628 414.887,273.511 411.683,273.451C409.841,273.436 408.186,273.043 406.718,272.272C405.251,271.501 404.124,270.415 403.337,269.015C402.551,267.614 402.188,266.016 402.248,264.219L407.549,264.241C407.489,265.679 407.845,266.836 408.616,267.712C409.388,268.588 410.515,269.048 411.997,269.093C413.63,269.153 415.019,268.674 416.164,267.656C417.31,266.637 417.973,265.304 418.152,263.657C418.332,261.995 417.991,260.729 417.13,259.861C416.269,258.992 415.03,258.535 413.412,258.49L409.975,258.468L410.649,254.155ZM88.824,268.794C91.999,268.824 94.582,268.056 96.574,266.491C98.566,264.926 100.056,262.579 101.044,259.449C99.008,261.426 96.851,262.399 94.575,262.369C92.883,262.339 91.415,261.879 90.172,260.988C88.929,260.097 88.001,258.812 87.387,257.135C86.773,255.458 86.555,253.601 86.735,251.564C86.93,249.393 87.563,247.401 88.633,245.589C89.704,243.777 91.093,242.377 92.8,241.388C94.508,240.4 96.372,239.935 98.394,239.995C100.146,240.04 101.67,240.486 102.965,241.332C104.261,242.178 105.268,243.384 105.986,244.949C106.705,246.514 107.117,248.262 107.222,250.194C107.297,251.796 107.125,253.796 106.705,256.192C105.747,261.733 103.695,265.971 100.55,268.906C97.405,271.841 93.407,273.309 88.555,273.309L88.06,273.309L88.487,268.771L88.824,268.794ZM457.691,259.488L457.691,252.634L483.147,252.634L483.147,259.488L457.691,259.488ZM28.853,259.488L28.853,252.634L54.309,252.634L54.309,259.488L28.853,259.488ZM95.9,258.124C97.009,258.154 98.057,257.85 99.045,257.214C100.034,256.577 100.887,255.698 101.606,254.574L101.898,252.395L101.988,250.823C102.033,248.876 101.726,247.33 101.067,246.184C100.408,245.038 99.42,244.436 98.102,244.376C96.23,244.316 94.695,245.214 93.497,247.071C92.299,248.928 91.812,251.115 92.037,253.631C92.141,254.964 92.531,256.034 93.205,256.843C93.879,257.652 94.777,258.079 95.9,258.124ZM482.046,233.053L467.849,234.521L467.604,232.93L481.801,231.462L482.046,233.053ZM44.273,234.521L29.954,233.053L30.199,231.462L44.518,232.93L44.273,234.521ZM47.7,212.614L33.626,209.555L33.993,207.964L48.067,211.023L47.7,212.614ZM478.374,209.555L464.422,212.492L464.055,211.023L478.007,207.964L478.374,209.555ZM135.91,194.039C133.079,193.979 130.938,193.002 129.485,191.108C128.033,189.213 127.329,186.559 127.374,183.144C127.389,182.036 127.464,180.928 127.598,179.82L128.474,173.979C129.208,169.397 130.623,165.975 132.72,163.713C134.817,161.452 137.527,160.359 140.852,160.434C143.667,160.493 145.805,161.452 147.265,163.309C148.725,165.166 149.433,167.802 149.388,171.216C149.373,172.339 149.298,173.448 149.163,174.541L148.287,180.224C147.524,184.912 146.105,188.405 144.031,190.703C141.956,193.002 139.249,194.114 135.91,194.039ZM113.963,193.59L108.661,193.59L113.199,167.442L104.932,170.183L105.764,165.353L118.703,160.771L119.511,160.771L113.963,193.59ZM400.817,193.546L379.454,193.546L380.083,189.57L393.674,176.519C396.205,174.048 397.597,171.809 397.852,169.802C398.047,168.379 397.807,167.192 397.133,166.241C396.459,165.291 395.448,164.785 394.1,164.725C392.438,164.665 391.038,165.186 389.9,166.286C388.762,167.387 388.073,168.888 387.833,170.79L382.532,170.813C382.681,168.806 383.292,167.001 384.362,165.399C385.433,163.797 386.856,162.55 388.631,161.659C390.405,160.768 392.326,160.345 394.392,160.39C397.238,160.45 399.488,161.273 401.143,162.861C402.798,164.448 403.528,166.575 403.333,169.24C403.078,172.295 401.244,175.523 397.829,178.922L396.437,180.292L386.979,189.188L401.513,189.188L400.817,193.546ZM53.33,191.075L39.745,186.546L40.235,185.078L53.942,189.484L53.33,191.075ZM472.255,186.546L458.67,190.952L458.18,189.484L471.765,185.078L472.255,186.546ZM143.974,173.665C144.169,171.957 144.266,170.744 144.266,170.026C144.191,166.641 142.956,164.896 140.56,164.792C138.733,164.717 137.265,165.383 136.157,166.791C135.049,168.199 134.27,170.437 133.821,173.507L132.787,180.628C132.608,182.171 132.525,183.391 132.54,184.29C132.54,187.794 133.768,189.599 136.224,189.704C139.609,189.898 141.788,187.255 142.761,181.774L143.974,173.665ZM463.81,164.395L450.837,170.147L450.103,168.678L463.198,162.926L463.81,164.395ZM61.285,170.147L48.19,164.395L48.802,162.926L61.897,168.8L61.285,170.147ZM79.643,158.153L57.491,145.425L60.918,139.428L83.07,152.278L79.643,158.153ZM452.734,142.426L453.163,143.1L453.119,143.125L454.387,145.425L432.357,158.153L428.93,152.278L451.082,139.428L452.734,142.426ZM168.963,140.724L163.661,140.724L168.199,114.576L159.932,117.317L160.764,112.487L173.703,107.904L174.511,107.904L168.963,140.724ZM194.549,140.724L189.248,140.724L193.785,114.576L185.519,117.317L186.35,112.487L199.289,107.904L200.098,107.904L194.549,140.724ZM338.483,138.864L333.182,138.864L337.719,112.716L329.453,115.457L330.284,110.627L343.223,106.044L344.032,106.044L338.483,138.864ZM83.437,131.595L71.688,123.151L72.667,121.805L84.293,130.249L83.437,131.595ZM440.19,123.151L428.686,131.595L427.707,130.249L439.333,121.805L440.19,123.151ZM242.562,117.958L237.261,117.958L241.798,91.811L233.532,94.551L234.363,89.722L247.302,85.139L248.111,85.139L242.562,117.958ZM275.359,117.958L253.996,117.958L254.625,113.982L268.216,100.931C270.747,98.46 272.139,96.221 272.394,94.214C272.589,92.792 272.349,91.605 271.675,90.654C271.001,89.703 269.99,89.197 268.643,89.138C266.98,89.078 265.58,89.598 264.442,90.699C263.304,91.8 262.615,93.301 262.375,95.203L257.074,95.225C257.224,93.218 257.834,91.414 258.905,89.812C259.975,88.209 261.398,86.962 263.173,86.071C264.947,85.18 266.868,84.757 268.935,84.802C271.78,84.862 274.03,85.686 275.685,87.273C277.34,88.861 278.07,90.987 277.875,93.653C277.621,96.708 275.786,99.935 272.372,103.335L270.979,104.705L261.522,113.601L276.056,113.601L275.359,117.958ZM425.381,104.548L414.734,114.217L413.632,112.993L424.28,103.447L425.381,104.548ZM97.389,114.217L86.619,104.548L87.72,103.447L98.368,112.993L97.389,114.217ZM113.054,98.429L103.386,87.781L104.609,86.68L114.278,97.327L113.054,98.429ZM408.614,87.781L399.068,98.307L397.845,97.327L407.391,86.68L408.614,87.781ZM130.31,84.355L121.866,72.728L123.09,71.749L131.534,83.376L130.31,84.355ZM390.134,72.728L381.812,84.232L380.466,83.376L388.91,71.749L390.134,72.728ZM369.574,59.266L370.308,59.633L370.281,59.679L372.511,60.979L359.783,83.131L353.908,79.704L366.636,57.552L369.574,59.266ZM142.426,59.266L145.364,57.552L158.092,79.704L152.217,83.131L139.489,60.979L141.719,59.679L141.692,59.633L142.426,59.266ZM168.739,61.958L162.865,48.863L164.333,48.129L170.208,61.346L168.739,61.958ZM349.135,48.863L343.261,61.836L341.914,61.224L347.667,48.129L349.135,48.863ZM252.573,54.37L252.573,28.792L259.427,28.792L259.427,54.37L252.573,54.37ZM189.545,53.881L185.017,40.174L186.608,39.684L191.013,53.391L189.545,53.881ZM326.983,40.174L322.578,53.758L320.987,53.269L325.392,39.684L326.983,40.174ZM210.962,48.006L208.025,33.932L209.494,33.687L212.553,47.761L210.962,48.006ZM303.975,33.932L301.038,48.006L299.447,47.639L302.384,33.687L303.975,33.932ZM232.992,44.457L231.401,30.138L232.992,30.016L234.583,44.335L232.992,44.457ZM280.477,30.138L279.008,44.335L277.417,44.212L278.886,30.016L280.477,30.138Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/drawable/ic_oneplus_numbers_hour.xml b/packages/SystemUI/res-keyguard/drawable/ic_oneplus_numbers_hour.xml
new file mode 100644
index 0000000..17dcd88
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/ic_oneplus_numbers_hour.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 The BlissRoms 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 android:height="211dp"
+ android:viewportHeight="512"
+ android:viewportWidth="512"
+ android:width="211dp"
+ xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <path
+ android:fillColor="@*android:color/accent_device_default_light"
+ android:fillType="nonZero"
+ android:pathData="M255.999,268.108C253.321,268.108 251.178,265.249 251.178,261.675L251.178,160.118C251.178,156.616 253.374,153.686 255.999,153.686C258.625,153.686 260.821,156.545 260.821,160.118L260.821,261.675C260.821,265.249 258.678,268.108 255.999,268.108Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/drawable/ic_oneplus_numbers_minute.xml b/packages/SystemUI/res-keyguard/drawable/ic_oneplus_numbers_minute.xml
new file mode 100644
index 0000000..b9b44d2
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/ic_oneplus_numbers_minute.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 The BlissRoms 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 android:height="211dp"
+ android:viewportHeight="512"
+ android:viewportWidth="512"
+ android:width="211dp"
+ xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <path
+ android:fillColor="#ffffff"
+ android:pathData="M253.25,247.852L253.25,129.449C253.25,128.721 253.54,128.021 254.056,127.505C254.57,126.989 255.27,126.7 256,126.7L256,126.7C256.73,126.7 257.43,126.989 257.944,127.505C258.46,128.021 258.749,128.721 258.749,129.449L258.749,247.852C262.434,249.019 265.107,252.467 265.107,256.536C265.107,261.563 261.027,265.643 256,265.643C250.973,265.643 246.893,261.563 246.893,256.536C246.893,252.467 249.565,249.019 253.25,247.852Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/drawable/ic_oneplus_roman_dial.xml b/packages/SystemUI/res-keyguard/drawable/ic_oneplus_roman_dial.xml
new file mode 100644
index 0000000..d1bf76e
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/ic_oneplus_roman_dial.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 The BlissRoms 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 android:height="211dp"
+ android:viewportHeight="512"
+ android:viewportWidth="512"
+ android:width="211dp"
+ xmlns:android="http://schemas.android.com/apk/res/android">
+ <path android:fillColor="#ffffff"
+ android:pathData="M257.892,380.756C256.682,380.739 255.477,380.68 254.266,380.562C254.366,372.955 254.197,365.341 254.37,357.743C255.546,357.599 256.722,357.658 257.896,357.649C257.882,365.349 257.921,373.057 257.892,380.756ZM244.083,365.897C244.287,365.957 244.699,366.076 244.902,366.14C244.589,368.635 244.549,371.159 244.133,373.645C243.925,373.574 243.513,373.441 243.304,373.376C243.504,370.877 243.9,368.397 244.083,365.897ZM267.14,366.24C267.323,366.17 267.696,366.026 267.879,365.952C268.231,368.422 268.494,370.901 268.747,373.381C268.534,373.431 268.107,373.54 267.894,373.589C267.731,371.13 267.358,368.695 267.14,366.24ZM278.502,364.142C278.716,364.231 279.147,364.4 279.36,364.489C279.921,366.879 280.506,369.275 280.888,371.71C280.69,371.665 280.298,371.581 280.099,371.536C279.305,369.136 279.018,366.607 278.502,364.142ZM231.149,371.611C231.744,369.215 231.958,366.701 232.821,364.39L233.54,364.033C233.277,366.572 232.504,369.017 232.071,371.526C231.844,371.546 231.382,371.591 231.149,371.611ZM289.612,361.176C289.845,361.271 290.311,361.454 290.544,361.543C291.253,363.736 292.21,365.888 292.602,368.164C292.468,368.318 292.2,368.615 292.066,368.764C291.134,366.274 290.385,363.72 289.612,361.176ZM221.652,361.33C221.85,361.3 222.247,361.24 222.445,361.211C221.721,363.711 220.888,366.18 220.03,368.64L219.375,368.228C220.015,365.893 220.68,363.547 221.652,361.33ZM319.601,363.284C318.545,363.874 317.471,364.426 316.364,364.928C312.647,358.291 308.694,351.78 305.045,345.114C305.991,344.401 307.039,343.865 308.052,343.27C311.89,349.946 315.777,356.601 319.601,363.284ZM195.566,364.928C194.527,364.308 193.513,363.654 192.524,362.947C196.413,356.409 200.075,349.73 204.024,343.236C205.113,343.7 206.102,344.339 207.124,344.919C203.262,351.579 199.442,358.275 195.566,364.928ZM210.845,356.935C211.054,357.035 211.46,357.224 211.668,357.322C210.359,359.535 209.972,362.366 208.157,364.226C207.642,363.567 208.321,362.822 208.499,362.173C209.308,360.437 210.111,358.701 210.845,356.935ZM300.518,356.91C301.395,357.085 301.638,357.982 301.985,358.661C302.685,360.347 303.453,362 304.242,363.646C304.053,363.79 303.686,364.073 303.503,364.216C302.506,361.781 301.058,359.495 300.518,356.91ZM320.296,345.777C320.519,345.737 320.971,345.658 321.194,345.618C322.592,347.299 323.827,349.149 325.082,350.944C325.126,351.252 325.211,351.872 325.255,352.18C323.242,350.35 321.982,347.88 320.296,345.777ZM188.988,348.127C189.762,347.106 190.372,345.896 191.498,345.207C191.542,346.649 190.293,347.607 189.619,348.758C188.696,349.878 188.101,351.45 186.628,351.962C187.015,350.463 188.141,349.362 188.988,348.127ZM179.149,341.293C180.131,340.321 180.89,339.101 182.031,338.303C182.229,338.343 182.62,338.427 182.814,338.472C180.959,340.435 179.422,342.802 177.17,344.328C177.215,342.994 178.375,342.221 179.149,341.293ZM329.421,338.516C329.59,338.457 329.927,338.333 330.095,338.273C331.877,340.094 333.652,341.958 335.149,344.026C334.222,344.314 333.676,343.466 333.151,342.91C331.921,341.432 330.493,340.118 329.421,338.516ZM338.001,330.958C337.441,330.705 338.116,330.268 338.11,329.892C339.811,331.523 341.681,332.981 343.333,334.658C343.372,334.906 343.451,335.402 343.491,335.649C341.453,334.355 339.816,332.535 338.001,330.958ZM170.679,332.858C171.908,331.856 172.885,330.432 174.472,329.976C174.011,331.444 172.578,332.202 171.551,333.234C170.554,334.048 169.736,335.218 168.407,335.496C168.675,334.271 169.845,333.661 170.679,332.858ZM166.785,320.826C166.909,321.098 167.034,321.381 167.142,321.664C165.238,323.176 163.179,324.485 161.26,325.988C161.057,325.765 160.853,325.547 160.655,325.334C162.664,323.786 164.801,322.413 166.785,320.826ZM344.86,320.91C347.325,322.14 349.551,323.866 351.63,325.676C350.177,326.187 349.22,324.605 348.083,323.995C346.988,322.993 345.173,322.541 344.86,320.91ZM364.419,317.161C363.8,318.2 363.146,319.214 362.438,320.203C355.901,316.314 349.222,312.653 342.728,308.704C343.191,307.613 343.831,306.626 344.411,305.603C351.071,309.466 357.766,313.285 364.419,317.161ZM149.271,320.181C148.681,319.125 148.13,318.052 147.627,316.944C154.264,313.227 160.774,309.274 167.441,305.625C168.153,306.571 168.689,307.619 169.284,308.632C162.609,312.469 155.953,316.358 149.271,320.181ZM152.492,302.213C153.563,301.984 154.972,300.293 155.824,301.632C153.405,302.729 151.024,303.939 148.509,304.802C148.842,303.021 151.202,303.085 152.492,302.213ZM356.5,300.948C358.995,301.88 361.44,302.981 363.825,304.182C363.359,304.574 362.803,304.757 362.263,304.385C360.443,303.518 358.568,302.773 356.768,301.871C356.698,301.638 356.564,301.176 356.5,300.948ZM360.924,290.186C363.23,291.168 365.923,291.417 368.021,292.77L367.872,293.316C365.412,292.666 363.032,291.778 360.626,290.98C360.701,290.782 360.85,290.384 360.924,290.186ZM144.085,292.487C146.099,291.842 148.093,291.134 150.122,290.538C150.692,290.147 151.207,290.549 151.575,290.95C149.135,291.723 146.744,292.641 144.26,293.276C144.22,293.078 144.131,292.685 144.085,292.487ZM141.031,280.624C143.332,280.019 145.667,279.474 148.034,279.191C148.197,279.32 148.529,279.572 148.698,279.701C146.204,280.406 143.659,280.971 141.1,281.378C141.085,281.19 141.046,280.813 141.031,280.624ZM363.701,279.062C366.146,279.533 368.626,279.915 371.007,280.679C371.076,280.842 371.22,281.179 371.289,281.348C368.75,281.135 366.28,280.44 363.805,279.87C363.775,279.667 363.726,279.266 363.701,279.062ZM365.189,268.31C365.784,267.388 366.9,267.858 367.797,267.898C369.514,268.137 371.249,268.295 372.985,268.385C372.98,268.627 372.966,269.103 372.956,269.342C370.372,268.955 367.743,268.895 365.189,268.31ZM139.195,268.478C141.621,268.137 144.071,267.962 146.501,267.665C146.525,267.858 146.565,268.245 146.59,268.434C144.12,268.816 141.631,268.999 139.156,269.332C139.166,269.118 139.185,268.691 139.195,268.478ZM380.243,254.704C380.227,255.915 380.168,257.12 380.05,258.33C372.443,258.23 364.828,258.399 357.23,258.226C357.086,257.05 357.146,255.875 357.137,254.699C364.836,254.714 372.544,254.675 380.243,254.704ZM131.756,258.318C131.773,257.108 131.832,255.903 131.95,254.693C139.557,254.792 147.172,254.623 154.77,254.797C154.914,255.972 154.854,257.148 154.863,258.324C147.163,258.308 139.456,258.348 131.756,258.318ZM365.497,244.628C367.778,244.445 370.039,244.078 372.321,243.904C372.827,243.512 373.625,244.812 372.752,244.693C370.382,245.164 367.932,245.09 365.546,245.486C365.531,245.268 365.511,244.841 365.497,244.628ZM139.032,243.84C141.447,244.087 143.877,244.281 146.273,244.663C146.417,244.851 146.699,245.228 146.838,245.417C144.314,245.209 141.779,245.07 139.265,244.757C139.206,244.529 139.091,244.073 139.032,243.84ZM141.129,231.763C143.475,232.254 145.896,232.537 148.153,233.35L148.604,234.025C145.99,233.856 143.49,233.053 140.936,232.562L141.129,231.763ZM364.733,233.043C366.791,232.527 368.879,232.146 370.967,231.734C371.011,231.947 371.096,232.369 371.14,232.577C368.586,233.038 366.092,233.856 363.488,234.025C363.721,233.45 364.133,233.122 364.733,233.043ZM360.77,222.261C363.051,221.13 365.571,220.565 367.996,219.806L367.758,220.595C365.521,221.651 363.076,222.181 360.74,222.985L360.77,222.261ZM143.922,219.851C146.556,220.397 149.075,221.353 151.594,222.266C151.471,222.851 150.757,222.782 150.324,222.668C148.34,222.058 146.327,221.498 144.413,220.684C144.289,220.476 144.046,220.059 143.922,219.851ZM148.326,208.533C150.84,208.881 153.003,210.344 155.329,211.266C155.413,211.509 155.582,211.995 155.671,212.238C153.89,211.687 152.264,210.78 150.533,210.105C149.72,209.714 148.693,209.466 148.326,208.533ZM356.465,211.34C358.85,210.418 361.098,209.173 363.513,208.33C363.761,209.322 362.729,209.481 362.139,209.833C360.368,210.607 358.583,211.34 356.857,212.203C356.758,211.985 356.564,211.554 356.465,211.34ZM362.769,192.988C363.359,194.044 363.91,195.118 364.413,196.225C357.775,199.942 351.265,203.896 344.598,207.544C343.886,206.598 343.35,205.55 342.755,204.537C349.431,200.7 356.086,196.812 362.769,192.988ZM169.289,204.501C168.669,205.541 168.015,206.554 167.307,207.543C160.77,203.655 154.091,199.993 147.598,196.044C148.061,194.954 148.7,193.966 149.28,192.943C155.941,196.806 162.636,200.626 169.289,204.501ZM345.128,191.349C347.028,189.915 348.912,188.432 350.956,187.208C351.664,187.49 350.995,188.199 350.633,188.403C348.788,189.737 346.973,191.126 345.019,192.301C345.048,192.063 345.103,191.586 345.128,191.349ZM160.918,187.034C163.1,188.403 165.069,190.079 167.251,191.448C167.152,191.656 166.949,192.067 166.849,192.276C164.871,190.803 162.698,189.563 160.893,187.877L160.918,187.034ZM340.758,179.689C341.686,178.896 342.469,177.79 343.779,177.636C342.38,179.962 339.935,181.415 338.026,183.299C337.956,183.106 337.827,182.724 337.758,182.531C338.616,181.444 339.771,180.646 340.758,179.689ZM168.268,177.73C168.521,177.78 169.032,177.884 169.285,177.934C171.125,179.535 173.079,181.067 174.616,182.977C173.5,183.176 172.815,182.183 172.067,181.579C170.787,180.309 169.201,179.312 168.268,177.73ZM329.466,174.968C330.503,172.562 332.858,170.9 334.485,168.837C334.599,169.041 334.827,169.453 334.941,169.661C333.012,171.317 331.821,173.887 329.466,174.968ZM177.136,169.457C177.339,168.262 178.092,169.532 178.485,169.77C179.913,171.427 181.475,172.979 182.735,174.774C181.693,175.022 181.108,173.985 180.473,173.361C179.387,172.037 178.107,170.876 177.136,169.457ZM316.613,148.177C317.653,148.797 318.667,149.451 319.655,150.158C315.767,156.696 312.106,163.376 308.156,169.868C307.066,169.406 306.078,168.766 305.056,168.186C308.919,161.526 312.738,154.831 316.613,148.177ZM206.96,168.212C205.903,168.803 204.83,169.354 203.723,169.856C200.006,163.22 196.052,156.71 192.403,150.043C193.349,149.331 194.397,148.794 195.411,148.199C199.247,154.874 203.136,161.529 206.96,168.212ZM186.484,161.28C187.704,161.368 188.23,162.524 188.88,163.368C189.737,164.627 190.68,165.822 191.523,167.092C191.438,167.32 191.27,167.776 191.19,168.004C189.559,165.808 187.808,163.68 186.484,161.28ZM320.494,167.102C322.111,165.108 323.281,162.717 325.255,161.047C325.484,162.147 324.551,162.906 324.02,163.735C322.924,165.063 322.18,166.705 320.821,167.792C320.737,167.617 320.573,167.276 320.494,167.102ZM303.418,149.233C303.637,149.203 304.069,149.144 304.282,149.119C303.334,151.494 302.308,153.845 301.172,156.136C300.993,156.067 300.637,155.918 300.453,155.849C301.365,153.612 302.318,151.375 303.418,149.233ZM207.785,149.01C208.023,149.109 208.489,149.298 208.727,149.396C209.893,151.549 210.667,153.89 211.772,156.077L210.9,156.092C209.73,153.801 208.643,151.44 207.785,149.01ZM254.275,131.243C255.486,131.26 256.691,131.319 257.901,131.438C257.801,139.044 257.97,146.659 257.797,154.257C256.621,154.401 255.446,154.342 254.27,154.35C254.285,146.65 254.246,138.943 254.275,131.243ZM219.246,144.735C219.46,144.754 219.891,144.799 220.109,144.824C220.942,147.056 221.771,149.312 222.266,151.643C222.128,151.767 221.856,152.015 221.716,152.139C220.779,149.709 220.04,147.21 219.246,144.735ZM291.943,144.606C292.141,144.655 292.537,144.754 292.736,144.804C292.111,147.14 291.342,149.446 290.47,151.708L289.646,151.985C290.296,149.491 291.154,147.056 291.943,144.606ZM231.169,141.536C232.444,141.258 232.151,142.845 232.473,143.604C232.716,145.389 233.659,147.224 233.301,149C233.162,148.96 232.895,148.881 232.756,148.841C232.037,146.45 231.725,143.966 231.169,141.536ZM280.104,141.357C280.283,141.477 280.64,141.714 280.819,141.833C280.402,144.189 279.876,146.535 279.286,148.856C279.127,148.871 278.81,148.896 278.651,148.905C278.814,146.346 279.539,143.852 280.104,141.357ZM243.36,139.532C243.573,139.606 243.995,139.751 244.207,139.824C244.584,142.285 244.624,144.784 244.877,147.264C244.674,147.155 244.277,146.942 244.074,146.833C243.806,144.402 243.458,141.977 243.36,139.532ZM267.894,139.894C268.102,139.79 268.514,139.591 268.722,139.493C268.528,141.958 268.326,144.437 267.894,146.872C267.72,146.966 267.383,147.15 267.215,147.244C267.264,144.779 267.646,142.339 267.894,139.894Z"/>
+ <path android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData="M253.523,428.569L247.085,410.253L249.946,410.253L255.055,425.682L260.19,410.253L262.846,410.253L256.409,428.569L253.523,428.569ZM265.426,410.253L268.109,410.253L268.109,428.569L265.426,428.569L265.426,410.253ZM171.629,391.326L174.311,391.326L174.311,409.641L171.629,409.641L171.629,391.326ZM179.011,391.326L181.694,391.326L181.694,409.641L179.011,409.641L179.011,391.326ZM338.277,409.641L331.84,391.326L334.701,391.326L339.81,406.755L344.944,391.326L347.601,391.326L341.164,409.641L338.277,409.641ZM159.725,409.641L153.288,391.326L156.149,391.326L161.258,406.755L166.392,391.326L169.049,391.326L162.611,409.641L159.725,409.641ZM390.877,333.747L393.56,333.747L393.56,352.063L390.877,352.063L390.877,333.747ZM402.526,352.063L396.089,333.747L398.95,333.747L404.059,349.176L409.193,333.747L411.85,333.747L405.412,352.063L402.526,352.063ZM105.372,331.189L108.054,331.189L108.054,349.504L105.372,349.504L105.372,331.189ZM112.754,331.189L115.436,331.189L115.436,349.504L112.754,349.504L112.754,331.189ZM120.137,331.189L122.819,331.189L122.819,349.504L120.137,349.504L120.137,331.189ZM93.468,349.504L87.031,331.189L89.892,331.189L95.001,346.618L100.135,331.189L102.792,331.189L96.354,349.504L93.468,349.504ZM95.681,257.495L91.057,265.158L87.966,265.158L94.071,255.783L88.426,246.843L91.491,246.843L95.655,254.046L99.845,246.843L102.884,246.843L97.29,255.758L103.344,265.158L100.279,265.158L95.681,257.495ZM411.85,246.843L414.532,246.843L414.532,265.158L411.85,265.158L411.85,246.843ZM419.232,246.843L421.914,246.843L421.914,265.158L419.232,265.158L419.232,246.843ZM426.615,246.843L429.297,246.843L429.297,265.158L426.615,265.158L426.615,246.843ZM82.704,246.843L85.386,246.843L85.386,265.158L82.704,265.158L82.704,246.843ZM112.639,176.365L108.016,184.029L104.925,184.029L111.03,174.654L105.385,165.713L108.45,165.713L112.614,172.917L116.803,165.713L119.843,165.713L114.249,174.628L120.303,184.029L117.237,184.029L112.639,176.365ZM392.316,162.59L394.999,162.59L394.999,180.906L392.316,180.906L392.316,162.59ZM399.699,162.59L402.381,162.59L402.381,180.906L399.699,180.906L399.699,162.59ZM170.514,112.4L165.891,120.063L162.8,120.063L168.905,110.688L163.26,101.748L166.325,101.748L170.489,108.951L174.678,101.748L177.718,101.748L172.124,110.663L178.178,120.063L175.113,120.063L170.514,112.4ZM180.835,101.748L183.517,101.748L183.517,120.063L180.835,120.063L180.835,101.748ZM329.158,100.961L331.84,100.961L331.84,119.277L329.158,119.277L329.158,100.961ZM251.262,94.084L246.638,101.748L243.547,101.748L249.652,92.373L244.007,83.432L247.072,83.432L251.236,90.636L255.426,83.432L258.465,83.432L252.871,92.347L258.925,101.748L255.86,101.748L251.262,94.084ZM268.964,83.432L271.647,83.432L271.647,101.748L268.964,101.748L268.964,83.432ZM261.582,83.432L264.264,83.432L264.264,101.748L261.582,101.748L261.582,83.432Z"/>
+ <path android:fillAlpha="0.69"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData="M235.58,28.81C267.53,25.89 300.12,29.78 330.44,40.3C378.38,56.74 420.39,89.77 447.75,132.41C470.36,167.25 483.14,208.44 484.01,249.96C485.06,285.21 477.73,320.68 462.71,352.6C446.29,387.71 420.77,418.53 389.27,441.14C356.78,464.67 317.94,479.36 277.99,483.08C241.88,486.54 204.9,481.45 171.23,467.84C127.59,450.44 89.66,419.14 64.28,379.63C41.63,344.77 28.85,303.55 27.99,261.99C26.7,220.02 37.46,177.77 58.66,141.52C82.45,100.36 119.49,67.03 162.92,47.68C185.85,37.39 210.53,30.9 235.58,28.81M236.76,32.94C179.01,37.47 123.78,66.05 86.22,110.08C54.79,146.35 35.59,193.03 32.59,240.94C29.79,280.5 37.9,320.79 55.73,356.21C76.97,398.73 112.14,434.15 154.55,455.63C187.26,472.44 224.22,480.67 260.95,479.93C297.6,479.06 334.06,469.23 365.95,451.08C401.32,431.14 431.09,401.39 451.03,366.02C469.21,334.12 479.05,297.65 479.93,260.98C480.69,223.72 472.2,186.24 454.92,153.18C430.77,106.21 389.39,68.41 340.45,48.56C307.78,35.27 271.9,29.71 236.76,32.94Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/drawable/ic_oneplus_roman_hour.xml b/packages/SystemUI/res-keyguard/drawable/ic_oneplus_roman_hour.xml
new file mode 100644
index 0000000..51f98b6
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/ic_oneplus_roman_hour.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 The BlissRoms 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 android:height="211dp"
+ android:viewportHeight="512"
+ android:viewportWidth="512"
+ android:width="211dp"
+ xmlns:android="http://schemas.android.com/apk/res/android">
+ <path android:fillColor="@*android:color/accent_device_default_light"
+ android:pathData="M252.641,247.472C253.624,246.915 254.388,246.021 254.779,244.938C254.8,244.945 254.8,244.945 254.8,244.945C255.219,243.785 255.21,242.515 254.777,241.36C254.743,241.271 254.709,241.181 254.676,241.091C254.251,239.962 253.412,239.038 252.33,238.508C251.083,237.925 250.294,237.039 250.293,236.049C250.275,224.458 250.214,185.286 250.206,180.031C250.206,179.644 250.328,179.26 250.569,178.898C251.575,177.379 254.4,173.116 255.527,171.416C255.6,171.306 255.786,171.234 255.993,171.235C256.2,171.235 256.384,171.309 256.453,171.42C257.534,173.133 260.246,177.429 261.189,178.924C261.407,179.269 261.52,179.633 261.521,180C261.537,185.131 261.657,224.416 261.693,236.041C261.696,236.898 261.096,237.719 260.027,238.325C259.704,238.508 259.347,238.667 258.964,238.799C258.402,238.995 257.957,239.431 257.748,239.988C257.588,240.388 257.406,240.873 257.23,241.342C256.793,242.508 256.784,243.792 257.208,244.963C257.208,244.964 257.208,244.964 257.208,244.964C257.581,245.999 258.297,246.86 259.217,247.418C262.741,248.726 265.255,252.12 265.255,256.098C265.255,261.206 261.108,265.353 256,265.353C250.892,265.353 246.745,261.206 246.745,256.098C246.745,252.174 249.192,248.818 252.641,247.472Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/drawable/ic_oneplus_roman_minute.xml b/packages/SystemUI/res-keyguard/drawable/ic_oneplus_roman_minute.xml
new file mode 100644
index 0000000..46f2f9b
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/ic_oneplus_roman_minute.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 The BlissRoms 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 android:height="211dp"
+ android:viewportHeight="512"
+ android:viewportWidth="512"
+ android:width="211dp"
+ xmlns:android="http://schemas.android.com/apk/res/android">
+ <path android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData="M255.63,108.758C255.807,108.739 256.152,108.683 256.329,108.656C258.343,115.191 262.221,121.456 261.699,128.504C261.69,161.145 261.895,193.794 261.802,226.434C261.969,229.278 259.312,230.835 258.1,233.063C256.86,236.522 256.273,240.559 257.905,243.999C259.275,247.672 263.564,249.21 264.86,252.93C266.995,258.142 263.359,264.743 257.755,265.554C252.768,266.701 247.379,262.915 246.735,257.853C245.822,254.105 247.957,250.469 250.828,248.222C254.679,245.211 256.124,239.738 254.418,235.179C253.532,231.683 249.756,229.39 250.138,225.511C250.12,191.883 250.017,158.254 250.082,124.635C251.155,119.135 253.756,114.026 255.63,108.758M253.681,251.243C250.017,252.763 249.281,258.254 252.451,260.65C255.536,263.437 261.112,261.33 261.513,257.172C262.38,252.977 257.476,249.304 253.681,251.243Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/drawable/ic_op_analog_dial.xml b/packages/SystemUI/res-keyguard/drawable/ic_op_analog_dial.xml
new file mode 100644
index 0000000..3d85c7d
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/ic_op_analog_dial.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 The BlissRoms 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 android:height="211dp"
+ android:viewportHeight="512"
+ android:viewportWidth="512"
+ android:width="211dp"
+ xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <path
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData="M239.37,18.355C274.524,16.159 310.19,21.827 342.815,35.149C380.073,50.207 413.292,75.054 438.39,106.419C461.153,134.702 477.235,168.315 484.9,203.802C492.109,237.092 492.063,271.954 484.669,305.203C474.885,349.911 451.533,391.47 418.668,423.291C387.466,453.729 347.684,475.305 305.075,484.593C273.577,491.551 240.65,491.924 208.978,485.801C176.922,479.596 146.196,466.586 119.429,447.882C85.294,424.187 57.59,391.327 40.059,353.644C24.351,320.102 16.84,282.793 18.196,245.786C19.43,206.669 30.715,167.921 50.668,134.252C69.105,102.948 94.868,75.986 125.322,56.166C159.196,33.94 198.932,20.792 239.37,18.355ZM240.686,26.168C212.163,27.853 183.951,34.883 158.054,46.986C128.118,60.882 101.289,81.403 79.98,106.604C54.712,136.325 37.248,172.646 29.998,210.985C23.516,244.833 24.791,280.151 33.756,313.426C41.513,342.272 55.045,369.541 73.313,393.17C97.787,425.016 130.801,450.243 168.013,465.382C201.518,479.124 238.341,484.547 274.396,481.326C302.438,478.899 330.004,471.148 355.22,458.65C375.398,448.65 394.102,435.661 410.476,420.198C442.481,390.221 465.567,350.817 475.878,308.178C483.64,276.408 484.429,242.97 478.275,210.852C470.979,172.472 453.473,136.12 428.134,106.399C404.46,78.459 373.98,56.305 340.035,42.542C308.7,29.711 274.468,24.218 240.686,26.168ZM254.92,430.863C256.788,429.962 258.893,429.921 260.92,429.722C260.931,431.191 260.931,432.66 260.941,434.135C258.729,434.314 256.282,434.714 254.756,436.49C253.819,437.366 253.491,438.63 253.015,439.777C254.797,438.308 257.244,437.719 259.502,438.195C261.637,438.666 263.306,440.428 264.023,442.45C264.914,445.389 264.975,448.876 262.968,451.389C259.825,455.639 252.641,455.634 249.426,451.482C247.153,448.63 247.117,444.739 247.475,441.288C247.777,436.792 250.67,432.497 254.92,430.863ZM252.882,444.012C252.984,445.737 252.764,447.637 253.752,449.157C254.848,450.755 257.556,450.586 258.396,448.814C259.763,446.602 259.036,442.491 255.98,442.307C254.628,442.086 253.681,443.105 252.882,444.012ZM46.377,245.018C49.761,242.652 54.943,243.328 57.411,246.707C59.761,249.795 59.689,253.926 59.274,257.597C58.906,261.801 56.223,265.861 52.188,267.341C50.355,268.201 48.307,268.242 46.326,268.457C46.326,266.967 46.326,265.482 46.321,264.003C48.466,263.808 50.944,263.629 52.434,261.852C53.253,261.012 53.478,259.84 53.832,258.77C51.251,260.931 47.058,260.884 44.754,258.345C41.385,254.582 42.086,247.813 46.377,245.018ZM445.327,245.581C448.179,243.195 452.265,243.277 455.644,244.311C458.506,245.268 460.421,248.366 459.822,251.356C459.52,253.338 457.912,254.746 456.253,255.677C457.303,256.21 458.404,256.773 459.136,257.741C461.112,260.337 460.503,264.463 457.887,266.414C454.84,268.733 450.499,268.938 447.012,267.54C444.483,266.573 442.803,264.064 442.711,261.376C444.564,261.361 446.423,261.371 448.282,261.361C448.609,263.311 450.647,264.576 452.541,263.951C455.219,263.439 455.465,259.128 453.007,258.166C451.579,257.679 450.043,257.869 448.568,257.833C448.563,256.445 448.563,255.058 448.568,253.67C449.905,253.645 451.272,253.768 452.588,253.435C454.892,252.713 454.932,248.74 452.572,248.074C450.898,247.455 449.044,248.438 448.594,250.148C446.756,250.148 444.923,250.158 443.09,250.138C443.284,248.412 443.924,246.676 445.327,245.581ZM49.203,248.975C47.964,250.813 47.882,253.527 49.203,255.345C50.468,256.927 52.961,256.358 53.929,254.756C53.811,252.846 54.118,250.757 53.1,249.037C52.255,247.67 50.043,247.521 49.203,248.975ZM238.362,52.68C242.068,51.43 245.734,50.063 249.472,48.891C249.503,56.991 249.477,65.085 249.482,73.185L243.871,73.185C243.876,67.231 243.871,61.276 243.871,55.322C242.033,55.864 240.2,56.397 238.362,56.934C238.356,55.516 238.362,54.098 238.362,52.68ZM259.661,50.278C262.385,48.307 266.045,48.435 269.117,49.408C271.345,50.232 272.87,52.444 272.983,54.799C273.352,57.477 271.892,59.935 270.275,61.932C268.196,64.215 266.132,66.509 264.136,68.864C267.305,68.869 270.474,68.864 273.644,68.869C273.638,70.308 273.638,71.747 273.638,73.185L256.773,73.185C256.768,71.967 256.768,70.748 256.768,69.53C260.091,65.802 264.003,62.546 266.716,58.317C267.878,56.632 267.628,53.371 265.201,53.038C263.025,52.664 261.934,54.984 261.827,56.786C259.968,56.776 258.104,56.791 256.246,56.776C256.399,54.252 257.505,51.712 259.661,50.278Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/drawable/ic_op_analog_hour.xml b/packages/SystemUI/res-keyguard/drawable/ic_op_analog_hour.xml
new file mode 100644
index 0000000..8646295
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/ic_op_analog_hour.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 The BlissRoms 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 android:height="211dp"
+ android:viewportHeight="512"
+ android:viewportWidth="512"
+ android:width="211dp"
+ xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <path
+ android:fillColor="@*android:color/accent_device_default_light"
+ android:pathData="M253.561,131.356l4.877,-0l-0,124.644l-4.877,0z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/drawable/ic_op_analog_minute.xml b/packages/SystemUI/res-keyguard/drawable/ic_op_analog_minute.xml
new file mode 100644
index 0000000..1d4ce75
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/ic_op_analog_minute.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 The BlissRoms 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 android:height="211dp"
+ android:viewportHeight="512"
+ android:viewportWidth="512"
+ android:width="211dp"
+ xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <path
+ android:fillColor="#ffffff"
+ android:pathData="M258.348,243.667C264.155,244.767 268.553,249.874 268.553,256C268.553,262.928 262.928,268.553 256,268.553C249.072,268.553 243.447,262.928 243.447,256C243.447,249.874 247.845,244.767 253.652,243.667L253.652,86.292L258.348,86.292L258.348,243.667Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/drawable/ic_op_minimal_dial.xml b/packages/SystemUI/res-keyguard/drawable/ic_op_minimal_dial.xml
new file mode 100644
index 0000000..f52072d
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/ic_op_minimal_dial.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 The BlissRoms 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 android:height="211dp"
+ android:viewportHeight="512"
+ android:viewportWidth="512"
+ android:width="211dp"
+ xmlns:android="http://schemas.android.com/apk/res/android">
+ <path
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData="M252.573,483.208L252.573,457.63L259.427,457.63L259.427,483.208L252.573,483.208ZM234.583,467.665L232.992,481.984L231.401,481.862L232.992,467.543L234.583,467.665ZM278.886,481.984L277.417,467.788L279.008,467.665L280.599,481.862L278.886,481.984ZM212.553,464.361L209.494,478.435L208.025,478.068L210.962,463.994L212.553,464.361ZM302.384,478.435L299.447,464.361L301.038,464.116L303.975,478.068L302.384,478.435ZM325.392,472.316L320.987,458.731L322.578,458.242L326.983,471.826L325.392,472.316ZM191.013,458.609L186.608,472.316L185.017,471.826L189.422,458.119L191.013,458.609ZM170.208,450.776L164.333,463.871L162.865,463.259L168.739,450.042L170.208,450.776ZM347.667,463.871L341.792,450.776L343.261,450.164L349.135,463.259L347.667,463.871ZM141.719,452.321L139.489,451.021L152.217,428.992L158.092,432.418L145.364,454.448L142.426,452.734L141.692,452.367L141.719,452.321ZM369.574,452.734L366.636,454.448L353.908,432.418L359.783,428.992L372.511,451.021L370.281,452.322L370.308,452.367L369.574,452.734ZM131.534,428.624L123.09,440.251L121.866,439.272L130.31,427.645L131.534,428.624ZM388.91,440.251L380.466,428.747L381.812,427.768L390.134,439.272L388.91,440.251ZM114.278,414.673L104.609,425.32L103.386,424.341L113.054,413.571L114.278,414.673ZM407.391,425.32L397.845,414.795L399.068,413.693L408.614,424.341L407.391,425.32ZM98.368,399.007L87.72,408.553L86.619,407.452L97.389,397.783L98.368,399.007ZM424.28,408.553L413.632,399.007L414.734,397.906L425.381,407.452L424.28,408.553ZM84.293,381.751L72.667,390.195L71.688,388.849L83.437,380.405L84.293,381.751ZM439.333,390.195L427.707,381.751L428.686,380.527L440.312,388.849L439.333,390.195ZM451.082,372.572L428.93,359.844L432.357,353.847L454.387,366.575L451.082,372.572ZM60.918,372.572L57.491,366.575L79.643,353.847L83.07,359.844L60.918,372.572ZM463.198,349.196L450.103,343.322L450.837,341.853L463.81,347.728L463.198,349.196ZM61.897,343.322L48.802,349.196L48.19,347.728L61.285,341.853L61.897,343.322ZM53.942,322.516L40.235,326.922L39.745,325.454L53.452,321.048L53.942,322.516ZM471.765,326.922L458.18,322.516L458.67,321.048L472.255,325.454L471.765,326.922ZM48.067,300.977L33.993,304.036L33.626,302.445L47.7,299.508L48.067,300.977ZM478.007,304.036L464.055,301.099L464.422,299.508L478.374,302.445L478.007,304.036ZM44.518,279.07L30.199,280.538L29.954,278.947L44.273,277.479L44.518,279.07ZM481.801,280.538L467.604,279.07L467.849,277.479L482.046,278.947L481.801,280.538ZM457.691,259.488L457.691,252.634L483.147,252.634L483.147,259.488L457.691,259.488ZM28.853,259.488L28.853,252.634L54.309,252.634L54.309,259.488L28.853,259.488ZM482.046,233.053L467.849,234.521L467.604,232.93L481.801,231.462L482.046,233.053ZM44.273,234.521L29.954,233.053L30.199,231.462L44.518,232.93L44.273,234.521ZM47.7,212.614L33.626,209.555L33.993,207.964L48.067,211.023L47.7,212.614ZM478.374,209.555L464.422,212.492L464.055,211.023L478.007,207.964L478.374,209.555ZM53.33,191.075L39.745,186.546L40.235,185.078L53.942,189.484L53.33,191.075ZM472.255,186.546L458.67,190.952L458.18,189.484L471.765,185.078L472.255,186.546ZM463.81,164.395L450.837,170.147L450.103,168.678L463.198,162.926L463.81,164.395ZM61.285,170.147L48.19,164.395L48.802,162.926L61.897,168.8L61.285,170.147ZM452.734,142.426L453.163,143.1L453.119,143.125L454.387,145.425L432.357,158.153L428.93,152.278L451.082,139.428L452.734,142.426ZM79.643,158.153L57.491,145.425L60.918,139.428L83.07,152.278L79.643,158.153ZM440.19,123.151L428.686,131.595L427.707,130.249L439.333,121.805L440.19,123.151ZM83.437,131.595L71.688,123.151L72.667,121.805L84.293,130.249L83.437,131.595ZM425.381,104.548L414.734,114.217L413.632,112.993L424.28,103.447L425.381,104.548ZM97.389,114.217L86.619,104.548L87.72,103.447L98.368,112.993L97.389,114.217ZM113.054,98.429L103.386,87.781L104.609,86.68L114.278,97.327L113.054,98.429ZM408.614,87.781L399.068,98.307L397.845,97.327L407.391,86.68L408.614,87.781ZM130.31,84.355L121.866,72.728L123.09,71.749L131.534,83.376L130.31,84.355ZM390.134,72.728L381.812,84.232L380.466,83.376L388.91,71.749L390.134,72.728ZM369.574,59.266L370.308,59.633L370.281,59.679L372.511,60.979L359.783,83.131L353.908,79.704L366.636,57.552L369.574,59.266ZM142.426,59.266L145.364,57.552L158.092,79.704L152.217,83.131L139.489,60.979L141.719,59.679L141.692,59.633L142.426,59.266ZM168.739,61.958L162.865,48.863L164.333,48.129L170.208,61.346L168.739,61.958ZM349.135,48.863L343.261,61.836L341.914,61.224L347.667,48.129L349.135,48.863ZM252.573,54.37L252.573,28.792L259.427,28.792L259.427,54.37L252.573,54.37ZM189.545,53.881L185.017,40.174L186.608,39.684L191.013,53.391L189.545,53.881ZM326.983,40.174L322.578,53.758L320.987,53.269L325.392,39.684L326.983,40.174ZM210.962,48.006L208.025,33.932L209.494,33.687L212.553,47.761L210.962,48.006ZM303.975,33.932L301.038,48.006L299.447,47.639L302.384,33.687L303.975,33.932ZM232.992,44.457L231.401,30.138L232.992,30.016L234.583,44.335L232.992,44.457ZM280.477,30.138L279.008,44.335L277.417,44.212L278.886,30.016L280.477,30.138Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/drawable/ic_op_minimal_hour.xml b/packages/SystemUI/res-keyguard/drawable/ic_op_minimal_hour.xml
new file mode 100644
index 0000000..bc5e13c
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/ic_op_minimal_hour.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 The BlissRoms 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 android:height="211dp"
+ android:viewportHeight="512"
+ android:viewportWidth="512"
+ android:width="211dp"
+ xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <path
+ android:fillColor="@*android:color/accent_device_default_light"
+ android:fillType="nonZero"
+ android:pathData="M256,268.108C251.737,268.108 248.326,264.697 248.326,260.434L248.326,139.269C248.326,135.091 251.822,131.595 256,131.595C260.178,131.595 263.674,135.006 263.674,139.269L263.674,260.434C263.674,264.697 260.263,268.108 256,268.108Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/drawable/ic_op_minimal_minute.xml b/packages/SystemUI/res-keyguard/drawable/ic_op_minimal_minute.xml
new file mode 100644
index 0000000..ddedc6a
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/ic_op_minimal_minute.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 The BlissRoms 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 android:height="211dp"
+ android:viewportHeight="512"
+ android:viewportWidth="512"
+ android:width="211dp"
+ xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <path
+ android:fillColor="#ffffff"
+ android:pathData="M251.186,240.94L251.186,33.606C251.186,32.33 251.693,31.105 252.597,30.201C253.497,29.298 254.723,28.791 256.001,28.791L256.001,28.791C257.279,28.791 258.504,29.298 259.405,30.201C260.308,31.105 260.815,32.33 260.815,33.606L260.815,240.94C267.268,242.983 271.948,249.021 271.948,256.146C271.948,264.948 264.803,272.093 256.001,272.093C247.198,272.093 240.054,264.948 240.054,256.146C240.054,249.021 244.733,242.983 251.186,240.94Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/drawable/ic_op_minimalism_dial.xml b/packages/SystemUI/res-keyguard/drawable/ic_op_minimalism_dial.xml
new file mode 100644
index 0000000..c2e879a
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/ic_op_minimalism_dial.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 The BlissRoms 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 android:height="211dp"
+ android:viewportHeight="540"
+ android:viewportWidth="540"
+ android:width="211dp"
+ xmlns:android="http://schemas.android.com/apk/res/android">
+ <path
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData="M264.23,529.42C266.79,525.04 273.97,525.38 276.09,529.99C278.37,534.08 275.39,539.36 270.87,540L269.18,540C264.35,539.4 261.41,533.49 264.23,529.42ZM268.32,250.42C278.25,249.34 288,257.06 289.4,266.92C290.76,274.69 286.76,282.95 279.96,286.88C273.99,290.55 265.99,290.56 260.03,286.86C252.91,282.85 249,274.04 250.75,266.06C252.34,257.72 259.86,251.07 268.32,250.42ZM265.36,258.53C260.13,260.55 256.77,266.43 257.79,271.97C258.69,278.48 265.47,283.45 271.97,282.21C278.87,281.25 283.93,273.72 281.99,266.97C280.4,259.94 272.01,255.57 265.36,258.53ZM0,269.1C0.65,264.28 6.6,261.41 10.64,264.28C14.96,266.87 14.57,273.97 10.01,276.08C5.94,278.36 0.69,275.42 0,270.93L0,269.1ZM529.96,263.91C534.04,261.63 539.31,264.56 540,269.07L540,270.87C539.35,275.68 533.41,278.59 529.37,275.72C525.04,273.15 525.4,266.04 529.96,263.91ZM269.1,0L270.82,0C275.68,0.57 278.6,6.58 275.72,10.63C273.13,14.96 266.03,14.58 263.91,10.01C261.63,5.94 264.59,0.65 269.1,0Z"/>
+ <path
+ android:fillColor="#666666"
+ android:fillType="nonZero"
+ android:pathData="M136.26,491.37C140.92,489.61 146.24,494.14 145.18,499.02C144.57,504.14 137.62,506.6 133.91,503.03C129.94,499.84 131.38,492.76 136.26,491.37ZM399.3,491.42C403.94,489.56 409.36,494.07 408.33,498.98C407.73,504.17 400.66,506.64 396.96,502.95C393.12,499.77 394.51,492.86 399.3,491.42ZM39.25,395.35C43.67,393.04 49.48,397.02 48.94,401.96C48.92,407.26 41.96,410.44 37.93,406.98C33.88,404.14 34.67,397.2 39.25,395.35ZM495.17,395.27C499.94,392.93 505.84,397.72 504.61,402.86C503.87,407.9 496.99,410.26 493.32,406.69C489.59,403.63 490.67,396.99 495.17,395.27ZM494.38,132.54C498.5,129.83 504.62,133.09 504.71,137.99C505.29,143.16 498.98,147.2 494.55,144.41C490.01,142.15 489.89,134.92 494.38,132.54ZM39.25,132.21C43.75,129.88 49.62,134.01 48.93,139.03C48.74,144.17 41.98,147.22 38,143.91C33.89,141.09 34.62,134.09 39.25,132.21ZM399.45,35.59C404.37,33.73 409.85,38.98 408.15,43.98C407.04,48.81 400.28,50.63 396.85,47.09C393.08,43.82 394.64,36.93 399.45,35.59ZM136.43,35.55C141.33,33.82 146.7,39.01 145.01,43.98C143.85,49.01 136.65,50.69 133.36,46.72C129.95,43.27 131.76,36.79 136.43,35.55Z"/>
+ <path
+ android:fillColor="@*android:color/accent_device_default_light"
+ android:fillType="nonZero"
+ android:pathData="M265.36,258.53C272.01,255.57 280.4,259.94 281.99,266.97C283.93,273.72 278.87,281.25 271.97,282.21C265.47,283.45 258.69,278.48 257.79,271.97C256.77,266.43 260.13,260.55 265.36,258.53Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/drawable/ic_op_minimalism_hour.xml b/packages/SystemUI/res-keyguard/drawable/ic_op_minimalism_hour.xml
new file mode 100644
index 0000000..0badc7f
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/ic_op_minimalism_hour.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 The BlissRoms 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 android:height="211dp"
+ android:viewportHeight="512"
+ android:viewportWidth="512"
+ android:width="211dp"
+ xmlns:android="http://schemas.android.com/apk/res/android">
+ <path
+ android:fillColor="@*android:color/accent_device_default_light"
+ android:pathData="M251.423,191.909C251.332,191.828 251.242,191.744 251.155,191.657C250.008,190.509 249.363,188.953 249.363,187.33L249.363,110.416C249.363,108.793 250.008,107.237 251.155,106.089C252.303,104.941 253.86,104.296 255.483,104.296L255.569,104.296C257.192,104.296 258.749,104.941 259.896,106.089C261.044,107.237 261.689,108.793 261.689,110.416L261.689,187.33C261.689,188.953 261.044,190.509 259.896,191.657C259.809,191.744 259.72,191.828 259.629,191.909C259.66,192.113 259.676,192.323 259.676,192.536L259.676,251.85C259.676,254.142 257.818,256 255.526,256C253.234,256 251.376,254.142 251.376,251.85L251.376,192.536C251.376,192.323 251.392,192.113 251.423,191.909Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/drawable/ic_op_minimalism_minute.xml b/packages/SystemUI/res-keyguard/drawable/ic_op_minimalism_minute.xml
new file mode 100644
index 0000000..d0e9f37
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/ic_op_minimalism_minute.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 The BlissRoms 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 android:height="211dp"
+ android:viewportHeight="512"
+ android:viewportWidth="512"
+ android:width="211dp"
+ xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <path
+ android:fillColor="#ffffff"
+ android:pathData="M252.203,192.823C250.486,191.624 249.363,189.632 249.363,187.379L249.363,46.459C249.363,42.794 252.334,39.822 256,39.822C259.665,39.822 262.637,42.794 262.637,46.459L262.637,187.379C262.637,189.632 261.514,191.624 259.797,192.823L259.797,256.944C259.797,259.041 258.098,260.741 256.001,260.741L255.999,260.741C253.902,260.741 252.203,259.041 252.203,256.944L252.203,192.823Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/drawable/oronos_roundbg.xml b/packages/SystemUI/res-keyguard/drawable/oronos_roundbg.xml
new file mode 100644
index 0000000..ee1c4b9
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/oronos_roundbg.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/listview_background_shape">
+ <stroke android:width="4dp" android:color="@color/typeClockAccentColor" />
+ <padding android:left="2dp"
+ android:top="2dp"
+ android:right="2dp"
+ android:bottom="2dp" />
+ <corners android:radius="999dp" />
+ <solid android:color="@*android:color/background_device_default_dark" />
+</shape>
diff --git a/packages/SystemUI/res-keyguard/drawable/sneeky_clock_dial.xml b/packages/SystemUI/res-keyguard/drawable/sneeky_clock_dial.xml
new file mode 100644
index 0000000..bf8599a
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/sneeky_clock_dial.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="150.000000dp"
+ android:height="150.000000dp"
+ android:viewportWidth="512"
+ android:viewportHeight="512">
+
+ <path
+ android:fillColor="#F4F4F4"
+ android:pathData="M51.5,216.6C66.6,131.9,133.2,64.9,217.6,49c-2.8-5.8-4.3-12.2-4.3-19.1c0-4.2,0.6-8.2,1.7-12 c-48.2,8.3-92.5,31.2-127.8,66.4c-35.6,35.6-58.5,80.4-66.6,129c3.6-0.9,7.4-1.5,11.3-1.5C38.9,212,45.6,213.7,51.5,216.6z" />
+ <path
+ android:fillColor="#F4F4F4"
+ android:pathData="M459.5,295.1c-16.8,81.5-81.4,145.8-163.1,161.9c3.2,6.1,5,13.1,5,20.5c0,3.6-0.4,7.1-1.2,10.4 c46.9-8.7,90.1-31.4,124.6-65.9c34.2-34.2,56.7-76.8,65.6-123.2c-3.4,0.8-6.9,1.3-10.6,1.3C472.5,300.1,465.6,298.3,459.5,295.1z" />
+ <path
+ android:fillColor="#F4F4F4"
+ android:pathData="M286.5,16.4c-5.1-11-16.2-18.6-29.1-18.6c-12.8,0-23.8,7.5-29,18.2c-2,4.2-3.2,8.9-3.2,13.9 c0,6.3,1.8,12.1,4.9,17.1c5.7,9,15.8,15.1,27.2,15.1c11.3,0,21.3-5.9,27-14.7c3.2-5,5.1-11,5.1-17.4 C289.5,25.1,288.4,20.5,286.5,16.4z M257.4,53.6c-6.8,0-13-2.9-17.3-7.6c-3.9-4.2-6.3-9.9-6.3-16.1c0-5.6,2-10.8,5.3-14.9 c4.3-5.3,11-8.8,18.4-8.8c7.5,0,14.2,3.5,18.5,9c3.2,4,5.1,9.1,5.1,14.7c0,6.3-2.5,12.1-6.5,16.3C270.2,50.8,264.1,53.6,257.4,53.6 z" />
+ <path
+ android:fillColor="#4285F4"
+ android:pathData="M275.9,15.3c-4.3-5.5-11-9-18.5-9c-7.4,0-14,3.4-18.4,8.8c-3.3,4.1-5.3,9.2-5.3,14.9c0,6.2,2.4,11.9,6.3,16.1 c4.3,4.6,10.5,7.6,17.3,7.6c6.7,0,12.8-2.8,17.1-7.3c4-4.2,6.5-10,6.5-16.3C281,24.4,279.1,19.4,275.9,15.3z" />
+ <path
+ android:fillColor="#F4F4F4"
+ android:pathData="M49.6,229.3c-5.1-3.4-11.2-5.4-17.8-5.4c-4.7,0-9.1,1-13.1,2.8C7.5,231.7-0.3,243-0.3,256 c0,13.4,8.2,24.8,19.8,29.7c3.8,1.6,8,2.5,12.4,2.5c6.9,0,13.2-2.2,18.5-5.8C58.6,276.5,64,266.9,64,256 C64,244.9,58.3,235,49.6,229.3z M49.1,272.2c-4.3,4.6-10.5,7.5-17.3,7.5c-5,0-9.7-1.6-13.5-4.3c-6.1-4.3-10.1-11.4-10.1-19.4 c0-7.8,3.8-14.7,9.6-19.1c3.9-2.9,8.8-4.6,14-4.6c6.6,0,12.6,2.7,16.9,7.1c4.2,4.3,6.8,10.1,6.8,16.5 C55.5,262.3,53,267.9,49.1,272.2z" />
+ <path
+ android:fillColor="#FBBC05"
+ android:pathData="M48.7,239.5c-4.3-4.4-10.3-7.1-16.9-7.1c-5.2,0-10.1,1.7-14,4.6c-5.8,4.3-9.6,11.2-9.6,19.1 c0,8,4,15.1,10.1,19.4c3.8,2.7,8.5,4.3,13.5,4.3c6.8,0,13-2.9,17.3-7.5c3.9-4.2,6.4-9.9,6.4-16.1C55.5,249.6,52.9,243.8,48.7,239.5 z" />
+ <path
+ android:fillColor="#F4F4F4"
+ android:pathData="M493.3,226.8c-4.1-1.9-8.6-2.9-13.4-2.9c-6.5,0-12.5,1.9-17.5,5.2c-8.8,5.7-14.7,15.7-14.7,27 c0,11,5.5,20.7,14,26.5c5.2,3.5,11.4,5.6,18.2,5.6c4.5,0,8.8-0.9,12.7-2.6C504,280.6,512,269.3,512,256 C512,243.1,504.3,231.9,493.3,226.8z M493.7,275.2c-3.9,2.8-8.7,4.5-13.9,4.5c-6.7,0-12.7-2.8-17-7.2c-4.1-4.3-6.7-10.1-6.7-16.4 c0-6.6,2.7-12.6,7.1-16.9c4.3-4.2,10.1-6.8,16.6-6.8c5.4,0,10.4,1.8,14.4,4.9c5.6,4.3,9.3,11.1,9.3,18.8 C503.5,263.9,499.6,270.9,493.7,275.2z" />
+ <path
+ android:fillColor="#EA4335"
+ android:pathData="M494.2,237.3c-4-3-9-4.9-14.4-4.9c-6.5,0-12.3,2.6-16.6,6.8c-4.4,4.3-7.1,10.3-7.1,16.9 c0,6.4,2.5,12.2,6.7,16.4c4.3,4.4,10.3,7.2,17,7.2c5.2,0,10-1.7,13.9-4.5c5.9-4.3,9.8-11.3,9.8-19.1 C503.5,248.4,499.9,241.6,494.2,237.3z" />
+ <path
+ android:fillColor="#F4F4F4"
+ android:pathData="M283.7,459.1c-5.8-8.3-15.5-13.8-26.4-13.8c-11.1,0-20.8,5.6-26.6,14.1c-3.5,5.1-5.5,11.4-5.5,18 c0,4.6,1,8.9,2.7,12.8c5,11.4,16.3,19.3,29.5,19.3c13.3,0,24.8-8.1,29.6-19.7c1.6-3.8,2.5-8,2.5-12.5 C289.5,470.7,287.4,464.4,283.7,459.1z M257.4,501.2c-7.9,0-14.9-3.9-19.2-9.8c-2.8-3.9-4.5-8.7-4.5-13.8c0-6.7,2.8-12.7,7.3-17.1 c4.2-4.1,10-6.6,16.4-6.6c6.3,0,11.9,2.4,16.2,6.4c4.6,4.3,7.5,10.4,7.5,17.3c0,5.1-1.6,9.7-4.3,13.6 C272.4,497.2,265.4,501.2,257.4,501.2z" />
+ <path
+ android:fillColor="#34A853"
+ android:pathData="M273.5,460.3c-4.2-4-9.9-6.4-16.2-6.4c-6.4,0-12.1,2.5-16.4,6.6c-4.5,4.3-7.3,10.3-7.3,17.1 c0,5.2,1.7,9.9,4.5,13.8c4.3,6,11.3,9.8,19.2,9.8c8,0,15.1-4,19.4-10.1c2.7-3.8,4.3-8.5,4.3-13.6 C281,470.7,278.1,464.6,273.5,460.3z" />
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/drawable/sneeky_clock_hand_hour.xml b/packages/SystemUI/res-keyguard/drawable/sneeky_clock_hand_hour.xml
new file mode 100644
index 0000000..1655233
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/sneeky_clock_hand_hour.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="150.000000dp"
+ android:height="150.000000dp"
+ android:viewportWidth="512"
+ android:viewportHeight="512">
+
+ <path
+ android:fillColor="@color/analog_clock_hand_hour_color"
+ android:pathData="M254,273L254,273c-5,0-9-4-9-9V121.9c0-4.9,4.1-9,9-9h0c4.9,0,9,4,9,9V264C263,269,259,273,254,273z" />
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/drawable/sneeky_clock_hand_minute.xml b/packages/SystemUI/res-keyguard/drawable/sneeky_clock_hand_minute.xml
new file mode 100644
index 0000000..3551e95
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/sneeky_clock_hand_minute.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="150.000000dp"
+ android:height="150.000000dp"
+ android:viewportWidth="512"
+ android:viewportHeight="512">
+
+ <path
+ android:fillColor="#F4F4F4"
+ android:pathData="M266.5,253.2l-2.5-3V250v-5.5v-161c0-5-4-9-9-9s-9,4-9,9v161v5.5v0.2l-2.5,3c-2.1,2.4-2.5,4-2.5,9 c0,5.7,0.2,6.3,3.9,9.9c3.7,3.7,4.2,3.9,10.1,3.9c5.9,0,6.4-0.2,10.1-3.9c3.7-3.6,3.9-4.2,3.9-9.9 C269,257.2,268.6,255.6,266.5,253.2z" />
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/drawable/spectrum_clock_dial.xml b/packages/SystemUI/res-keyguard/drawable/spectrum_clock_dial.xml
new file mode 100644
index 0000000..32ebe2e
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/spectrum_clock_dial.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="150.000000dp"
+ android:height="150.000000dp"
+ android:viewportWidth="512"
+ android:viewportHeight="512">
+
+ <path
+ android:fillColor="#F4F4F4"
+ android:pathData="M218.1,457.5c-83-15.4-148.8-80.1-165.7-162.6c-6.2,3.3-13.2,5.1-20.6,5.1c-3.5,0-6.9-0.4-10.2-1.2 c8.9,46.4,31.4,89,65.6,123.2c35.2,35.2,79.4,58,127.5,66.4c-0.9-3.5-1.4-7.2-1.4-10.9C213.3,470.3,215,463.5,218.1,457.5z" />
+ <path
+ android:fillColor="#F4F4F4"
+ android:pathData="M51.5,216.6C66.6,131.9,133.2,64.9,217.6,49c-2.8-5.8-4.3-12.2-4.3-19.1c0-4.2,0.6-8.2,1.7-12 c-48.2,8.3-92.5,31.2-127.8,66.4c-35.6,35.6-58.5,80.4-66.6,129c3.6-0.9,7.4-1.5,11.3-1.5C38.9,212,45.6,213.7,51.5,216.6z" />
+ <path
+ android:fillColor="#F4F4F4"
+ android:pathData="M296.9,49.5c83.2,16.7,148.6,83.2,163.7,166.9c5.8-2.9,12.4-4.5,19.3-4.5c4,0,7.9,0.5,11.6,1.6 c-8.1-48.7-31.1-93.5-66.6-129.1C390.3,49.9,347,27.2,299.9,18.5c1,3.7,1.5,7.5,1.5,11.5C301.4,37,299.8,43.6,296.9,49.5z" />
+ <path
+ android:fillColor="#F4F4F4"
+ android:pathData="M459.5,295.1c-16.8,81.5-81.4,145.8-163.1,161.9c3.2,6.1,5,13.1,5,20.5c0,3.6-0.4,7.1-1.2,10.4 c46.9-8.7,90.1-31.4,124.6-65.9c34.2-34.2,56.7-76.8,65.6-123.2c-3.4,0.8-6.9,1.3-10.6,1.3C472.5,300.1,465.6,298.3,459.5,295.1z" />
+ <path
+ android:fillColor="#F4F4F4"
+ android:pathData="M286.5,16.4c-5.1-11-16.2-18.6-29.1-18.6c-12.8,0-23.8,7.5-29,18.2c-2,4.2-3.2,8.9-3.2,13.9 c0,6.3,1.8,12.1,4.9,17.1c5.7,9,15.8,15.1,27.2,15.1c11.3,0,21.3-5.9,27-14.7c3.2-5,5.1-11,5.1-17.4 C289.5,25.1,288.4,20.5,286.5,16.4z M257.4,53.6c-6.8,0-13-2.9-17.3-7.6c-3.9-4.2-6.3-9.9-6.3-16.1c0-5.6,2-10.8,5.3-14.9 c4.3-5.3,11-8.8,18.4-8.8c7.5,0,14.2,3.5,18.5,9c3.2,4,5.1,9.1,5.1,14.7c0,6.3-2.5,12.1-6.5,16.3C270.2,50.8,264.1,53.6,257.4,53.6 z" />
+ <path
+ android:fillColor="#4285F4"
+ android:pathData="M275.9,15.3c-4.3-5.5-11-9-18.5-9c-7.4,0-14,3.4-18.4,8.8c-3.3,4.1-5.3,9.2-5.3,14.9c0,6.2,2.4,11.9,6.3,16.1 c4.3,4.6,10.5,7.6,17.3,7.6c6.7,0,12.8-2.8,17.1-7.3c4-4.2,6.5-10,6.5-16.3C281,24.4,279.1,19.4,275.9,15.3z" />
+ <path
+ android:fillColor="#F4F4F4"
+ android:pathData="M49.6,229.3c-5.1-3.4-11.2-5.4-17.8-5.4c-4.7,0-9.1,1-13.1,2.8C7.5,231.7-0.3,243-0.3,256 c0,13.4,8.2,24.8,19.8,29.7c3.8,1.6,8,2.5,12.4,2.5c6.9,0,13.2-2.2,18.5-5.8C58.6,276.5,64,266.9,64,256 C64,244.9,58.3,235,49.6,229.3z M49.1,272.2c-4.3,4.6-10.5,7.5-17.3,7.5c-5,0-9.7-1.6-13.5-4.3c-6.1-4.3-10.1-11.4-10.1-19.4 c0-7.8,3.8-14.7,9.6-19.1c3.9-2.9,8.8-4.6,14-4.6c6.6,0,12.6,2.7,16.9,7.1c4.2,4.3,6.8,10.1,6.8,16.5 C55.5,262.3,53,267.9,49.1,272.2z" />
+ <path
+ android:fillColor="#FBBC05"
+ android:pathData="M48.7,239.5c-4.3-4.4-10.3-7.1-16.9-7.1c-5.2,0-10.1,1.7-14,4.6c-5.8,4.3-9.6,11.2-9.6,19.1 c0,8,4,15.1,10.1,19.4c3.8,2.7,8.5,4.3,13.5,4.3c6.8,0,13-2.9,17.3-7.5c3.9-4.2,6.4-9.9,6.4-16.1C55.5,249.6,52.9,243.8,48.7,239.5 z" />
+ <path
+ android:fillColor="#F4F4F4"
+ android:pathData="M493.3,226.8c-4.1-1.9-8.6-2.9-13.4-2.9c-6.5,0-12.5,1.9-17.5,5.2c-8.8,5.7-14.7,15.7-14.7,27 c0,11,5.5,20.7,14,26.5c5.2,3.5,11.4,5.6,18.2,5.6c4.5,0,8.8-0.9,12.7-2.6C504,280.6,512,269.3,512,256 C512,243.1,504.3,231.9,493.3,226.8z M493.7,275.2c-3.9,2.8-8.7,4.5-13.9,4.5c-6.7,0-12.7-2.8-17-7.2c-4.1-4.3-6.7-10.1-6.7-16.4 c0-6.6,2.7-12.6,7.1-16.9c4.3-4.2,10.1-6.8,16.6-6.8c5.4,0,10.4,1.8,14.4,4.9c5.6,4.3,9.3,11.1,9.3,18.8 C503.5,263.9,499.6,270.9,493.7,275.2z" />
+ <path
+ android:fillColor="#EA4335"
+ android:pathData="M494.2,237.3c-4-3-9-4.9-14.4-4.9c-6.5,0-12.3,2.6-16.6,6.8c-4.4,4.3-7.1,10.3-7.1,16.9 c0,6.4,2.5,12.2,6.7,16.4c4.3,4.4,10.3,7.2,17,7.2c5.2,0,10-1.7,13.9-4.5c5.9-4.3,9.8-11.3,9.8-19.1 C503.5,248.4,499.9,241.6,494.2,237.3z" />
+ <path
+ android:fillColor="#F4F4F4"
+ android:pathData="M283.7,459.1c-5.8-8.3-15.5-13.8-26.4-13.8c-11.1,0-20.8,5.6-26.6,14.1c-3.5,5.1-5.5,11.4-5.5,18 c0,4.6,1,8.9,2.7,12.8c5,11.4,16.3,19.3,29.5,19.3c13.3,0,24.8-8.1,29.6-19.7c1.6-3.8,2.5-8,2.5-12.5 C289.5,470.7,287.4,464.4,283.7,459.1z M257.4,501.2c-7.9,0-14.9-3.9-19.2-9.8c-2.8-3.9-4.5-8.7-4.5-13.8c0-6.7,2.8-12.7,7.3-17.1 c4.2-4.1,10-6.6,16.4-6.6c6.3,0,11.9,2.4,16.2,6.4c4.6,4.3,7.5,10.4,7.5,17.3c0,5.1-1.6,9.7-4.3,13.6 C272.4,497.2,265.4,501.2,257.4,501.2z" />
+ <path
+ android:fillColor="#34A853"
+ android:pathData="M273.5,460.3c-4.2-4-9.9-6.4-16.2-6.4c-6.4,0-12.1,2.5-16.4,6.6c-4.5,4.3-7.3,10.3-7.3,17.1 c0,5.2,1.7,9.9,4.5,13.8c4.3,6,11.3,9.8,19.2,9.8c8,0,15.1-4,19.4-10.1c2.7-3.8,4.3-8.5,4.3-13.6 C281,470.7,278.1,464.6,273.5,460.3z" />
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/drawable/spectrum_clock_hand_hour.xml b/packages/SystemUI/res-keyguard/drawable/spectrum_clock_hand_hour.xml
new file mode 100644
index 0000000..1655233
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/spectrum_clock_hand_hour.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="150.000000dp"
+ android:height="150.000000dp"
+ android:viewportWidth="512"
+ android:viewportHeight="512">
+
+ <path
+ android:fillColor="@color/analog_clock_hand_hour_color"
+ android:pathData="M254,273L254,273c-5,0-9-4-9-9V121.9c0-4.9,4.1-9,9-9h0c4.9,0,9,4,9,9V264C263,269,259,273,254,273z" />
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/drawable/spectrum_clock_hand_minute.xml b/packages/SystemUI/res-keyguard/drawable/spectrum_clock_hand_minute.xml
new file mode 100644
index 0000000..3551e95
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/spectrum_clock_hand_minute.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="150.000000dp"
+ android:height="150.000000dp"
+ android:viewportWidth="512"
+ android:viewportHeight="512">
+
+ <path
+ android:fillColor="#F4F4F4"
+ android:pathData="M266.5,253.2l-2.5-3V250v-5.5v-161c0-5-4-9-9-9s-9,4-9,9v161v5.5v0.2l-2.5,3c-2.1,2.4-2.5,4-2.5,9 c0,5.7,0.2,6.3,3.9,9.9c3.7,3.7,4.2,3.9,10.1,3.9c5.9,0,6.4-0.2,10.1-3.9c3.7-3.6,3.9-4.2,3.9-9.9 C269,257.2,268.6,255.6,266.5,253.2z" />
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/drawable/spidey_clock_dial.xml b/packages/SystemUI/res-keyguard/drawable/spidey_clock_dial.xml
new file mode 100644
index 0000000..73ec35d
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/spidey_clock_dial.xml
@@ -0,0 +1,214 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 AospExtended ROM
+ 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="175dp"
+ android:height="175dp"
+ android:viewportWidth="175"
+ android:viewportHeight="175">
+
+ <group>
+ <path
+ android:fillColor="#f44336"
+ android:strokeColor="#171717"
+ android:strokeWidth="5"
+ android:pathData="M 5 87.5 C 5 41.967 41.967 5 87.5 5 C 133.033 5 170 41.967 170 87.5 C 170 133.033 133.033 170 87.5 170 C 41.967 170 5 133.033 5 87.5 Z" />
+ <path
+ android:fillColor="#000000"
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 99.6 83.9 L 94.7 80.6" />
+ <path
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 82.7 99.4 C 82.7 99.4 91.3 102.6 95.2 99" />
+ <path
+ android:fillColor="#000000"
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 88.6 79.3 L 88.4 5" />
+ <path
+ android:fillColor="#000000"
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 83.5 81.5 L 56.1 12.2" />
+ <path
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 84.7 99.9 L 83.233 107.707 L 71.6 169.6" />
+ <path
+ android:fillColor="#000000"
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 91.1 100.8 L 103.1 170" />
+ <path
+ android:fillColor="#000000"
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 44.6 159.5 L 66.4 124.6" />
+ <path
+ android:fillColor="#000000"
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 130.2 159.2 L 113.3 130.3" />
+ <path
+ android:fillColor="#000000"
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 153.6 138.9 L 139.1 127.1" />
+ <path
+ android:fillColor="#000000"
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 167.5 111.2 L 151.3 106" />
+ <path
+ android:fillColor="#000000"
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 170 82.3 L 156.4 84.5" />
+ <path
+ android:fillColor="#000000"
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 163 56.7 L 150.7 61.1" />
+ <path
+ android:fillColor="#000000"
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 146.8 31.8 L 138.3 39.1" />
+ <path
+ android:fillColor="#000000"
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 23 139.4 L 37.3 127.2" />
+ <path
+ android:fillColor="#000000"
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 8.3 112.3 L 24.3 106.5" />
+ <path
+ android:fillColor="#000000"
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 5 83.4 L 18.6 85.2" />
+ <path
+ android:fillColor="#000000"
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 12.1 54.8 L 24.3 59.7" />
+ <path
+ android:fillColor="#000000"
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 29.5 28.9 L 37 37.3" />
+ <path
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 62.1 26.9 C 62.1 26.9 80.1 27.7 87.5 21.1" />
+ <path
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 89.4 20.5 C 89.4 20.5 105 29.7 114.5 27.3" />
+ <path
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 116.4 27.1 C 116.4 27.1 128.2 40.8 138.1 41.5" />
+ <path
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 61.5 27 C 61.5 27 50.1 41 40.2 42" />
+ <path
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 69.5 46.1 C 69.5 46.1 80.5 46.6 88 42.8" />
+ <path
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 107.9 46 C 107.9 46 96.9 46.5 89.4 42.8" />
+ <path
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 52.3 57.1 C 52.3 57.1 64.1 52.6 69.5 46.2" />
+ <path
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 124.9 57.4 C 124.9 57.4 113.2 52.4 107.8 46.1" />
+ <path
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 77.4 153 C 77.4 153 62.7 142.6 52.9 144.2" />
+ <path
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 100.8 152.2 C 100.8 152.2 83.3 147.9 74.8 152.9" />
+ <path
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 100.1 151.1 C 100.1 151.1 109.8 144.9 121.3 144.3" />
+ <path
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 54.5 143.4 C 54.5 143.4 49.9 134.8 39.4 127" />
+ <path
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 121.9 143.6 C 121.9 143.6 125.9 134.7 135.8 126.2" />
+ <path
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 62.2 70.3 C 67.2 70.7 75.6 62.9 75.6 62.9" />
+ <path
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 101.1 62.5 C 101.1 62.5 111.6 72 115.2 69.8" />
+ <path
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 76.2 61.6 C 76.2 61.6 84.3 61.9 88.3 58.8 C 88.3 58.8 99.4 63.3 102.3 61.8" />
+ <path
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 76.9 85.2 L 81.9 79.8 L 88 78.4 L 93.9 80.3 L 120.6 13.6" />
+ <path
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 82 115.7 C 82 115.7 88.9 114.3 93.7 115.9" />
+ <path
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 78.8 131.5 C 78.8 131.5 89.1 128.2 96.5 131.8" />
+ <path
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 97.7 132.3 C 97.7 132.3 107.9 124.4 109 125.8" />
+ <path
+ android:strokeColor="#171717"
+ android:strokeWidth="3"
+ android:pathData="M 78.3 133.6 C 78.3 133.6 69.6 125.1 65.8 125.9" />
+ <path
+ android:fillColor="#171717"
+ android:strokeColor="#171717"
+ android:strokeWidth="1"
+ android:pathData="M 91.1 92.2 C 91.1 92.2 92.8 122.7 100.9 129.5 C 100.9 129.5 128.2 153.2 148.7 121.7 C 148.7 121.7 166 95.9 149.5 55.5 C 149.5 55.5 140.6 38.5 131.6 31.8 C 131.6 31.8 135.5 46.3 128.8 50.6 C 128.8 50.6 98.8 81.6 94 93.7 L 91.1 92.2 L 91.1 92.2 Z" />
+ <path
+ android:fillColor="#ffffff"
+ android:pathData="M 138 62.9 C 138 62.9 112.1 73.4 99.9 101.3 C 99.9 101.3 106.4 132.2 129.8 125.7 C 130 125.7 159.8 107.4 138 62.9 Z" />
+ <path
+ android:fillColor="#171717"
+ android:strokeColor="#171717"
+ android:strokeWidth="1"
+ android:pathData="M 83.9 91.9 C 83.9 91.9 81.8 122.4 73.5 129 C 73.5 129 45.8 152.3 25.8 120.3 C 25.8 120.3 8.9 94.2 26 54 C 26 54 35.1 37.2 44.3 30.6 C 44.3 30.6 40.2 45.1 46.8 49.4 C 46.8 49.4 76.3 80.9 80.8 93 L 83.9 91.9 L 83.9 91.9 Z" />
+ <path
+ android:fillColor="#ffffff"
+ android:pathData="M 37.4 61.7 C 37.4 61.7 63.1 72.6 74.7 100.7 C 74.7 100.7 67.7 131.5 44.4 124.7 C 44.5 124.7 14.9 106 37.4 61.7 Z" />
+ </group>
+</vector>
diff --git a/packages/SystemUI/res-keyguard/drawable/spidey_clock_hand_hour.xml b/packages/SystemUI/res-keyguard/drawable/spidey_clock_hand_hour.xml
new file mode 100644
index 0000000..b0254d2
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/spidey_clock_hand_hour.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Dirty Unicorns 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="175.000000dp"
+ android:height="175.000000dp"
+ android:viewportWidth="512.000000"
+ android:viewportHeight="512.000000">
+
+ <group
+ android:translateY="512.000000"
+ android:scaleX="0.100000"
+ android:scaleY="-0.100000">
+ <path
+ android:fillColor="#FFFFFF"
+ android:strokeWidth="1"
+ android:pathData="M2486 4279 l-26 -20 0 -893 0 -893 23 -21 c33 -31 105 -31 135 1 l22 23 0 891 0 892 -26 20 c-16 13 -41 21 -64 21 -23 0 -48 -8 -64 -21z" />
+ </group>
+</vector>
diff --git a/packages/SystemUI/res-keyguard/drawable/spidey_clock_hand_minute.xml b/packages/SystemUI/res-keyguard/drawable/spidey_clock_hand_minute.xml
new file mode 100644
index 0000000..c4c9e36
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/spidey_clock_hand_minute.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Dirty Unicorns 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="175.000000dp"
+ android:height="175.000000dp"
+ android:viewportWidth="512.000000"
+ android:viewportHeight="512.000000">
+
+ <group
+ android:translateY="512.000000"
+ android:scaleX="0.100000"
+ android:scaleY="-0.100000">
+ <path
+ android:fillColor="#FFFFFF"
+ android:strokeWidth="1"
+ android:pathData="M2486 4529 l-26 -20 0 -946 0 -945 -25 -30 c-21 -24 -25 -40 -25 -90 0 -57 2 -63 39 -99 37 -37 42 -39 101 -39 59 0 64 2 101 39 37 36 39 42 39 99 0 50 -4 66 -25 90 l-25 30 0 945 0 946 -26 20 c-16 13 -41 21 -64 21 -23 0 -48 -8 -64 -21z" />
+ </group>
+</vector>
diff --git a/packages/SystemUI/res-keyguard/layout/analog_clock.xml b/packages/SystemUI/res-keyguard/layout/analog_clock.xml
index ee0df48..4d8574a 100644
--- a/packages/SystemUI/res-keyguard/layout/analog_clock.xml
+++ b/packages/SystemUI/res-keyguard/layout/analog_clock.xml
@@ -17,29 +17,38 @@
<com.android.keyguard.clock.ClockLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- >
- <com.android.keyguard.clock.ImageClock
- android:id="@+id/analog_clock"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- >
- <ImageView
- android:id="@+id/hour_hand"
- android:layout_width="wrap_content"
+ android:layout_height="match_parent">
+
+ <LinearLayout
+ android:layout_width="@dimen/analog_clock_width"
android:layout_height="wrap_content"
- android:src="@drawable/analog_hour_hand"
- />
- <ImageView
- android:id="@+id/minute_hand"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/analog_minute_hand"
- />
- <ImageView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/analog_frame"
- />
- </com.android.keyguard.clock.ImageClock>
+ android:layout_gravity="center"
+ android:orientation="vertical" >
+
+ <com.android.keyguard.clock.ImageClock
+ android:id="@+id/analog_clock"
+ android:layout_width="@dimen/analog_clock_width"
+ android:layout_height="@dimen/analog_clock_height"
+ android:background="@drawable/analog_clock_background">
+
+ <ImageView
+ android:id="@+id/hour_hand"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/analog_hour_hand"/>
+ <ImageView
+ android:id="@+id/minute_hand"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/analog_minute_hand"/>
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/analog_frame"/>
+
+ </com.android.keyguard.clock.ImageClock>
+ <View
+ android:layout_width="@dimen/analog_clock_width"
+ android:layout_height="@dimen/clock_bottom_margin" />
+ </LinearLayout>
</com.android.keyguard.clock.ClockLayout>
diff --git a/packages/SystemUI/res-keyguard/layout/analog_clock_preview.xml b/packages/SystemUI/res-keyguard/layout/analog_clock_preview.xml
new file mode 100644
index 0000000..a5ef5ef
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/analog_clock_preview.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<RelativeLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ >
+
+ <com.android.keyguard.clock.ImageClock
+ android:id="@+id/analog_clock"
+ android:layout_width="@dimen/analog_clock_width"
+ android:layout_height="@dimen/analog_clock_height"
+ android:background="@drawable/analog_clock_background"
+ android:layout_marginBottom="@dimen/clock_bottom_margin"
+ android:layout_centerInParent="true"
+ android:layout_above="@id/date" >
+
+ <ImageView
+ android:id="@+id/hour_hand"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/analog_hour_hand" />
+ <ImageView
+ android:id="@+id/minute_hand"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/analog_minute_hand" />
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/analog_frame"/>
+
+ </com.android.keyguard.clock.ImageClock>
+
+ <TextClock
+ android:id="@+id/date"
+ style="@stype/widget_big"
+ android:layout_width="@dimen/analog_clock_width"
+ android:layout_height="wrap_content"
+ android:layout_centerInParent="true"
+ android:letterSpacing="0.03"
+ android:gravity="center_horizontal"
+ android:format12Hour="EEE, MMM d"
+ android:format24Hour="EEE, MMM d"
+ />
+</RelativeLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/layout/binary_clock.xml b/packages/SystemUI/res-keyguard/layout/binary_clock.xml
new file mode 100644
index 0000000..f7ce79b
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/binary_clock.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<com.android.keyguard.clock.ClockLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <LinearLayout
+ android:layout_width="@dimen/binary_clock_width"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:orientation="vertical" >
+
+ <com.android.keyguard.clock.BinaryClock
+ android:id="@+id/binary_clock"
+ android:layout_width="@dimen/binary_clock_width"
+ android:layout_height="@dimen/binary_clock_height"
+ android:layout_gravity="top" />
+ <View
+ android:layout_width="@dimen/binary_clock_width"
+ android:layout_height="@dimen/clock_bottom_margin" />
+
+ </LinearLayout>
+</com.android.keyguard.clock.ClockLayout>
diff --git a/packages/SystemUI/res-keyguard/layout/binary_clock_preview.xml b/packages/SystemUI/res-keyguard/layout/binary_clock_preview.xml
new file mode 100644
index 0000000..6c019ba
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/binary_clock_preview.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<RelativeLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ >
+
+ <LinearLayout
+ android:layout_width="@dimen/binary_clock_width"
+ android:layout_height="wrap_content"
+ android:layout_centerInParent="true"
+ android:layout_above="@id/date"
+ android:orientation="vertical" >
+
+ <com.android.keyguard.clock.BinaryClock
+ android:id="@+id/binary_clock"
+ android:layout_width="@dimen/binary_clock_width"
+ android:layout_height="@dimen/binary_clock_height"
+ android:layout_gravity="top" />
+ <View
+ android:layout_width="@dimen/binary_clock_width"
+ android:layout_height="@dimen/clock_bottom_margin" />
+
+ </LinearLayout>
+ <TextClock
+ android:id="@+id/date"
+ style="@stype/widget_big"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_centerInParent="true"
+ android:letterSpacing="0.03"
+ android:gravity="center_horizontal"
+ android:format12Hour="EEE, MMM d"
+ android:format24Hour="EEE, MMM d"
+ />
+</RelativeLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/layout/bliss_clock.xml b/packages/SystemUI/res-keyguard/layout/bliss_clock.xml
new file mode 100644
index 0000000..9053235
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/bliss_clock.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 The BlissRoms 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.
+-->
+<com.android.keyguard.clock.ClockLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <LinearLayout
+ android:layout_width="@dimen/analog_clock_width"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:orientation="vertical" >
+
+ <com.android.keyguard.clock.ImageClock
+ android:id="@+id/analog_clock"
+ android:layout_gravity="center"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/bliss_clock_dial"/>
+
+ <ImageView
+ android:id="@+id/hour_hand"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/bliss_clock_hand_hour" />
+
+ <ImageView
+ android:id="@+id/minute_hand"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/bliss_clock_hand_minute" />
+
+ </com.android.keyguard.clock.ImageClock>
+ <View
+ android:layout_width="@dimen/analog_clock_width"
+ android:layout_height="@dimen/clock_bottom_margin" />
+ </LinearLayout>
+</com.android.keyguard.clock.ClockLayout>
+
diff --git a/packages/SystemUI/res-keyguard/layout/bubble_clock.xml b/packages/SystemUI/res-keyguard/layout/bubble_clock.xml
index a6ad254..f68aab3 100644
--- a/packages/SystemUI/res-keyguard/layout/bubble_clock.xml
+++ b/packages/SystemUI/res-keyguard/layout/bubble_clock.xml
@@ -17,26 +17,29 @@
<com.android.keyguard.clock.ClockLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- >
- <com.android.keyguard.clock.ImageClock
- android:id="@+id/analog_clock"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- >
- <ImageView
- android:id="@+id/minute_hand"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/bubble_minute_hand"
- android:tint="@color/bubbleMinuteHandColor"
- />
- <ImageView
- android:id="@+id/hour_hand"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/bubble_hour_hand"
- android:tint="@color/bubbleHourHandColor"
- />
- </com.android.keyguard.clock.ImageClock>
+ android:layout_height="match_parent">
+ <FrameLayout
+ android:layout_width="@dimen/analog_clock_width"
+ android:layout_height="@dimen/custom_clock_height"
+ android:layout_gravity="center" >
+
+ <com.android.keyguard.clock.ImageClock
+ android:id="@+id/bubble_clock"
+ android:layout_marginBottom="@dimen/date_padding"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+ <ImageView
+ android:id="@+id/minute_hand"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/bubble_minute_hand"
+ android:tint="@color/bubbleMinuteHandColor"/>
+ <ImageView
+ android:id="@+id/hour_hand"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/bubble_hour_hand"
+ android:tint="@color/bubbleHourHandColor"/>
+ </com.android.keyguard.clock.ImageClock>
+ </FrameLayout>
</com.android.keyguard.clock.ClockLayout>
diff --git a/packages/SystemUI/res-keyguard/layout/custom_num_clock.xml b/packages/SystemUI/res-keyguard/layout/custom_num_clock.xml
new file mode 100644
index 0000000..a2af5f6
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/custom_num_clock.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 The BlissRoms 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.
+-->
+<com.android.keyguard.clock.ClockLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <LinearLayout
+ android:layout_width="@dimen/analog_clock_width"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:orientation="vertical" >
+
+ <com.android.keyguard.clock.ImageClock
+ android:id="@+id/analog_clock"
+ android:layout_gravity="center"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/custom_num_clock_dial"/>
+
+ <ImageView
+ android:id="@+id/hour_hand"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/custom_num_clock_hand_hour" />
+
+ <ImageView
+ android:id="@+id/minute_hand"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/custom_num_clock_hand_minute" />
+
+ </com.android.keyguard.clock.ImageClock>
+ <View
+ android:layout_width="@dimen/analog_clock_width"
+ android:layout_height="@dimen/clock_bottom_margin" />
+ </LinearLayout>
+</com.android.keyguard.clock.ClockLayout>
+
diff --git a/packages/SystemUI/res-keyguard/layout/digital_clock_custom.xml b/packages/SystemUI/res-keyguard/layout/digital_clock_custom.xml
new file mode 100644
index 0000000..502ee96
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/digital_clock_custom.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<com.android.keyguard.clock.ClockLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal|top">
+ <FrameLayout
+ android:id="@+id/clock_view"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:layout_alignParentTop="true">
+ <TextClock
+ android:id="@+id/clock"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:gravity="center_horizontal"
+ android:paddingBottom="@dimen/title_clock_padding"
+ android:letterSpacing="0.02"
+ android:textColor="?attr/wallpaperTextColor"
+ style="@style/widget_big"
+ android:elegantTextHeight="false"
+ />
+ </FrameLayout>
+</com.android.keyguard.clock.ClockLayout>
diff --git a/packages/SystemUI/res-keyguard/layout/digital_clock_sfuny.xml b/packages/SystemUI/res-keyguard/layout/digital_clock_sfuny.xml
new file mode 100644
index 0000000..0bad796
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/digital_clock_sfuny.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<com.android.keyguard.clock.ClockLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal|top">
+ <LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center|top"
+ android:gravity="center">
+
+ <TextClock
+ android:id="@+id/clockHour"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:gravity="right"
+ android:paddingRight="4dp"
+ android:format12Hour="hh"
+ android:format24Hour="kk"
+ style="@style/widget_big"
+ android:textColor="?attr/wallpaperTextColor"
+ android:textSize="108sp" />
+
+ <TextClock
+ android:id="@+id/clockMinute"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:paddingLeft="4dp"
+ android:format12Hour="mm"
+ android:format24Hour="mm"
+ style="@style/widget_big"
+ android:textColor="?attr/wallpaperTextColor"
+ android:textSize="56sp" />
+
+ </LinearLayout>
+</com.android.keyguard.clock.ClockLayout>
diff --git a/packages/SystemUI/res-keyguard/layout/digital_mnml_box.xml b/packages/SystemUI/res-keyguard/layout/digital_mnml_box.xml
new file mode 100644
index 0000000..4a9e118
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/digital_mnml_box.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<com.android.keyguard.clock.ClockLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal|top">
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="30dp"
+ android:background="#9a000000"
+ android:orientation="vertical"
+ android:padding="16dp">
+
+ <TextView
+ android:id="@+id/clock"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingBottom="@dimen/widget_vertical_padding_clock"
+ android:alpha="0.75"
+ android:letterSpacing="0.05"
+ android:textColor="#fff"
+ android:textSize="20sp" />
+
+ <TextView
+ android:id="@+id/bigDate"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:letterSpacing="0.20"
+ android:textColor="#fff"
+ android:textSize="32sp" />
+ </LinearLayout>
+</com.android.keyguard.clock.ClockLayout>
diff --git a/packages/SystemUI/res-keyguard/layout/digital_mnml_minimal.xml b/packages/SystemUI/res-keyguard/layout/digital_mnml_minimal.xml
new file mode 100644
index 0000000..1b7c7a1
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/digital_mnml_minimal.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<com.android.keyguard.clock.ClockLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal|top">
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:gravity="center_horizontal"
+ android:orientation="vertical">
+
+ <TextClock
+ android:id="@+id/clock"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:paddingBottom="@dimen/widget_vertical_padding_clock"
+ android:gravity="center"
+ android:textColor="?attr/wallpaperTextColor"
+ android:format12Hour="hh | mm | ss"
+ android:format24Hour="kk | mm | ss"
+ android:letterSpacing="0.1"
+ android:textSize="44sp" />
+
+ <TextClock
+ android:id="@+id/date"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:background="@drawable/oronos_roundbg"
+ android:gravity="center"
+ android:textColor="#000"
+ android:paddingLeft="20dp"
+ android:paddingTop="12dp"
+ android:paddingRight="20dp"
+ android:paddingBottom="12dp"
+ android:format12Hour="EEE"
+ android:format24Hour="EEE"
+ android:letterSpacing="0.2"
+ android:textAllCaps="true"
+ android:textSize="14sp" />
+ </LinearLayout>
+</com.android.keyguard.clock.ClockLayout>
diff --git a/packages/SystemUI/res-keyguard/layout/digital_sfuny_preview.xml b/packages/SystemUI/res-keyguard/layout/digital_sfuny_preview.xml
new file mode 100644
index 0000000..5546014
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/digital_sfuny_preview.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ >
+ <LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:gravity="center">
+
+ <TextClock
+ android:id="@+id/clockHour"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:gravity="right"
+ android:paddingRight="4dp"
+ android:format12Hour="hh"
+ android:format24Hour="kk"
+ style="@style/widget_big"
+ android:textColor="?attr/wallpaperTextColor"
+ android:textSize="108sp" />
+
+ <TextClock
+ android:id="@+id/clockMinute"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:paddingLeft="4dp"
+ android:format12Hour="mm"
+ android:format24Hour="mm"
+ style="@style/widget_big"
+ android:textColor="?attr/wallpaperTextColor"
+ android:textSize="56sp" />
+
+ </LinearLayout>
+
+ <TextClock
+ android:id="@+id/date"
+ style="@stype/widget_big"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_centerInParent="true"
+ android:letterSpacing="0.03"
+ android:gravity="center_horizontal"
+ android:format12Hour="EEE, MMM d"
+ android:format24Hour="EEE, MMM d"
+ />
+</RelativeLayout>
diff --git a/packages/SystemUI/res-keyguard/layout/divided_lines_clock.xml b/packages/SystemUI/res-keyguard/layout/divided_lines_clock.xml
new file mode 100644
index 0000000..53f6b29
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/divided_lines_clock.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="utf-8"?>
+<com.android.keyguard.clock.ClockLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal|top">
+ <FrameLayout
+ android:id="@+id/clock_view"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:layout_alignParentTop="true">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal"
+ android:orientation="vertical"
+ android:layout_alignParentTop="true">
+
+ <View
+ android:id="@+id/topLine"
+ android:layout_width="match_parent"
+ android:layout_height="2dp"
+ android:layout_marginLeft="100dp"
+ android:layout_marginRight="100dp"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp"
+ android:layout_weight="1"
+ android:background="?attr/wallpaperTextColor" />
+
+ <TextClock
+ android:id="@+id/date"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:gravity="center_horizontal"
+ android:format12Hour="EEE, MMM d"
+ android:format24Hour="EEE, MMM d"
+ android:textColor="?attr/wallpaperTextColor"
+ android:theme="@style/TextAppearance.Keyguard"
+ android:fontFamily="@*android:string/config_bodyFontFamily"
+ android:textSize="14sp"
+ android:layout_weight="1"
+ android:letterSpacing="0.25"
+ android:textAllCaps="true"
+ android:alpha="0.85"
+ android:paddingTop="15dp" />
+
+ <TextClock
+ android:id="@+id/clock"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:gravity="center_horizontal"
+ android:layout_weight="1"
+ android:paddingTop="15dp"
+ android:paddingBottom="15dp"
+ style="@style/widget_big"
+ android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
+ android:letterSpacing="0.3"
+ android:textColor="?attr/wallpaperTextColor"
+ android:textSize="42sp" />
+
+ <View
+ android:id="@+id/bottomLine"
+ android:layout_width="match_parent"
+ android:layout_height="2dp"
+ android:layout_marginLeft="100dp"
+ android:layout_marginRight="100dp"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp"
+ android:layout_weight="1"
+ android:background="?attr/wallpaperTextColor" />
+
+ </LinearLayout>
+ </FrameLayout>
+</com.android.keyguard.clock.ClockLayout>
diff --git a/packages/SystemUI/res-keyguard/layout/divided_lines_preview.xml b/packages/SystemUI/res-keyguard/layout/divided_lines_preview.xml
new file mode 100644
index 0000000..528be60
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/divided_lines_preview.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ >
+
+ <View
+ android:id="@+id/topLine"
+ android:layout_width="match_parent"
+ android:layout_height="2dp"
+ android:layout_marginLeft="100dp"
+ android:layout_marginRight="100dp"
+ android:layout_above="@id/date"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp"
+ android:layout_weight="1"
+ android:background="?attr/wallpaperTextColor" />
+
+ <TextClock
+ android:id="@+id/date"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:layout_above="@id/clock"
+ android:gravity="center_horizontal"
+ android:format12Hour="EEE, MMM d"
+ android:format24Hour="EEE, MMM d"
+ android:textColor="?attr/wallpaperTextColor"
+ android:theme="@style/TextAppearance.Keyguard"
+ android:fontFamily="@*android:string/config_bodyFontFamily"
+ android:textSize="14sp"
+ android:layout_weight="1"
+ android:letterSpacing="0.25"
+ android:textAllCaps="true"
+ android:alpha="0.85"
+ android:paddingTop="15dp" />
+
+ <TextClock
+ android:id="@+id/clock"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:layout_centerInParent="true"
+ android:layout_above="@id/bottomLine"
+ android:gravity="center_horizontal"
+ android:format12Hour="hh:mm"
+ android:format24Hour="kk:mm"
+ android:layout_weight="1"
+ android:paddingTop="15dp"
+ android:paddingBottom="15dp"
+ style="@style/widget_big"
+ android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
+ android:letterSpacing="0.3"
+ android:textColor="?attr/wallpaperTextColor"
+ android:textSize="42sp" />
+
+ <View
+ android:id="@+id/bottomLine"
+ android:layout_width="match_parent"
+ android:layout_height="2dp"
+ android:layout_marginLeft="100dp"
+ android:layout_marginRight="100dp"
+ android:layout_centerInParent="true"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp"
+ android:layout_weight="1"
+ android:background="?attr/wallpaperTextColor" />
+
+</RelativeLayout>
diff --git a/packages/SystemUI/res-keyguard/layout/dot_clock.xml b/packages/SystemUI/res-keyguard/layout/dot_clock.xml
new file mode 100644
index 0000000..3bc3c8d
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/dot_clock.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 The BlissRoms 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.
+-->
+<com.android.keyguard.clock.ClockLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <LinearLayout
+ android:layout_width="@dimen/analog_clock_width"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:orientation="vertical" >
+
+ <com.android.keyguard.clock.ImageClock
+ android:id="@+id/analog_clock"
+ android:layout_gravity="center"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/dot_clock_dial"/>
+
+ <ImageView
+ android:id="@+id/hour_hand"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/dot_clock_hand_hour" />
+
+ <ImageView
+ android:id="@+id/minute_hand"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/dot_clock_hand_minute" />
+
+ </com.android.keyguard.clock.ImageClock>
+ <View
+ android:layout_width="@dimen/analog_clock_width"
+ android:layout_height="@dimen/clock_bottom_margin" />
+ </LinearLayout>
+</com.android.keyguard.clock.ClockLayout>
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
index 10cd3cb..4529fbd 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
@@ -58,12 +58,9 @@
<TextView
android:id="@+id/owner_info"
- android:layout_marginLeft="16dp"
- android:layout_marginRight="16dp"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
android:layout_marginTop="@dimen/date_owner_info_margin"
- android:layout_gravity="center_horizontal"
android:layout_centerHorizontal="true"
android:textColor="?attr/wallpaperTextColorSecondary"
android:textSize="@dimen/widget_label_font_size"
diff --git a/packages/SystemUI/res-keyguard/layout/oneplus_numbers_clock.xml b/packages/SystemUI/res-keyguard/layout/oneplus_numbers_clock.xml
new file mode 100644
index 0000000..21924a3
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/oneplus_numbers_clock.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 The BlissRoms 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.
+-->
+<com.android.keyguard.clock.ClockLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <LinearLayout
+ android:layout_width="@dimen/analog_clock_width"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:orientation="vertical" >
+
+ <com.android.keyguard.clock.ImageClock
+ android:id="@+id/analog_clock"
+ android:layout_gravity="center"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_oneplus_numbers_dial"/>
+
+ <ImageView
+ android:id="@+id/hour_hand"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_oneplus_numbers_hour" />
+
+ <ImageView
+ android:id="@+id/minute_hand"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_oneplus_numbers_minute" />
+
+ </com.android.keyguard.clock.ImageClock>
+ <View
+ android:layout_width="@dimen/analog_clock_width"
+ android:layout_height="@dimen/clock_bottom_margin" />
+ </LinearLayout>
+</com.android.keyguard.clock.ClockLayout>
diff --git a/packages/SystemUI/res-keyguard/layout/op_analog_clock.xml b/packages/SystemUI/res-keyguard/layout/op_analog_clock.xml
new file mode 100644
index 0000000..fc9feb1
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/op_analog_clock.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 The BlissRoms 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.
+-->
+<com.android.keyguard.clock.ClockLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <LinearLayout
+ android:layout_width="@dimen/analog_clock_width"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:orientation="vertical" >
+
+ <com.android.keyguard.clock.ImageClock
+ android:id="@+id/analog_clock"
+ android:layout_width="@dimen/analog_clock_width"
+ android:layout_height="@dimen/analog_clock_height">
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_op_analog_dial"/>
+
+ <ImageView
+ android:id="@+id/hour_hand"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_op_analog_hour" />
+
+ <ImageView
+ android:id="@+id/minute_hand"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_op_analog_minute" />
+
+ </com.android.keyguard.clock.ImageClock>
+ <View
+ android:layout_width="@dimen/analog_clock_width"
+ android:layout_height="@dimen/clock_bottom_margin" />
+ </LinearLayout>
+</com.android.keyguard.clock.ClockLayout>
diff --git a/packages/SystemUI/res-keyguard/layout/op_minimal_clock.xml b/packages/SystemUI/res-keyguard/layout/op_minimal_clock.xml
new file mode 100644
index 0000000..3a5ec28
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/op_minimal_clock.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 The BlissRoms 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.
+-->
+<com.android.keyguard.clock.ClockLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <LinearLayout
+ android:layout_width="@dimen/analog_clock_width"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:orientation="vertical" >
+
+ <com.android.keyguard.clock.ImageClock
+ android:id="@+id/analog_clock"
+ android:layout_gravity="center"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_op_minimal_dial"/>
+
+ <ImageView
+ android:id="@+id/hour_hand"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_op_minimal_hour" />
+
+ <ImageView
+ android:id="@+id/minute_hand"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_op_minimal_minute" />
+
+ </com.android.keyguard.clock.ImageClock>
+ <View
+ android:layout_width="@dimen/analog_clock_width"
+ android:layout_height="@dimen/clock_bottom_margin" />
+ </LinearLayout>
+</com.android.keyguard.clock.ClockLayout>
diff --git a/packages/SystemUI/res-keyguard/layout/op_minimalism_clock.xml b/packages/SystemUI/res-keyguard/layout/op_minimalism_clock.xml
new file mode 100644
index 0000000..fca397c
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/op_minimalism_clock.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 The BlissRoms 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.
+-->
+<com.android.keyguard.clock.ClockLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <LinearLayout
+ android:layout_width="@dimen/analog_clock_width"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:orientation="vertical" >
+
+ <com.android.keyguard.clock.ImageClock
+ android:id="@+id/analog_clock"
+ android:layout_width="@dimen/analog_clock_width"
+ android:layout_height="@dimen/analog_clock_height">
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_op_minimalism_dial"/>
+
+ <ImageView
+ android:id="@+id/hour_hand"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_op_minimalism_hour" />
+
+ <ImageView
+ android:id="@+id/minute_hand"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_op_minimalism_minute" />
+
+ </com.android.keyguard.clock.ImageClock>
+ <View
+ android:layout_width="@dimen/analog_clock_width"
+ android:layout_height="@dimen/clock_bottom_margin" />
+ </LinearLayout>
+</com.android.keyguard.clock.ClockLayout>
diff --git a/packages/SystemUI/res-keyguard/layout/op_roman_clock.xml b/packages/SystemUI/res-keyguard/layout/op_roman_clock.xml
new file mode 100644
index 0000000..9697edb
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/op_roman_clock.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 The BlissRoms 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.
+-->
+<com.android.keyguard.clock.ClockLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <LinearLayout
+ android:layout_width="@dimen/analog_clock_width"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:orientation="vertical" >
+
+ <com.android.keyguard.clock.ImageClock
+ android:id="@+id/analog_clock"
+ android:layout_gravity="center"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_oneplus_roman_dial"/>
+
+ <ImageView
+ android:id="@+id/hour_hand"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_oneplus_roman_hour" />
+
+ <ImageView
+ android:id="@+id/minute_hand"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_oneplus_roman_minute" />
+
+ </com.android.keyguard.clock.ImageClock>
+ <View
+ android:layout_width="@dimen/analog_clock_width"
+ android:layout_height="@dimen/clock_bottom_margin" />
+ </LinearLayout>
+</com.android.keyguard.clock.ClockLayout>
diff --git a/packages/SystemUI/res-keyguard/layout/sneeky_clock.xml b/packages/SystemUI/res-keyguard/layout/sneeky_clock.xml
new file mode 100644
index 0000000..d4c90e0
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/sneeky_clock.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 The BlissRoms 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.
+-->
+<com.android.keyguard.clock.ClockLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <LinearLayout
+ android:layout_width="@dimen/analog_clock_width"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:orientation="vertical" >
+
+ <com.android.keyguard.clock.ImageClock
+ android:id="@+id/analog_clock"
+ android:layout_gravity="center"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/sneeky_clock_dial"/>
+
+ <ImageView
+ android:id="@+id/hour_hand"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/sneeky_clock_hand_hour" />
+
+ <ImageView
+ android:id="@+id/minute_hand"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/sneeky_clock_hand_minute" />
+
+ </com.android.keyguard.clock.ImageClock>
+ <View
+ android:layout_width="@dimen/analog_clock_width"
+ android:layout_height="@dimen/clock_bottom_margin" />
+ </LinearLayout>
+</com.android.keyguard.clock.ClockLayout>
+
diff --git a/packages/SystemUI/res-keyguard/layout/spectrum_clock.xml b/packages/SystemUI/res-keyguard/layout/spectrum_clock.xml
new file mode 100644
index 0000000..58bacdd
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/spectrum_clock.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 The BlissRoms 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.
+-->
+<com.android.keyguard.clock.ClockLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <LinearLayout
+ android:layout_width="@dimen/analog_clock_width"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:orientation="vertical" >
+
+ <com.android.keyguard.clock.ImageClock
+ android:id="@+id/analog_clock"
+ android:layout_gravity="center"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/spectrum_clock_dial"/>
+
+ <ImageView
+ android:id="@+id/hour_hand"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/spectrum_clock_hand_hour" />
+
+ <ImageView
+ android:id="@+id/minute_hand"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/spectrum_clock_hand_minute" />
+
+ </com.android.keyguard.clock.ImageClock>
+ <View
+ android:layout_width="@dimen/analog_clock_width"
+ android:layout_height="@dimen/clock_bottom_margin" />
+ </LinearLayout>
+</com.android.keyguard.clock.ClockLayout>
+
diff --git a/packages/SystemUI/res-keyguard/layout/spidey_clock.xml b/packages/SystemUI/res-keyguard/layout/spidey_clock.xml
new file mode 100644
index 0000000..2061db3
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/spidey_clock.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 The BlissRoms 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.
+-->
+<com.android.keyguard.clock.ClockLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <LinearLayout
+ android:layout_width="@dimen/analog_clock_width"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:orientation="vertical" >
+
+ <com.android.keyguard.clock.ImageClock
+ android:id="@+id/analog_clock"
+ android:layout_gravity="center"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/spidey_clock_dial"/>
+
+ <ImageView
+ android:id="@+id/hour_hand"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/spidey_clock_hand_hour" />
+
+ <ImageView
+ android:id="@+id/minute_hand"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/spidey_clock_hand_minute" />
+
+ </com.android.keyguard.clock.ImageClock>
+ <View
+ android:layout_width="@dimen/analog_clock_width"
+ android:layout_height="@dimen/clock_bottom_margin" />
+ </LinearLayout>
+</com.android.keyguard.clock.ClockLayout>
diff --git a/packages/SystemUI/res-keyguard/layout/type_aod_clock.xml b/packages/SystemUI/res-keyguard/layout/type_aod_clock.xml
new file mode 100644
index 0000000..28ff5a2
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/type_aod_clock.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<com.android.keyguard.clock.ClockLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ >
+ <include layout="@layout/typographic_clock" />
+</com.android.keyguard.clock.ClockLayout>
diff --git a/packages/SystemUI/res-keyguard/layout/typographic_clock.xml b/packages/SystemUI/res-keyguard/layout/typographic_clock.xml
new file mode 100644
index 0000000..73bb4b9
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/typographic_clock.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<com.android.keyguard.clock.TypographicClock
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/type_clock"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingStart="50dp"
+ android:textAlignment="viewStart"
+ style="@style/widget_big"
+ android:textSize="40dp"
+ />
diff --git a/packages/SystemUI/res-keyguard/values/bliss_arrays.xml b/packages/SystemUI/res-keyguard/values/bliss_arrays.xml
new file mode 100644
index 0000000..492e0a0
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/values/bliss_arrays.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 BlissRoms 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.
+-->
+<resources>
+
+</resources>
diff --git a/packages/SystemUI/res-keyguard/values/bliss_attrs.xml b/packages/SystemUI/res-keyguard/values/bliss_attrs.xml
new file mode 100644
index 0000000..492e0a0
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/values/bliss_attrs.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 BlissRoms 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.
+-->
+<resources>
+
+</resources>
diff --git a/packages/SystemUI/res-keyguard/values/bliss_colors.xml b/packages/SystemUI/res-keyguard/values/bliss_colors.xml
new file mode 100644
index 0000000..23acbfa
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/values/bliss_colors.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 BlissRoms 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.
+-->
+<resources>
+
+ <color name="analog_clock_hour_color">#ff0000</color>
+ <color name="analog_clock_minute_color">#ffffff</color>
+ <color name="analog_clock_bg_color">#303030</color>
+ <color name="binary_clock_dot_color">#ffffff</color>
+ <color name="binary_clock_empty_dot_color">#ffffff</color>
+ <color name="binary_clock_ambient_dot_color">#ffffff</color>
+ <color name="binary_clock_ambient_empty_dot_color">#ffffff</color>
+
+ <!-- Custom Analog clocks -->
+ <color name="analog_clock_border_color">#212121</color>
+ <color name="analog_clock_face_color">#FFFFFF</color>
+ <color name="analog_clock_hand_hour_color">@*android:color/accent_device_default_light</color>
+ <color name="analog_clock_hand_minute_color">#212121</color>
+ <color name="custom_text_clock_top_color">@*android:color/accent_device_default_light</color>
+
+</resources>
diff --git a/packages/SystemUI/res-keyguard/values/bliss_config.xml b/packages/SystemUI/res-keyguard/values/bliss_config.xml
new file mode 100644
index 0000000..492e0a0
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/values/bliss_config.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 BlissRoms 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.
+-->
+<resources>
+
+</resources>
diff --git a/packages/SystemUI/res-keyguard/values/bliss_dimens.xml b/packages/SystemUI/res-keyguard/values/bliss_dimens.xml
new file mode 100644
index 0000000..164600e
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/values/bliss_dimens.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 BlissRoms 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.
+-->
+<resources>
+
+ <!-- The minimum bottom margin of the keyguard security container -->
+ <dimen name="kg_security_container_min_bottom_margin">0dp</dimen>
+
+ <!-- Binary Clock -->
+ <dimen name="binary_clock_dot_size">8dp</dimen>
+ <dimen name="binary_clock_stroke_width">2dp</dimen>
+ <dimen name="binary_clock_width">90dp</dimen>
+ <dimen name="binary_clock_height">90dp</dimen>
+ <dimen name="custom_clock_width">100dp</dimen>
+ <dimen name="custom_clock_height">100dp</dimen>
+ <dimen name="custom_clock_preview_width">200dp</dimen>
+ <dimen name="custom_clock_preview_height">200dp</dimen>
+ <dimen name="custom_clock_left_padding">50dp</dimen>
+ <dimen name="analog_clock_width">200dp</dimen>
+ <dimen name="analog_clock_height">200dp</dimen>
+ <dimen name="date_padding">8dp</dimen>
+ <dimen name="clock_bottom_margin">8dp</dimen>
+
+ <!-- Padding added to keyguard status area when Type clock is in use -->
+ <dimen name="keyguard_status_area_typeclock_padding">32dp</dimen>
+
+</resources>
diff --git a/packages/SystemUI/res-keyguard/values/bliss_strings.xml b/packages/SystemUI/res-keyguard/values/bliss_strings.xml
new file mode 100644
index 0000000..4e5b895
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/values/bliss_strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 BlissRoms 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.
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <string name="clock_title_binary">Binary</string>
+ <string name="clock_title_default_bold">Default (bold)</string>
+ <string name="clock_title_samsung">Samsung</string>
+ <string name="clock_title_samsung_bold">Samsung (bold)</string>
+ <string name="clock_title_mnml_box" translatable="false">MNML\'s Box</string>
+ <string name="clock_title_mnml_minimal" translatable="false">MNML\'s Minimal</string>
+</resources>
diff --git a/packages/SystemUI/res-keyguard/values/bliss_styles.xml b/packages/SystemUI/res-keyguard/values/bliss_styles.xml
new file mode 100644
index 0000000..ffc6e10
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/values/bliss_styles.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 BlissRoms 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.
+-->
+<resources>
+ <style name="widget_big_thin" parent="widget_big" >
+ <item name="android:fontFamily">sans-serif-thin</item>
+ </style>
+
+</resources>
diff --git a/packages/SystemUI/res-keyguard/values/bliss_symbols.xml b/packages/SystemUI/res-keyguard/values/bliss_symbols.xml
new file mode 100644
index 0000000..492e0a0
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/values/bliss_symbols.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 BlissRoms 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.
+-->
+<resources>
+
+</resources>
diff --git a/packages/SystemUI/res-keyguard/values/strings.xml b/packages/SystemUI/res-keyguard/values/strings.xml
index 4b662137..c843f8f 100644
--- a/packages/SystemUI/res-keyguard/values/strings.xml
+++ b/packages/SystemUI/res-keyguard/values/strings.xml
@@ -118,9 +118,6 @@
<string name="keyguard_widget_12_hours_format" translatable="false">h:mm</string>
<!-- Time format strings for fall-back clock widget -->
<string name="keyguard_widget_24_hours_format" translatable="false">kk:mm</string>
- <!-- The character used in keyguard_widget_12_hours_format and keyguard_widget_24_hours_format
- to represent a ":". -->
- <string name="keyguard_fancy_colon" translatable="false"></string>
<!-- Accessibility description of the PIN password view. [CHAR_LIMIT=none] -->
<string name="keyguard_accessibility_pin_area">PIN area</string>
@@ -318,11 +315,140 @@
number">%d</xliff:g> remaining attempts before SIM becomes permanently unusable. Contact carrier for details.</item>
</plurals>
+ <!-- Time displayed on typographic clock face, which displays the time in words.
+ Example:
+
+ It's
+ Four
+ Twenty
+ Nine
+
+ This string requires two arguments: the first in the hours of the time and
+ the second is the minutes of the time. The hours string is obtained from
+ string-array type_clock_hours below and the minutes string is obtained
+ from string-array type_clock_minutes below.
+
+ [CHAR LIMIT=8] -->
+ <plurals name="type_clock_header">
+ <item quantity="one"><annotation name="color">It\u2019s</annotation>\n^1\n^2</item>
+ <item quantity="few"><annotation name="color">It\u2019s</annotation>\n^1\n^2</item>
+ <item quantity="other"><annotation name="color">It\u2019s</annotation>\n^1\n^2</item>
+ </plurals>
+
+ <!-- Hour displayed in words on the typographic clock face. [CHAR LIMIT=12] -->
+ <string-array name="type_clock_hours_12">
+ <item>Twelve</item>
+ <item>One</item>
+ <item>Two</item>
+ <item>Three</item>
+ <item>Four</item>
+ <item>Five</item>
+ <item>Six</item>
+ <item>Seven</item>
+ <item>Eight</item>
+ <item>Nine</item>
+ <item>Ten</item>
+ <item>Eleven</item>
+ </string-array>
+
+ <string-array name="type_clock_hours_24">
+ <item>O</item>
+ <item>One</item>
+ <item>Two</item>
+ <item>Three</item>
+ <item>Four</item>
+ <item>Five</item>
+ <item>Six</item>
+ <item>Seven</item>
+ <item>Eight</item>
+ <item>Nine</item>
+ <item>Ten</item>
+ <item>Eleven</item>
+ <item>Twelve</item>
+ <item>Thirteen</item>
+ <item>Fourteen</item>
+ <item>Fiveteen</item>
+ <item>Sixteen</item>
+ <item>Seventeen</item>
+ <item>Eighteen</item>
+ <item>Nineteen</item>
+ <item>Twenty</item>
+ <item>Twenty One</item>
+ <item>Twenty Two</item>
+ <item>Twenty Three</item>
+ </string-array>
+
+ <!-- Minutes displayed in words on the typographic clock face. [CHAR LIMIT=20] -->
+ <string-array name="type_clock_minutes">
+ <item>O\u2019Clock</item>
+ <item>Oh One</item>
+ <item>Oh Two</item>
+ <item>Oh Three</item>
+ <item>Oh Four</item>
+ <item>Oh Five</item>
+ <item>Oh Six</item>
+ <item>Oh Seven</item>
+ <item>Oh Eight</item>
+ <item>Oh Nine</item>
+ <item>Ten</item>
+ <item>Eleven</item>
+ <item>Twelve</item>
+ <item>Thirteen</item>
+ <item>Fourteen</item>
+ <item>Fifteen</item>
+ <item>Sixteen</item>
+ <item>Seventeen</item>
+ <item>Eighteen</item>
+ <item>Nineteen</item>
+ <item>Twenty</item>
+ <item>Twenty\nOne</item>
+ <item>Twenty\nTwo</item>
+ <item>Twenty\nThree</item>
+ <item>Twenty\nFour</item>
+ <item>Twenty\nFive</item>
+ <item>Twenty\nSix</item>
+ <item>Twenty\nSeven</item>
+ <item>Twenty\nEight</item>
+ <item>Twenty\nNine</item>
+ <item>Thirty</item>
+ <item>Thirty\nOne</item>
+ <item>Thirty\nTwo</item>
+ <item>Thirty\nThree</item>
+ <item>Thirty\nFour</item>
+ <item>Thirty\nFive</item>
+ <item>Thirty\nSix</item>
+ <item>Thirty\nSeven</item>
+ <item>Thirty\nEight</item>
+ <item>Thirty\nNine</item>
+ <item>Forty</item>
+ <item>Forty\nOne</item>
+ <item>Forty\nTwo</item>
+ <item>Forty\nThree</item>
+ <item>Forty\nFour</item>
+ <item>Forty\nFive</item>
+ <item>Forty\nSix</item>
+ <item>Forty\nSeven</item>
+ <item>Forty\nEight</item>
+ <item>Forty\nNine</item>
+ <item>Fifty</item>
+ <item>Fifty\nOne</item>
+ <item>Fifty\nTwo</item>
+ <item>Fifty\nThree</item>
+ <item>Fifty\nFour</item>
+ <item>Fifty\nFive</item>
+ <item>Fifty\nSix</item>
+ <item>Fifty\nSeven</item>
+ <item>Fifty\nEight</item>
+ <item>Fifty\nNine</item>
+ </string-array>
+
<!-- Name of the "Default" clock face, which is the clock face that will be shown by default. [CHAR LIMIT=15]-->
<string name="clock_title_default">Default</string>
<!-- Name of the "Bubble" clock face, which is an analog clock with hands shaped like large bubbles [CHAR LIMIT=15]-->
<string name="clock_title_bubble">Bubble</string>
<!-- Name of the "Analog" clock face [CHAR LIMIT=15]-->
<string name="clock_title_analog">Analog</string>
+ <!-- Name of the "Type" clock face [CHAR LIMIT=15]-->
+ <string name="clock_title_type">Type</string>
</resources>
diff --git a/packages/SystemUI/res/drawable-nodpi/fod_icon_pressed.png b/packages/SystemUI/res/drawable-nodpi/fod_icon_pressed.png
new file mode 100644
index 0000000..4102e28
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/fod_icon_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/android.xml b/packages/SystemUI/res/drawable/android.xml
index 750de05..ce938eb 100644
--- a/packages/SystemUI/res/drawable/android.xml
+++ b/packages/SystemUI/res/drawable/android.xml
@@ -1,5 +1,5 @@
<!--
-Copyright (C) 2014 The Android Open Source Project
+Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2 (the "License");
you may not use this file except in compliance with the License.
@@ -13,25 +13,13 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
+<!-- version of the android head logo optimized for display at 24dp or smaller -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="48dp"
- android:height="48dp"
- android:viewportWidth="48"
- android:viewportHeight="48">
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
<path
- android:name="torso"
- android:pathData="M12,36c0,1.1 0.9,2 2,2l2,0l0,7c0,1.7 1.3,3 3,3c1.7,0 3,-1.3 3,-3l0,-7l4,0l0,7c0,1.7 1.3,3 3,3c1.7,0 3,-1.3 3,-3l0,-7l2,0c1.1,0 2,-0.9 2,-2L36,16L12,16L12,36z"
- android:fillColor="#FFFFFF"/>
- <path
- android:name="leftArm"
- android:pathData="M7,16c-1.7,0 -3,1.3 -3,3l0,14c0,1.7 1.3,3 3,3c1.7,0 3,-1.3 3,-3L10,19C10,17.3 8.7,16 7,16z"
- android:fillColor="#FFFFFF"/>
- <path
- android:name="rightArm"
- android:pathData="M41,16c-1.7,0 -3,1.3 -3,3l0,14c0,1.7 1.3,3 3,3c1.7,0 3,-1.3 3,-3L44,19C44,17.3 42.7,16 41,16z"
- android:fillColor="#FFFFFF"/>
- <path
- android:name="illFormTheHead"
- android:pathData="M31.1,4.3l2.6,-2.6c0.4,-0.4 0.4,-1 0,-1.4c-0.4,-0.4 -1,-0.4 -1.4,0l-3,3C27.7,2.5 25.9,2 24,2c-1.9,0 -3.7,0.5 -5.3,1.3l-3,-3c-0.4,-0.4 -1,-0.4 -1.4,0c-0.4,0.4 -0.4,1 0,1.4l2.6,2.6C13.9,6.5 12,10 12,14l24,0C36,10 34.1,6.5 31.1,4.3zM20.31,9c0,0.72 -0.59,1.31 -1.31,1.31c-0.72,0 -1.31,-0.59 -1.31,-1.31c0,-0.72 0.59,-1.31 1.31,-1.31C19.72,7.69 20.31,8.28 20.31,9zM30.31,9c0,0.72 -0.59,1.31 -1.31,1.31c-0.73,0 -1.31,-0.59 -1.31,-1.31c0,-0.72 0.59,-1.31 1.31,-1.31C29.72,7.69 30.31,8.28 30.31,9z"
- android:fillColor="#FFFFFF"/>
+ android:fillColor="#000000"
+ android:pathData="M17.6 11.48l1.84-3.18a0.63 0.63 0 0 0-1.09-0.63l-1.88 3.24a11.43 11.43 0 0 0-8.94 0L5.65 7.67A0.63 0.63 0 0 0 4.56 8.3l1.84 3.18A10.81 10.81 0 0 0 1 20h22a10.81 10.81 0 0 0-5.4-8.52zM7 17.25A1.25 1.25 0 1 1 8.25 16 1.25 1.25 0 0 1 7 17.25zm10 0A1.25 1.25 0 1 1 18.25 16 1.25 1.25 0 0 1 17 17.25z"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/control_background.xml b/packages/SystemUI/res/drawable/control_background.xml
index cf298b7..e663da0 100644
--- a/packages/SystemUI/res/drawable/control_background.xml
+++ b/packages/SystemUI/res/drawable/control_background.xml
@@ -20,8 +20,8 @@
<item
android:id="@+id/background">
<shape>
- <solid android:color="@color/control_default_background" />
- <corners android:radius="@dimen/control_corner_radius" />
+ <solid android:color="?android:attr/colorPrimary" />
+ <corners android:radius="@*android:dimen/config_dialogCornerRadius" />
</shape>
</item>
<item
diff --git a/packages/SystemUI/res/drawable/control_background_dialog.xml b/packages/SystemUI/res/drawable/control_background_dialog.xml
new file mode 100644
index 0000000..fd233cd
--- /dev/null
+++ b/packages/SystemUI/res/drawable/control_background_dialog.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 The AospExtended 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.
+-->
+<inset xmlns:android="http://schemas.android.com/apk/res/android">
+ <shape>
+ <solid android:color="?android:attr/colorSecondary"/>
+ <corners android:radius="@*android:dimen/config_dialogCornerRadius" />
+ </shape>
+</inset>
diff --git a/packages/SystemUI/res/drawable/control_background_ripple.xml b/packages/SystemUI/res/drawable/control_background_ripple.xml
index 27e3da9..d920a13 100644
--- a/packages/SystemUI/res/drawable/control_background_ripple.xml
+++ b/packages/SystemUI/res/drawable/control_background_ripple.xml
@@ -19,8 +19,8 @@
<item android:id="@android:id/mask">
<shape android:shape="rectangle">
<solid android:color="@android:color/white" />
- <corners android:radius="@dimen/control_corner_radius" />
+ <corners android:radius="@*android:dimen/config_dialogCornerRadius" />
</shape>
</item>
<item android:drawable="@drawable/control_background" />
-</ripple>
\ No newline at end of file
+</ripple>
diff --git a/packages/SystemUI/res/drawable/control_layer.xml b/packages/SystemUI/res/drawable/control_layer.xml
index fe8c4a4..94b0f25 100644
--- a/packages/SystemUI/res/drawable/control_layer.xml
+++ b/packages/SystemUI/res/drawable/control_layer.xml
@@ -18,5 +18,5 @@
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@android:color/transparent"/>
- <corners android:radius="@dimen/control_corner_radius" />
+ <corners android:radius="@*android:dimen/config_dialogCornerRadius" />
</shape>
diff --git a/packages/SystemUI/res/drawable/controls_list_divider.xml b/packages/SystemUI/res/drawable/controls_list_divider.xml
index f8211d5..5fd046c 100644
--- a/packages/SystemUI/res/drawable/controls_list_divider.xml
+++ b/packages/SystemUI/res/drawable/controls_list_divider.xml
@@ -15,8 +15,8 @@
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:tint="@color/control_secondary_text">
- <solid android:color="#33000000" />
+ android:tint="?android:attr/textColorSecondary">
+ <solid android:color="?android:attr/textColorSecondary" />
<size
android:height="1dp"
android:width="1dp" />
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 0000000..7cde6be
--- /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/fod_icon_default.xml b/packages/SystemUI/res/drawable/fod_icon_default.xml
new file mode 100644
index 0000000..38e9d31
--- /dev/null
+++ b/packages/SystemUI/res/drawable/fod_icon_default.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="48dp"
+ android:height="48dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#ffffff"
+ android:pathData="M17.81,4.47c-0.08,0 -0.16,-0.02 -0.23,-0.06C15.66,3.42 14,3 12.01,3c-1.98,0 -3.86,0.47 -5.57,1.41 -0.24,0.13 -0.54,0.04 -0.68,-0.2 -0.13,-0.24 -0.04,-0.55 0.2,-0.68C7.82,2.52 9.86,2 12.01,2c2.13,0 3.99,0.47 6.03,1.52 0.25,0.13 0.34,0.43 0.21,0.67 -0.09,0.18 -0.26,0.28 -0.44,0.28zM3.5,9.72c-0.1,0 -0.2,-0.03 -0.29,-0.09 -0.23,-0.16 -0.28,-0.47 -0.12,-0.7 0.99,-1.4 2.25,-2.5 3.75,-3.27C9.98,4.04 14,4.03 17.15,5.65c1.5,0.77 2.76,1.86 3.75,3.25 0.16,0.22 0.11,0.54 -0.12,0.7 -0.23,0.16 -0.54,0.11 -0.7,-0.12 -0.9,-1.26 -2.04,-2.25 -3.39,-2.94 -2.87,-1.47 -6.54,-1.47 -9.4,0.01 -1.36,0.7 -2.5,1.7 -3.4,2.96 -0.08,0.14 -0.23,0.21 -0.39,0.21zM9.75,21.79c-0.13,0 -0.26,-0.05 -0.35,-0.15 -0.87,-0.87 -1.34,-1.43 -2.01,-2.64 -0.69,-1.23 -1.05,-2.73 -1.05,-4.34 0,-2.97 2.54,-5.39 5.66,-5.39s5.66,2.42 5.66,5.39c0,0.28 -0.22,0.5 -0.5,0.5s-0.5,-0.22 -0.5,-0.5c0,-2.42 -2.09,-4.39 -4.66,-4.39 -2.57,0 -4.66,1.97 -4.66,4.39 0,1.44 0.32,2.77 0.93,3.85 0.64,1.15 1.08,1.64 1.85,2.42 0.19,0.2 0.19,0.51 0,0.71 -0.11,0.1 -0.24,0.15 -0.37,0.15zM16.92,19.94c-1.19,0 -2.24,-0.3 -3.1,-0.89 -1.49,-1.01 -2.38,-2.65 -2.38,-4.39 0,-0.28 0.22,-0.5 0.5,-0.5s0.5,0.22 0.5,0.5c0,1.41 0.72,2.74 1.94,3.56 0.71,0.48 1.54,0.71 2.54,0.71 0.24,0 0.64,-0.03 1.04,-0.1 0.27,-0.05 0.53,0.13 0.58,0.41 0.05,0.27 -0.13,0.53 -0.41,0.58 -0.57,0.11 -1.07,0.12 -1.21,0.12zM14.91,22c-0.04,0 -0.09,-0.01 -0.13,-0.02 -1.59,-0.44 -2.63,-1.03 -3.72,-2.1 -1.4,-1.39 -2.17,-3.24 -2.17,-5.22 0,-1.62 1.38,-2.94 3.08,-2.94 1.7,0 3.08,1.32 3.08,2.94 0,1.07 0.93,1.94 2.08,1.94s2.08,-0.87 2.08,-1.94c0,-3.77 -3.25,-6.83 -7.25,-6.83 -2.84,0 -5.44,1.58 -6.61,4.03 -0.39,0.81 -0.59,1.76 -0.59,2.8 0,0.78 0.07,2.01 0.67,3.61 0.1,0.26 -0.03,0.55 -0.29,0.64 -0.26,0.1 -0.55,-0.04 -0.64,-0.29 -0.49,-1.31 -0.73,-2.61 -0.73,-3.96 0,-1.2 0.23,-2.29 0.68,-3.24 1.33,-2.79 4.28,-4.6 7.51,-4.6 4.55,0 8.25,3.51 8.25,7.83 0,1.62 -1.38,2.94 -3.08,2.94s-3.08,-1.32 -3.08,-2.94c0,-1.07 -0.93,-1.94 -2.08,-1.94s-2.08,0.87 -2.08,1.94c0,1.71 0.66,3.31 1.87,4.51 0.95,0.94 1.86,1.46 3.27,1.85 0.27,0.07 0.42,0.35 0.35,0.61 -0.05,0.23 -0.26,0.38 -0.47,0.38z" />
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_android.xml b/packages/SystemUI/res/drawable/ic_android.xml
index 19ee9a7..ce938eb 100644
--- a/packages/SystemUI/res/drawable/ic_android.xml
+++ b/packages/SystemUI/res/drawable/ic_android.xml
@@ -1,7 +1,7 @@
<!--
-Copyright (C) 2014 The Android Open Source Project
+Copyright (C) 2019 The Android Open Source Project
- Licensed under the Apache License, Version 2.0 (the "License");
+ Licensed under the Apache License, Version 2 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
@@ -13,12 +13,13 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
+<!-- version of the android head logo optimized for display at 24dp or smaller -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24.0dp"
- android:height="24.0dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0">
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
<path
- android:pathData="M6.000000,18.000000c0.000000,0.600000 0.400000,1.000000 1.000000,1.000000l1.000000,0.000000l0.000000,3.500000C8.000000,23.299999 8.700000,24.000000 9.500000,24.000000c0.800000,0.000000 1.500000,-0.700000 1.500000,-1.500000L11.000000,19.000000l2.000000,0.000000l0.000000,3.500000c0.000000,0.800000 0.700000,1.500000 1.500000,1.500000c0.800000,0.000000 1.500000,-0.700000 1.500000,-1.500000L16.000000,19.000000l1.000000,0.000000c0.600000,0.000000 1.000000,-0.400000 1.000000,-1.000000L18.000000,8.000000L6.000000,8.000000L6.000000,18.000000zM3.500000,8.000000C2.700000,8.000000 2.000000,8.700000 2.000000,9.500000l0.000000,7.000000C2.000000,17.299999 2.700000,18.000000 3.500000,18.000000C4.300000,18.000000 5.000000,17.299999 5.000000,16.500000l0.000000,-7.000000C5.000000,8.700000 4.300000,8.000000 3.500000,8.000000zM20.500000,8.000000C19.700001,8.000000 19.000000,8.700000 19.000000,9.500000l0.000000,7.000000c0.000000,0.800000 0.700000,1.500000 1.500000,1.500000c0.800000,0.000000 1.500000,-0.700000 1.500000,-1.500000l0.000000,-7.000000C22.000000,8.700000 21.299999,8.000000 20.500000,8.000000zM15.500000,2.200000l1.300000,-1.300000c0.200000,-0.200000 0.200000,-0.500000 0.000000,-0.700000c-0.200000,-0.200000 -0.500000,-0.200000 -0.700000,0.000000l-1.500000,1.500000C13.900000,1.200000 13.000000,1.000000 12.000000,1.000000c-1.000000,0.000000 -1.900000,0.200000 -2.700000,0.600000L7.900000,0.100000C7.700000,0.000000 7.300000,0.000000 7.100000,0.100000C7.000000,0.300000 7.000000,0.700000 7.100000,0.900000l1.300000,1.300000C7.000000,3.300000 6.000000,5.000000 6.000000,7.000000l12.000000,0.000000C18.000000,5.000000 17.000000,3.200000 15.500000,2.200000zM10.000000,5.000000L9.000000,5.000000L9.000000,4.000000l1.000000,0.000000L10.000000,5.000000zM15.000000,5.000000l-1.000000,0.000000L14.000000,4.000000l1.000000,0.000000L15.000000,5.000000z"
- android:fillColor="#ffffffff"/>
+ android:fillColor="#000000"
+ android:pathData="M17.6 11.48l1.84-3.18a0.63 0.63 0 0 0-1.09-0.63l-1.88 3.24a11.43 11.43 0 0 0-8.94 0L5.65 7.67A0.63 0.63 0 0 0 4.56 8.3l1.84 3.18A10.81 10.81 0 0 0 1 20h22a10.81 10.81 0 0 0-5.4-8.52zM7 17.25A1.25 1.25 0 1 1 8.25 16 1.25 1.25 0 0 1 7 17.25zm10 0A1.25 1.25 0 1 1 18.25 16 1.25 1.25 0 0 1 17 17.25z"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_brightness_thumb.xml b/packages/SystemUI/res/drawable/ic_brightness_thumb.xml
index d721988..af9eaea 100644
--- a/packages/SystemUI/res/drawable/ic_brightness_thumb.xml
+++ b/packages/SystemUI/res/drawable/ic_brightness_thumb.xml
@@ -1,29 +1,27 @@
<!--
-Copyright (C) 2017 The Android Open Source Project
+ Copyright (C) 2018 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
+ 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
+ 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.
+ 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="24dp"
- android:height="24dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0">
+ android:height="13dp"
+ android:width="13dp"
+ android:viewportWidth="42.0"
+ android:viewportHeight="42.0">
<path
- android:pathData="M18,14.48V18h-3.52L12,20.48L9.52,18H6v-3.52L3.52,12L6,9.52V6h3.52L12,3.52L14.48,6H18v3.52L20.48,12L18,14.48z"
- android:fillColor="?android:attr/colorBackgroundFloating" />
-
- <path
- android:pathData=" M20,8.69 V4h-4.69L12,0.69L8.69,4H4v4.69L0.69,12L4,15.31V20h4.69L12,23.31L15.31,20H20v-4.69L23.31,12L20,8.69z M18,14.48V18h-3.52L12,20.48L9.52,18H6v-3.52L3.52,12L6,9.52V6h3.52L12,3.52L14.48,6H18v3.52L20.48,12L18,14.48z M12,7c-2.76,0 -5,2.24 -5,5s2.24,5 5,5s5,-2.24 5,-5S14.76,7 12,7z"
- android:fillColor="?android:attr/colorControlActivated" />
+ android:fillColor="?android:attr/colorControlActivated"
+ android:pathData="M 21 0 C 32.5979797464 0 42 9.40202025355 42 21 C 42 32.5979797464 32.5979797464 42 21 42 C 9.40202025355 42 0 32.5979797464 0 21 C 0 9.40202025355 9.40202025355 0 21 0 Z"
+ android:strokeWidth="1.0" />
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_force_stop.xml b/packages/SystemUI/res/drawable/ic_force_stop.xml
new file mode 100644
index 0000000..eda6079
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_force_stop.xml
@@ -0,0 +1,31 @@
+<!--
+ Copyright (C) 2018 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="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M12,5.99L19.53,19H4.47L12,5.99M12,2L1,21h22L12,2L12,2z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M13,16l-2,0l0,2l2,0l0,-2z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M13,10l-2,0l0,4l2,0l0,-4z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_ambient_display.xml b/packages/SystemUI/res/drawable/ic_qs_ambient_display.xml
new file mode 100644
index 0000000..dcc469f
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_ambient_display.xml
@@ -0,0 +1,51 @@
+<!--
+ 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="64"
+ android:viewportHeight="64">
+
+ <group
+ android:translateY="-988.583">
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M15.0133
+1051.24c-1.3615-0.2479-2.37425-1.2789-2.57968-2.6262-0.06554-0.4298-0.06571-55.8484-0.00018-56.28
+0.09875-0.65024 0.367851-1.20544 0.812983-1.6773 0.402211-0.42637
+0.920053-0.7356 1.49909-0.8952l0.299302-0.0825h16.845 16.845l0.291174
+0.0804c1.24697 0.34447 2.13039 1.32473 2.32019 2.57456 0.06515 0.42898 0.06541
+55.8484 0.0003 56.28-0.188067 1.2461-1.07608 2.2305-2.32306 2.5752l-0.288567
+0.08h-16.755c-13.5267 0-16.7958
+0-16.9665-0.034zm29.8065-31.1862v-19.23h-12.99-12.99v19.23 19.23h12.99
+12.99v-19.23zm-13.459
+11.687c-1.03547-0.2354-1.77837-1.1208-1.83292-2.1845l-0.01654-0.3225h1.87175c1.02946
+0 2.10645 0.01 2.3933 0.02l0.521553 0.02-0.01945 0.253c-0.02847 0.3705-0.09559
+0.6134-0.267159 0.9672-0.135477 0.2794-0.18522 0.3474-0.439626 0.6013-0.31197
+0.3114-0.571617 0.4707-0.976866 0.5995-0.269196 0.085-0.949163 0.111-1.23404
+0.046zm-9.04096-4.1842v-0.6872l1.10534-1.0831 1.10534-1.0831
+0.02483-1.2072c0.01366-0.664 0.02781-2.213 0.03145-3.4422 0.007-2.3727
+0.01776-2.5909 0.162279-3.3 0.234013-1.1483 0.861931-2.2993 1.7263-3.1643
+0.762874-0.7634 1.91951-1.4813 3.00204-1.8633 0.262572-0.093 0.512691-0.1813
+0.555819-0.1969l0.07842-0.029 0.01577-0.426c0.01284-0.3469 0.03018-0.4706
+0.09332-0.666 0.197394-0.6109 0.642609-1.0525 1.21018-1.2004 0.365688-0.095
+0.860153-0.043 1.2089 0.1282 0.234414 0.1149 0.589851 0.4783 0.725931 0.7422
+0.171483 0.3325 0.207933 0.491 0.225975 0.9825 0.01148 0.3126 0.02671 0.4425
+0.0519 0.4425 0.01961 0 0.2844 0.088 0.588423 0.1954 2.74734 0.9715 4.21726
+2.7794 4.71985 5.805 0.171696 1.0336 0.211308 1.7926 0.259098 4.9646l0.03345
+2.22 1.10911 1.095 1.1091 1.095-0.0014 0.6825-0.0014 0.6825h-9.57-9.57v-0.6872z" />
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_brightness_auto_off.xml b/packages/SystemUI/res/drawable/ic_qs_brightness_auto_off.xml
new file mode 100644
index 0000000..9cff976
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_brightness_auto_off.xml
@@ -0,0 +1,27 @@
+<!--
+ 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="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M0 0h24v24H0V0z" />
+ <path
+ android:fillColor="?android:attr/colorControlActivated"
+ android:pathData="M20 8.69V4h-4.69L12 0.69 8.69 4H4v4.69L0.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12 20 8.69zm-2 5.79V18h-3.52L12 20.48 9.52 18H6v-3.52L3.52 12 6 9.52V6h3.52L12 3.52 14.48 6H18v3.52L20.48 12 18 14.48zM12 6v12c3.31 0 6-2.69 6-6s-2.69-6-6-6z" />
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_brightness_auto_on.xml b/packages/SystemUI/res/drawable/ic_qs_brightness_auto_on.xml
new file mode 100644
index 0000000..64af36f
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_brightness_auto_on.xml
@@ -0,0 +1,29 @@
+<!--
+ 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="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0" >
+
+ <path
+ android:fillColor="?android:attr/colorControlActivated"
+ android:pathData="M11,7l-3.2,9h1.9l0.7,-2h3.2l0.7,2h1.9L13,7H11zM10.85,12.65L12,9l1.15,3.65H10.85z" />
+
+ <path
+ android:fillColor="?android:attr/colorControlActivated"
+ android:pathData="M20,8.69 V4h-4.69L12,0.69L8.69,4H4v4.69L0.69,12L4,15.31V20h4.69L12,23.31L15.31,20H20v-4.69L23.31,12L20,8.69z M18,14.48V18h-3.52L12,20.48L9.52,18H6v-3.52L3.52,12L6,9.52V6h3.52L12,3.52L14.48,6H18v3.52L20.48,12L18,14.48z" />
+</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 0000000..57ed1ef
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_caffeine.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (c) 2014-2020, BlissRoms 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"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M2,21V19H20V21H2M20,8V5H18V8H20M20,3A2,2 0 0,1 22,5V8A2,2 0 0,1 20,10H18V13A4,4 0 0,1 14,17H8A4,4 0 0,1 4,13V3H20M16,5H6V13A2,2 0 0,0 8,15H14A2,2 0 0,0 16,13V5Z" />
+</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 0000000..e48ddf1
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_heads_up.xml
@@ -0,0 +1,25 @@
+<!--
+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:height="64dp"
+ android:width="64dp"
+ android:viewportHeight="24.0"
+ android:viewportWidth="24.0">
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M20,2H4c-1.1,0 -2,0.9 -2,2v18l4,-4h14c1.1,0 2,-0.9 2,-2V4c0,-1.1 -0.9,-2 -2,-2z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_battery_saving.xml b/packages/SystemUI/res/drawable/ic_qs_location_battery_saving.xml
new file mode 100644
index 0000000..ec6a043
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_location_battery_saving.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2017 The Dirty Unicorns 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:viewportWidth="24"
+ android:viewportHeight="24"
+ android:width="24dp"
+ android:height="24dp">
+ <path
+ android:pathData="M12 2C8.1 2 5 5.2 5 9c0 5.3 7 13 7 13 0 0 7 -7.8 7 -13 0 -3.8 -3.2 -7 -7 -7zm0 9.5C10.6 11.5 9.5 10.4 9.5 9 9.5 7.6 10.6 6.5 12 6.5c1.4 0 2.5 1.1 2.5 2.5 0 1.4 -1.1 2.5 -2.5 2.5z"
+ android:fillColor="#4dffffff" />
+ <path
+ android:pathData="M12 2C8.1 2 5 5.2 5 9c0 5.3 7 13 7 13L12 11.5C10.6 11.5 9.5 10.4 9.5 9 9.5 7.6 10.6 6.5 12 6.5L12 2Z"
+ android:fillColor="#ffffff" />
+ <path
+ android:pathData="M18.4 13.5c0.3 0 0.6 0.3 0.6 0.6l0 7.2c0 0.3 -0.3 0.6 -0.6 0.6l-4.4 0c-0.3 0 -0.6 -0.3 -0.6 -0.6l0 -7.2c0 -0.3 0.3 -0.6 0.6 -0.6l0.8 0 0 -0.9 2.8 0 0 0.9 0.8 0m-0.3 4.7l0 -0.9 -1.4 0 0 -1.4 -0.9 0 0 1.4 -1.4 0 0 0.9 1.4 0 0 1.4 0.9 0 0 -1.4 1.4 0z"
+ android:fillColor="#ffffff" />
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_location_high_accuracy.xml b/packages/SystemUI/res/drawable/ic_qs_location_high_accuracy.xml
new file mode 100644
index 0000000..c1967ec
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_location_high_accuracy.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2017 The Dirty Unicorns 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:viewportWidth="48"
+ android:viewportHeight="48"
+ android:width="48dp"
+ android:height="48dp">
+ <path
+ android:pathData="M24 5C31.7 5 38 11.3 38 19 38 29.5 24 45 24 45 24 45 10 29.5 10 19 10 11.3 16.3 5 24 5m-6 8l0 12 4 0 0 -4 4 0 0 4 4 0 0 -12 -4 0 0 4 -4 0 0 -4 -4 0z"
+ android:fillColor="@android:color/white" />
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_nfc.xml b/packages/SystemUI/res/drawable/ic_qs_nfc.xml
new file mode 100644
index 0000000..2c08096
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_nfc.xml
@@ -0,0 +1,31 @@
+<!--
+ Copyright (C) 2016 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="48dp"
+ android:height="48dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M4 20h16V4H4v16z" />
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M20 2H4c-1.1 0-2 .9-2 2v16c0 1.1 .9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0
+18H4V4h16v16zM18 6h-5c-1.1 0-2 .9-2 2v2.28c-.6 .35 -1 .98-1 1.72 0 1.1 .9 2 2
+2s2-.9 2-2c0-.74-.4-1.38-1-1.72V8h3v8H8V8h2V6H6v12h12V6z" />
+ <path
+ android:pathData="M0 0h24v24H0z" />
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_nfc_disabled.xml b/packages/SystemUI/res/drawable/ic_qs_nfc_disabled.xml
deleted file mode 100644
index 558f3d0..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_nfc_disabled.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!--
- Copyright (C) 2016 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="24dp"
- android:height="24dp"
- android:viewportWidth="24"
- android:viewportHeight="24">
-
- <path
- android:pathData="M4 20h16V4H4v16z" />
- <path
- android:fillColor="#4DFFFFFF"
- android:pathData="M20 2H4c-1.1 0-2 .9-2 2v16c0 1.1 .9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0
-18H4V4h16v16zM18 6h-5c-1.1 0-2 .9-2 2v2.28c-.6 .35 -1 .98-1 1.72 0 1.1 .9 2 2
-2s2-.9 2-2c0-.74-.4-1.38-1-1.72V8h3v8H8V8h2V6H6v12h12V6z" />
- <path
- android:pathData="M0 0h24v24H0z" />
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_nfc_enabled.xml b/packages/SystemUI/res/drawable/ic_qs_nfc_enabled.xml
deleted file mode 100644
index becb18a..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_nfc_enabled.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!--
- Copyright (C) 2016 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="24dp"
- android:height="24dp"
- android:viewportWidth="24"
- android:viewportHeight="24">
-
- <path
- android:pathData="M4 20h16V4H4v16z" />
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M20 2H4c-1.1 0-2 .9-2 2v16c0 1.1 .9 2 2 2h16c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0
-18H4V4h16v16zM18 6h-5c-1.1 0-2 .9-2 2v2.28c-.6 .35 -1 .98-1 1.72 0 1.1 .9 2 2
-2s2-.9 2-2c0-.74-.4-1.38-1-1.72V8h3v8H8V8h2V6H6v12h12V6z" />
- <path
- android:pathData="M0 0h24v24H0z" />
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_region_screenshot.xml b/packages/SystemUI/res/drawable/ic_qs_region_screenshot.xml
new file mode 100644
index 0000000..6526bf9
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_region_screenshot.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The ABC rom
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="32dp"
+ android:height="32dp"
+ android:viewportWidth="32"
+ android:viewportHeight="32">
+
+ <path
+ android:fillColor="#ffffff"
+ android:pathData="M6.13531,15.9648 C6.13531,12.3536,6.13531,8.74244,6.13531,5.1312
+C6.13531,2.25987,7.86163,0.49832,10.7153,0.49832
+C14.2736,0.49832,17.8144,0.49832,21.3727,0.49832
+C24.0679,0.49832,25.8647,2.27749,25.8647,4.95504
+C25.8647,12.3184,25.8647,19.6816,25.8647,27.0449
+C25.8647,29.7225,24.0679,31.484,21.3727,31.5016
+C17.7967,31.5016,14.2208,31.5016,10.6272,31.5016
+C7.89679,31.5016,6.13524,29.7224,6.13524,26.9568
+C6.13524,23.2928,6.13524,19.6287,6.13524,15.9647 Z M8.67194,4.7613
+C8.67194,11.3847,8.67194,17.9025,8.67194,24.4202
+C13.6043,24.4202,18.4662,24.4202,23.3457,24.4202
+C23.3457,17.8496,23.3457,11.3319,23.3457,4.7613
+C18.431,4.7613,13.5691,4.7613,8.672,4.7613 Z M13.2167,28.6479
+C15.1192,28.6479,16.9336,28.6479,18.7656,28.6479
+C18.7656,28.1899,18.7656,27.7671,18.7656,27.3444
+C16.8807,27.3444,15.0487,27.3444,13.2167,27.3444
+C13.2167,27.7848,13.2167,28.1899,13.2167,28.6479 Z" />
+ <path
+ android:fillColor="#ffffff"
+ android:pathData="M10.2485,12.3007 C10.9355,12.3007,11.552,12.3007,12.2567,12.3007
+C12.2567,11.6137,12.2567,10.9443,12.2567,10.2397
+C12.6619,10.2397,12.9613,10.2397,13.3312,10.2397
+C13.3312,13.023,13.3312,15.771,13.3312,18.6247
+C16.1673,18.6247,18.9329,18.6247,21.7514,18.6247
+C21.7514,19.0122,21.7514,19.2941,21.7514,19.6816
+C21.0996,19.6816,20.4302,19.6816,19.708,19.6816
+C19.708,20.4215,19.708,21.0556,19.708,21.7426
+C19.3381,21.7426,19.0386,21.7426,18.6687,21.7426
+C18.6687,21.1084,18.6687,20.4743,18.6687,19.6992
+C17.6118,19.6992,16.6429,19.6992,15.6564,19.6992
+C14.9518,19.6992,14.2472,19.7168,13.5425,19.6992
+C12.6793,19.6816,12.3094,19.3117,12.3094,18.4485
+C12.2918,16.775,12.3094,15.1192,12.3094,13.3752
+C11.5872,13.3752,10.953,13.3752,10.266,13.3752
+C10.2484,13.0053,10.2484,12.7058,10.2484,12.3007 Z" />
+ <path
+ android:fillColor="#ffffff"
+ android:pathData="M18.6511,13.3577 C17.189,13.3577,15.8502,13.3577,14.4586,13.3577
+C14.4586,12.9878,14.4586,12.6883,14.4586,12.3008
+C15.8855,12.3008,17.2771,12.2832,18.6863,12.3184
+C19.2852,12.336,19.6728,12.7412,19.6728,13.3401
+C19.6904,14.7141,19.6728,16.0881,19.6728,17.515
+C19.3205,17.515,19.021,17.515,18.6511,17.515
+C18.6511,16.1762,18.6511,14.8374,18.6511,13.3577 Z" />
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_ringer_audible.xml b/packages/SystemUI/res/drawable/ic_qs_ringer_audible.xml
new file mode 100644
index 0000000..2974157
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_ringer_audible.xml
@@ -0,0 +1,28 @@
+<!--
+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:fillColor="#FFFFFFFF"
+ android:pathData="M18,17v-6c0,-3.07 -1.63,-5.64 -4.5,-6.32V4c0,-0.83 -0.67,-1.5 -1.5,-1.5S10.5,3.17 10.5,4v0.68C7.64,5.36 6,7.92 6,11v6H4v2h10h0.38H20v-2H18zM16,17H8v-6c0,-2.48 1.51,-4.5 4,-4.5s4,2.02 4,4.5V17z"/>
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4C10,21.1 10.9,22 12,22z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_ringer_silent.xml b/packages/SystemUI/res/drawable/ic_qs_ringer_silent.xml
new file mode 100644
index 0000000..6db508c
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_ringer_silent.xml
@@ -0,0 +1,31 @@
+<!--
+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:fillColor="#FFFFFFFF"
+ android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4C10,21.1 10.9,22 12,22z"/>
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M16,16L2.81,2.81L1.39,4.22l4.85,4.85C6.09,9.68 6,10.33 6,11v6H4v2h12.17l3.61,3.61l1.41,-1.41L16,16zM8,17c0,0 0.01,-6.11 0.01,-6.16L14.17,17H8z"/>
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M12,6.5c2.49,0 4,2.02 4,4.5v2.17l2,2V11c0,-3.07 -1.63,-5.64 -4.5,-6.32V4c0,-0.83 -0.67,-1.5 -1.5,-1.5S10.5,3.17 10.5,4v0.68C9.72,4.86 9.05,5.2 8.46,5.63L9.93,7.1C10.51,6.73 11.2,6.5 12,6.5z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_ringer_vibrate.xml b/packages/SystemUI/res/drawable/ic_qs_ringer_vibrate.xml
new file mode 100644
index 0000000..c87b595
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_ringer_vibrate.xml
@@ -0,0 +1,25 @@
+<!--
+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:fillColor="#FFFFFFFF"
+ android:pathData="M1,9h2v6H1V9zM4,17h2V7H4V17zM21,9v6h2V9H21zM18,17h2V7h-2V17zM17,5.5v13c0,0.83 -0.67,1.5 -1.5,1.5h-7C7.67,20 7,19.33 7,18.5v-13C7,4.67 7.67,4 8.5,4h7C16.33,4 17,4.67 17,5.5zM15,6H9v12h6V6z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_screenshot.xml b/packages/SystemUI/res/drawable/ic_qs_screenshot.xml
new file mode 100644
index 0000000..140ee75
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_screenshot.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The ABC rom
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="32dp"
+ android:height="32dp"
+ android:viewportWidth="32"
+ android:viewportHeight="32">
+
+ <path
+ android:fillColor="#ffffff"
+ android:pathData="M6.13531,15.9648 C6.13531,12.3536,6.13531,8.74244,6.13531,5.1312
+C6.13531,2.25987,7.86163,0.49832,10.7153,0.49832
+C14.2736,0.49832,17.8144,0.49832,21.3727,0.49832
+C24.0679,0.49832,25.8647,2.27749,25.8647,4.95504
+C25.8647,12.3184,25.8647,19.6816,25.8647,27.0449
+C25.8647,29.7225,24.0679,31.484,21.3727,31.5016
+C17.7967,31.5016,14.2208,31.5016,10.6272,31.5016
+C7.89679,31.5016,6.13524,29.7224,6.13524,26.9568
+C6.13524,23.2928,6.13524,19.6287,6.13524,15.9647 Z M8.67194,4.7613
+C8.67194,11.3847,8.67194,17.9025,8.67194,24.4202
+C13.6043,24.4202,18.4662,24.4202,23.3457,24.4202
+C23.3457,17.8496,23.3457,11.3319,23.3457,4.7613
+C18.431,4.7613,13.5691,4.7613,8.672,4.7613 Z M13.2167,28.6479
+C15.1192,28.6479,16.9336,28.6479,18.7656,28.6479
+C18.7656,28.1899,18.7656,27.7671,18.7656,27.3444
+C16.8807,27.3444,15.0487,27.3444,13.2167,27.3444
+C13.2167,27.7848,13.2167,28.1899,13.2167,28.6479 Z" />
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_sync_off.xml b/packages/SystemUI/res/drawable/ic_qs_sync_off.xml
new file mode 100644
index 0000000..2f50804
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_sync_off.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (c) 2015 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="64dp"
+ android:height="64dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M10 6.35V4.26c-.8 .21 -1.55 .54 -2.23 .96 l1.46 1.46c.25-.12 .5 -.24 .77
+-.33zm-7.14-.94l2.36 2.36C4.45 8.99 4 10.44 4 12c0 2.21 .91 4.2 2.36 5.64L4
+20h6v-6l-2.24 2.24C6.68 15.15 6 13.66 6 12c0-1 .25-1.94 .68 -2.77l8.08 8.08c-.25
+.13 -.5 .25 -.77 .34 v2.09c.8-.21 1.55-.54 2.23-.96l2.36 2.36 1.27-1.27L4.14
+4.14 2.86 5.41zM20 4h-6v6l2.24-2.24C17.32 8.85 18 10.34 18 12c0 1-.25 1.94-.68
+2.77l1.46 1.46C19.55 15.01 20 13.56 20 12c0-2.21-.91-4.2-2.36-5.64L20 4z" />
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_sync_on.xml b/packages/SystemUI/res/drawable/ic_qs_sync_on.xml
new file mode 100644
index 0000000..5997690
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_sync_on.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (c) 2015 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="64dp"
+ android:height="64dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01-.25 1.97-.7 2.8l1.46 1.46C19.54 15.03
+20 13.57 20 12c0-4.42-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6 0-1.01 .25 -1.97 .7
+-2.8L5.24 7.74C4.46 8.97 4 10.43 4 12c0 4.42 3.58 8 8 8v3l4-4-4-4v3z" />
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_usb_tether.xml b/packages/SystemUI/res/drawable/ic_qs_usb_tether.xml
new file mode 100644
index 0000000..729dbf8
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_usb_tether.xml
@@ -0,0 +1,26 @@
+<!--
+ Copyright (C) 2015 The CyanogenMod Open Source 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="64dp"
+ android:height="64dp"
+ android:viewportWidth="64"
+ android:viewportHeight="64">
+
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M48.677,29.724h5.255V22.47h4.401l-7.047-9.611l-7.052,9.611h4.443V29.724z M48.677,34.537h5.255v7.254h4.401l-7.047,9.611 l-7.052-9.611h4.443V34.537z M38.85,16.447h-8.444v8.445h2.11v3.251l-8.574,4.36V14.337h4.562l-6.547-8.975l-6.545,8.975h4.561 v21.805l-8.571-3.715v-3.896c1.257-0.734,2.111-2.079,2.111-3.639c0-2.33-1.887-4.222-4.224-4.222c-2.332,0-4.222,1.892-4.222,4.222c0,1.56,0.854,2.905,2.113,3.639v6.668l12.794,5.547v5.609c-2.518,0.837-4.348,3.184-4.348,5.987c0,3.495,2.835,6.333,6.332,6.333c3.501,0,6.337-2.838,6.337-6.333c0-2.802-1.83-5.15-4.352-5.987v-9.113l12.798-6.512v-5.839h2.11L38.85,16.447L38.85,16.447z" />
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_restart_advanced.xml b/packages/SystemUI/res/drawable/ic_restart_advanced.xml
new file mode 100644
index 0000000..f7193d3
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_restart_advanced.xml
@@ -0,0 +1,35 @@
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+ Copyright (C) 2017 The ABC rom
+
+ 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="24.0dp"
+ android:height="24.0dp"
+ android:viewportHeight="24.0"
+ android:viewportWidth="24.0"
+ android:tint="?android:attr/colorControlNormal">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="m 12,4 0,-3 0.0089,5.0067283 L 12,9 12.007813,6.0078125 C 15.907812,6.0078125 19,9.1 19,13 c 0,3.9 -3.1,7 -7,7 l 0,2 c 5,0 9,-4 9,-9 0,-5 -4,-9 -9,-9 z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M5.0,12.9C5.0,11.0 5.8,9.2 7.2,7.9L5.8,6.4C4.0,8.1 3.0,10.5 3.0,12.9c0.0,4.0 2.7,7.6 6.5,8.7l0.5,-1.9C7.1,18.8 5.0,16.1 5.0,12.9z"/>
+ <circle
+ fill="#FF000000"
+ id="path4145"
+ cx="11.844038"
+ cy="5.1732821"
+ r="2.4142135" />
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_restart_bootloader.xml b/packages/SystemUI/res/drawable/ic_restart_bootloader.xml
new file mode 100644
index 0000000..bef1a62
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_restart_bootloader.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Dirty Unicorns 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="24.000000dp"
+ android:height="24.000000dp"
+ android:viewportWidth="512.000000"
+ android:viewportHeight="512.000000"
+ android:tint="?android:attr/colorControlNormal">
+
+ <group
+ android:translateY="512.000000"
+ android:scaleX="0.100000"
+ android:scaleY="-0.100000">
+ <path
+ android:fillColor="#FF000000"
+ android:strokeWidth="1"
+ android:pathData="M2078 4236 c-10 -7 -18 -16 -18 -20 0 -4 -30 -69 -67 -144 -37 -75 -67 -138 -67
+-139 -1 -1 -21 -4 -46 -8 -25 -3 -63 -11 -85 -17 -97 -26 -97 -26 -187 54 -173 153
+-195 162 -252 109 -84 -79 -118 -110 -177 -161 -35 -30 -78 -68 -95 -85 -17 -16
+-43 -39 -59 -50 -41 -30 -36 -60 32 -161 127 -188 136 -205 113 -219 -5 -3 -19 -38
+-31 -78 -22 -71 -24 -80 -27 -104 -1 -7 -5 -12 -9 -11 -5 1 -18 -3 -30 -10 -12 -6
+-30 -13 -40 -15 -10 -2 -28 -8 -40 -15 -12 -7 -30 -12 -40 -12 -11 0 -23 -4 -28 -8
+-6 -5 -39 -19 -73 -32 -85 -31 -89 -42 -62 -166 12 -54 23 -112 25 -129 2 -16 13
+-72 25 -124 11 -52 20 -104 20 -116 0 -12 11 -32 25 -45 24 -22 27 -23 157 -16 73
+4 148 9 166 11 18 1 38 -3 45 -10 27 -27 132 -148 139 -159 3 -6 0 -42 -8 -79 -7
+-37 -16 -86 -19 -108 -3 -23 -8 -45 -11 -50 -3 -5 -8 -31 -11 -57 -4 -38 -1 -51 14
+-63 22 -20 506 -182 528 -177 17 3 24 14 71 113 15 33 36 72 46 87 10 14 18 33 18
+42 0 9 4 16 9 16 5 0 12 13 16 30 6 25 11 30 38 31 18 0 39 2 47 4 151 39 148 39
+184 8 18 -15 44 -37 57 -47 13 -10 51 -42 84 -71 96 -83 113 -87 167 -37 18 16 60
+53 93 82 33 29 67 60 76 69 34 34 151 136 164 144 8 4 17 23 21 43 5 28 2 40 -15
+58 -11 12 -21 25 -21 29 0 3 -25 42 -55 87 -72 106 -89 139 -77 153 12 15 55 147
+55 167 0 20 17 41 28 34 5 -3 9 -1 9 4 0 5 17 14 38 20 36 11 149 51 184 66 9 4 25
+9 35 10 10 1 26 19 36 39 15 29 16 43 8 74 -6 21 -13 54 -16 73 -3 19 -10 55 -15
+80 -9 41 -47 226 -56 275 -2 11 -14 28 -26 38 -20 17 -34 18 -113 13 -49 -4 -124
+-9 -167 -12 l-76 -5 -56 69 c-31 39 -66 76 -76 83 -20 14 -20 16 -5 94 9 44 18 102
+21 129 3 27 10 60 15 73 14 38 11 68 -10 87 -18 17 -482 176 -511 176 -8 0 -23 -7
+-32 -14z m-28 -799 c138 -23 243 -99 305 -222 36 -70 38 -78 39 -178 1 -102 0 -105
+-38 -181 -79 -156 -225 -244 -381 -230 -173 16 -313 114 -365 256 -33 88 -33 220
+-2 298 40 101 139 199 241 240 70 27 113 31 201 17z" />
+ <path
+ android:fillColor="#FF000000"
+ android:strokeWidth="1"
+ android:pathData="M3504 3954 c-11 -90 -57 -119 -136 -84 -25 11 -52 18 -60 15 -17 -7 -98 -149 -98
+-172 1 -10 21 -33 45 -51 40 -29 45 -37 45 -72 0 -34 -6 -43 -45 -76 -25 -20 -45
+-44 -45 -53 0 -21 88 -171 100 -171 5 0 33 9 62 20 51 19 54 20 86 3 35 -19 37 -24
+47 -95 l6 -48 109 0 109 0 6 38 c4 20 8 48 11 62 3 16 17 33 37 43 32 18 35 17 87
+-3 29 -11 59 -19 65 -16 18 7 95 145 95 169 -1 14 -17 34 -45 55 -40 29 -45 37 -45
+72 0 35 5 42 45 71 30 22 45 40 45 55 0 19 -66 144 -88 166 -5 5 -33 0 -66 -13 -57
+-21 -59 -21 -92 -3 -26 14 -35 27 -40 54 -3 19 -8 47 -10 63 l-6 27 -108 0 -109 0
+-7 -56z m184 -244 c131 -80 69 -275 -82 -258 -135 16 -170 187 -53 258 41 25 93 25
+135 0z" />
+ <path
+ android:fillColor="#FF000000"
+ android:strokeWidth="1"
+ android:pathData="M3232 2286 c-100 -19 -166 -37 -172 -46 -5 -7 -6 -64 -4 -125 l5 -112 -36 -27 c-19
+-15 -44 -37 -54 -48 -19 -19 -21 -19 -103 -3 -129 25 -136 25 -157 7 -27 -24 -125
+-314 -117 -347 4 -14 11 -23 16 -20 6 3 10 2 10 -2 0 -5 23 -17 50 -28 28 -11 50
+-22 50 -26 0 -3 17 -14 39 -23 37 -17 39 -20 51 -92 l13 -73 -72 -84 c-39 -47 -71
+-93 -71 -103 0 -11 19 -39 41 -64 23 -25 53 -61 67 -80 15 -19 50 -59 78 -89 62
+-65 64 -64 182 14 l84 55 48 -21 c26 -11 55 -22 65 -23 20 -3 44 -42 45 -73 0 -12
+4 -24 9 -28 5 -3 13 -20 16 -38 12 -53 34 -87 57 -87 36 0 343 61 352 70 8 8 9 49
+2 192 -2 45 0 49 42 80 24 18 48 41 53 51 6 10 14 15 18 12 5 -2 26 -7 46 -11 21
+-3 47 -8 59 -10 89 -19 111 -21 126 -12 9 6 29 49 45 97 16 47 34 98 41 112 15 29
+24 66 31 121 5 34 2 39 -23 50 -16 7 -32 17 -36 23 -4 5 -8 6 -8 2 0 -4 -6 -3 -12
+3 -7 6 -37 23 -67 38 -51 25 -55 30 -58 67 -2 22 -8 55 -14 73 -12 36 -13 33 56
+107 89 96 96 121 51 167 -13 13 -47 52 -76 88 -81 99 -123 140 -143 140 -9 0 -58
+-26 -108 -58 l-91 -59 -69 26 -69 26 -26 70 c-14 39 -31 84 -37 100 -14 41 -27 55
+-46 54 -9 -1 -89 -15 -179 -33z m222 -521 c40 -7 108 -44 138 -76 39 -40 62 -103
+65 -172 2 -80 -9 -117 -51 -173 -96 -128 -280 -141 -402 -28 -40 37 -54 65 -69 136
+-24 111 23 228 113 281 37 23 126 47 152 42 8 -2 32 -6 54 -10z" />
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_restart_recovery.xml b/packages/SystemUI/res/drawable/ic_restart_recovery.xml
new file mode 100644
index 0000000..e00d6f0
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_restart_recovery.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Dirty Unicorns 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="24.000000dp"
+ android:height="24.000000dp"
+ android:viewportWidth="512.000000"
+ android:viewportHeight="512.000000"
+ android:tint="?android:attr/colorControlNormal">
+
+ <group
+ android:translateY="512.000000"
+ android:scaleX="0.100000"
+ android:scaleY="-0.100000">
+ <path
+ android:fillColor="#FF000000"
+ android:strokeWidth="1"
+ android:pathData="M2176 4247 c-25 -25 -26 -31 -66 -312 -32 -231 -25 -210 -83 -239 -72 -35 -188
+-105 -214 -129 -14 -12 -30 -18 -45 -14 -13 3 -117 44 -233 91 -115 47 -222 86
+-237 86 -17 0 -40 -11 -57 -27 -16 -16 -111 -169 -210 -341 -218 -377 -216 -371
+-123 -449 33 -26 94 -75 137 -108 42 -33 106 -83 142 -111 l64 -51 0 -179 0 -179
+-84 -65 c-46 -36 -113 -87 -148 -114 -35 -28 -88 -70 -116 -94 -87 -73 -87 -71 128
+-444 99 -172 194 -325 210 -340 17 -17 40 -28 57 -28 15 0 122 39 237 86 116 47
+219 88 231 91 14 3 42 -10 85 -40 35 -24 101 -63 146 -87 71 -37 82 -46 87 -73 3
+-18 15 -99 26 -182 40 -281 41 -287 66 -312 l23 -23 403 0 c302 1 407 4 418 13 33
+27 41 50 56 158 16 126 54 372 57 375 1 1 38 21 82 44 44 24 109 63 144 87 43 30
+71 43 85 40 12 -3 116 -44 231 -91 116 -47 222 -86 236 -86 45 0 73 34 180 217 56
+98 140 242 186 321 69 119 83 150 83 186 0 48 -11 60 -169 182 -35 27 -102 78 -148
+114 l-84 65 0 180 0 179 153 119 c253 196 248 191 248 242 0 38 -17 73 -126 262
+-69 120 -155 268 -190 329 -64 111 -88 134 -137 134 -12 0 -116 -39 -232 -86 -115
+-47 -218 -88 -227 -91 -11 -3 -45 13 -86 40 -38 25 -105 64 -149 87 l-81 43 -21
+136 c-12 75 -26 177 -32 226 -5 50 -15 105 -20 122 -20 64 -12 63 -457 63 l-403 0
+-23 -23z m564 -1173 c183 -43 338 -163 417 -324 97 -197 97 -373 0 -570 -79 -161
+-234 -281 -417 -324 -270 -64 -565 76 -687 324 -97 196 -97 371 -2 569 98 202 317
+338 549 340 41 0 104 -6 140 -15z" />
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_restart_ui.xml b/packages/SystemUI/res/drawable/ic_restart_ui.xml
new file mode 100644
index 0000000..cb7bc3b
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_restart_ui.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Dirty Unicorns 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="24.000000dp"
+ android:height="24.000000dp"
+ android:viewportWidth="512.000000"
+ android:viewportHeight="512.000000"
+ android:tint="?android:attr/colorControlNormal">
+
+ <group
+ android:translateY="512.000000"
+ android:scaleX="0.100000"
+ android:scaleY="-0.100000">
+ <path
+ android:fillColor="#FF000000"
+ android:strokeWidth="1"
+ android:pathData="M1455 3827 c-38 -48 -37 -59 5 -152 8 -18 96 -248 114 -300 4 -11 6 -21 4 -21 -2
+-1 4 -10 13 -20 9 -11 33 -64 53 -119 21 -55 45 -117 54 -138 17 -42 16 -43 -66
+-105 -28 -20 -215 -205 -256 -253 -41 -48 -179 -239 -194 -269 -7 -14 -22 -41 -34
+-60 -41 -67 -80 -145 -114 -230 -19 -47 -44 -104 -55 -128 -75 -163 -146 -529 -165
+-840 l-7 -122 1789 2 1789 3 -3 135 c-3 147 -10 218 -41 385 -30 168 -80 349 -119
+436 -12 24 -37 83 -56 131 -37 90 -105 223 -137 270 -11 14 -19 29 -19 32 0 14
+-183 256 -237 312 -32 34 -67 73 -78 85 -25 29 -130 120 -153 133 -52 30 -54 37
+-28 112 33 92 64 171 82 205 8 16 14 32 13 35 0 4 3 10 8 13 5 3 14 22 20 41 6 19
+37 102 67 184 31 82 56 158 56 168 0 10 -7 34 -14 53 -13 29 -20 35 -46 35 -30 0
+-33 -5 -81 -105 -27 -58 -49 -107 -49 -110 0 -10 -112 -292 -129 -325 -9 -19 -29
+-64 -42 -99 -13 -35 -29 -65 -36 -68 -13 -5 -125 46 -131 60 -2 4 -11 7 -21 7 -9 0
+-34 9 -55 19 -21 11 -52 23 -69 27 -18 3 -36 10 -42 14 -5 4 -34 13 -64 19 -30 6
+-59 16 -65 20 -15 12 -210 31 -323 31 -120 0 -280 -17 -318 -34 -16 -8 -51 -17 -77
+-20 -27 -4 -48 -11 -48 -15 0 -5 -20 -12 -45 -15 -25 -4 -45 -11 -45 -16 0 -6 -20
+-15 -45 -21 -25 -6 -45 -15 -45 -19 0 -4 -12 -11 -27 -15 -16 -3 -35 -13 -44 -21
+-9 -8 -29 -16 -45 -17 -25 -2 -30 3 -50 53 -13 30 -32 75 -43 100 -11 25 -50 122
+-87 215 -36 94 -84 207 -105 253 -36 79 -39 82 -71 82 -18 -1 -37 -6 -43 -13z m371
+-1477 c60 -21 99 -124 82 -217 -5 -26 -9 -54 -10 -62 -1 -7 -16 -28 -33 -47 -28
+-30 -38 -34 -82 -34 -89 0 -135 61 -135 179 0 143 74 217 178 181z m1640 0 c81 -28
+115 -181 66 -290 -25 -56 -48 -70 -110 -70 -50 0 -58 3 -89 36 -19 20 -32 39 -29
+42 3 3 2 10 -3 16 -15 19 -20 87 -11 137 21 109 89 159 176 129z" />
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_settings_memory.xml b/packages/SystemUI/res/drawable/ic_settings_memory.xml
new file mode 100644
index 0000000..1320fc6
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_settings_memory.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2018 Havoc-OS
+ 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="18dp"
+ android:height="18dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:strokeColor="#ffffffff"
+ android:strokeWidth="2"
+ android:strokeMiterLimit="10"
+ android:pathData="M 5.9 4 H 17.9 V 20 H 5.9 V 4 Z" />
+ <path
+ android:strokeColor="#ffffffff"
+ android:strokeWidth="2"
+ android:strokeMiterLimit="10"
+ android:pathData="M 19 18 L 22 18" />
+ <path
+ android:strokeColor="#ffffffff"
+ android:strokeWidth="2"
+ android:strokeMiterLimit="10"
+ android:pathData="M 19 14 L 22 14" />
+ <path
+ android:strokeColor="#ffffffff"
+ android:strokeWidth="2"
+ android:strokeMiterLimit="10"
+ android:pathData="M 19 10 L 22 10" />
+ <path
+ android:strokeColor="#ffffffff"
+ android:strokeWidth="2"
+ android:strokeMiterLimit="10"
+ android:pathData="M 5 10 L 2 10" />
+ <path
+ android:strokeColor="#ffffffff"
+ android:strokeWidth="2"
+ android:strokeMiterLimit="10"
+ android:pathData="M 5 14 L 2 14" />
+ <path
+ android:strokeColor="#ffffffff"
+ android:strokeWidth="2"
+ android:strokeMiterLimit="10"
+ android:pathData="M 5 18 L 2 18" />
+ <path
+ android:strokeColor="#ffffffff"
+ android:strokeWidth="2"
+ android:strokeMiterLimit="10"
+ android:pathData="M 5 6 L 2 6" />
+ <path
+ android:strokeColor="#ffffffff"
+ android:strokeWidth="2"
+ android:strokeMiterLimit="10"
+ android:pathData="M 22 6 L 19 6" />
+ <path
+ android:strokeColor="#ffffffff"
+ android:strokeWidth="1"
+ android:strokeMiterLimit="10"
+ android:pathData="M 15 17 L 15 14" />
+ <path
+ android:strokeColor="#ffffffff"
+ android:strokeWidth="1"
+ android:strokeMiterLimit="10"
+ android:pathData="M 13 17 L 13 14" />
+ <path
+ android:strokeColor="#ffffffff"
+ android:strokeWidth="1"
+ android:strokeMiterLimit="10"
+ android:pathData="M 11 17 L 11 14" />
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_settings_tuner.xml b/packages/SystemUI/res/drawable/ic_settings_tuner.xml
new file mode 100644
index 0000000..76491fd
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_settings_tuner.xml
@@ -0,0 +1,13 @@
+<?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"
+ android:tint="?android:attr/colorControlNormal" >
+
+ <path
+ android:fillColor="#ffffff"
+ android:strokeWidth="0.1519109"
+ android:pathData="M 3,0 2.7,0.61539 5.85,2.46154 C 5.85,4 5.25,5.23077 3.9,6 L 0.74999,4.15384 0.6,4.46154 c 0.74999,2.30769 2.25,3.84615 5.25,3.84615 0.74999,0 3,2.30769 4.2,3.53846 l 2.4,-2.46154 c -1.2,-1.23076 -3.9,-4 -3.9,-4.76923 C 8.55,1.84616 7.79999,0 3,0 Z m 18.75,0.76923 -3,2.15384 -0.3,1.23077 -8.7,8.92308 -1.2,-0.76923 -0.6,0.61539 c 0,1.84615 -2.1,2.76923 -3,2.76923 L 0,20.76923 C 0,22.30769 1.65,24 3.14999,24 L 8.1,18.92308 C 8.1,18 8.99999,15.84615 10.8,15.84615 L 11.4,15.23076 10.65,14 l 8.7,-8.92308 1.2,-0.30769 2.1,-3.07692 z m -7.5,10.46154 -2.4,2.46154 c 1.8,1.84615 4.19999,4.30769 4.19999,5.07692 0,2.76923 0.75001,4.61538 5.55001,4.61538 l 0.3,-0.61538 -3.15,-1.84616 c 0,-1.53845 0.6,-2.76922 1.95,-3.53845 l 3.15,1.84615 0.15,-0.30769 c -0.75,-2.30769 -2.25,-3.84616 -5.25,-3.84616 -0.75,0 -2.70001,-2 -4.5,-3.84615 z" />
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_sysbar_home.xml b/packages/SystemUI/res/drawable/ic_sysbar_home.xml
index da23937..421af99 100644
--- a/packages/SystemUI/res/drawable/ic_sysbar_home.xml
+++ b/packages/SystemUI/res/drawable/ic_sysbar_home.xml
@@ -15,12 +15,15 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="28dp"
- android:height="28dp"
- android:viewportWidth="28"
- android:viewportHeight="28">
+ android:width="26dp"
+ android:height="26dp"
+ android:viewportWidth="96"
+ android:viewportHeight="96">
<path
android:fillColor="?attr/singleToneColor"
- android:pathData="M 14 7 C 17.8659932488 7 21 10.1340067512 21 14 C 21 17.8659932488 17.8659932488 21 14 21 C 10.1340067512 21 7 17.8659932488 7 14 C 7 10.1340067512 10.1340067512 7 14 7 Z" />
-</vector>
\ No newline at end of file
+ android:pathData="M48 83.6c-19.6 0 -35.6 -16 -35.6 -35.6 0 -19.6 16 -35.6 35.6 -35.6 19.6 0 35.6 16 35.6 35.6l0 0.2C83.4 67.8 67.6 83.4 48 83.6ZM77.8 48.2C77.6 32 64.8 18.8 48.4 18.2c-16.2 0 -29.6 12.8 -30.2 29 0 16.6 13.2 30 29.6 30.4 16.4 -0.2 29.6 -13.2 30 -29.4z" />
+ <path
+ android:fillColor="?attr/singleToneColor"
+ android:pathData="M72 48.2C72 61.4 61.2 72.2 47.8 72 34.4 71.8 23.8 61.2 24 47.8 24.2 34.4 34.8 24 48 24l0.2 0C61.4 24.2 72 34.8 72 48.2c0 -0.2 0 0 0 0z" />
+</vector>
diff --git a/packages/SystemUI/res/drawable/left_dialog_tri_state_down_bg.xml b/packages/SystemUI/res/drawable/left_dialog_tri_state_down_bg.xml
new file mode 100644
index 0000000..bdc35775
--- /dev/null
+++ b/packages/SystemUI/res/drawable/left_dialog_tri_state_down_bg.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 CypherOS
+ Copyright (C) 2020 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.
+-->
+<layer-list
+ xmlns:android="http://schemas.android.com/apk/res/android">
+ <item>
+ <shape>
+ <solid android:color="#ff1d1d1d" />
+ <corners
+ android:topLeftRadius="@dimen/left_tri_state_down_top_left_radius"
+ android:topRightRadius="@dimen/left_tri_state_down_top_right_radius"
+ android:bottomLeftRadius="@dimen/left_tri_state_down_bottom_left_radius"
+ android:bottomRightRadius="@dimen/left_tri_state_down_bottom_right_radius" />
+ </shape>
+ </item>
+</layer-list>
diff --git a/packages/SystemUI/res/drawable/left_dialog_tri_state_up_bg.xml b/packages/SystemUI/res/drawable/left_dialog_tri_state_up_bg.xml
new file mode 100644
index 0000000..64dd96c
--- /dev/null
+++ b/packages/SystemUI/res/drawable/left_dialog_tri_state_up_bg.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 CypherOS
+ Copyright (C) 2020 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.
+-->
+<layer-list
+ xmlns:android="http://schemas.android.com/apk/res/android">
+ <item>
+ <shape>
+ <solid android:color="#ff1d1d1d" />
+ <corners
+ android:topLeftRadius="@dimen/left_tri_state_up_top_left_radius"
+ android:topRightRadius="@dimen/left_tri_state_up_top_right_radius"
+ android:bottomLeftRadius="@dimen/left_tri_state_up_bottom_left_radius"
+ android:bottomRightRadius="@dimen/left_tri_state_up_bottom_right_radius" />
+ </shape>
+ </item>
+</layer-list>
diff --git a/packages/SystemUI/res/drawable/notification_material_bg.xml b/packages/SystemUI/res/drawable/notification_material_bg.xml
index ae45663..28788b7 100644
--- a/packages/SystemUI/res/drawable/notification_material_bg.xml
+++ b/packages/SystemUI/res/drawable/notification_material_bg.xml
@@ -22,4 +22,4 @@
<solid android:color="@color/notification_material_background_color" />
</shape>
</item>
-</ripple>
\ No newline at end of file
+</ripple>
diff --git a/packages/SystemUI/res/drawable/power_menu_item_ripple.xml b/packages/SystemUI/res/drawable/power_menu_item_ripple.xml
new file mode 100644
index 0000000..6dca9e7
--- /dev/null
+++ b/packages/SystemUI/res/drawable/power_menu_item_ripple.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+ android:color="?android:attr/colorControlHighlight">
+ <shape android:shape="oval" />
+</ripple>
diff --git a/packages/SystemUI/res/drawable/qs_navbar_scrim.xml b/packages/SystemUI/res/drawable/qs_navbar_scrim.xml
deleted file mode 100644
index bbb2617..0000000
--- a/packages/SystemUI/res/drawable/qs_navbar_scrim.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- ~ 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
- -->
-
-<shape xmlns:android="http://schemas.android.com/apk/res/android">
- <gradient
- android:type="linear"
- android:angle="90"
- android:startColor="#55000000"
- android:endColor="#00000000" />
-</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/right_dialog_tri_state_down_bg.xml b/packages/SystemUI/res/drawable/right_dialog_tri_state_down_bg.xml
new file mode 100644
index 0000000..884974d
--- /dev/null
+++ b/packages/SystemUI/res/drawable/right_dialog_tri_state_down_bg.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 CypherOS
+ Copyright (C) 2020 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.
+-->
+<layer-list
+ xmlns:android="http://schemas.android.com/apk/res/android">
+ <item>
+ <shape>
+ <solid android:color="#ff1d1d1d" />
+ <corners
+ android:topLeftRadius="@dimen/right_tri_state_down_top_left_radius"
+ android:topRightRadius="@dimen/right_tri_state_down_top_right_radius"
+ android:bottomLeftRadius="@dimen/right_tri_state_down_bottom_left_radius"
+ android:bottomRightRadius="@dimen/right_tri_state_down_bottom_right_radius" />
+ </shape>
+ </item>
+</layer-list>
diff --git a/packages/SystemUI/res/drawable/right_dialog_tri_state_up_bg.xml b/packages/SystemUI/res/drawable/right_dialog_tri_state_up_bg.xml
new file mode 100644
index 0000000..1c26d6f
--- /dev/null
+++ b/packages/SystemUI/res/drawable/right_dialog_tri_state_up_bg.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 CypherOS
+ Copyright (C) 2020 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.
+-->
+<layer-list
+ xmlns:android="http://schemas.android.com/apk/res/android">
+ <item>
+ <shape>
+ <solid android:color="#ff1d1d1d" />
+ <corners
+ android:topLeftRadius="@dimen/right_tri_state_up_top_left_radius"
+ android:topRightRadius="@dimen/right_tri_state_up_top_right_radius"
+ android:bottomLeftRadius="@dimen/right_tri_state_up_bottom_left_radius"
+ android:bottomRightRadius="@dimen/right_tri_state_up_bottom_right_radius" />
+ </shape>
+ </item>
+</layer-list>
diff --git a/packages/SystemUI/res/drawable/rounded_ripple.xml b/packages/SystemUI/res/drawable/rounded_ripple.xml
index d9ed823..24f2325 100644
--- a/packages/SystemUI/res/drawable/rounded_ripple.xml
+++ b/packages/SystemUI/res/drawable/rounded_ripple.xml
@@ -18,13 +18,13 @@
<item android:id="@android:id/mask">
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FFFFFFFF"/>
- <corners android:radius="8dp"/>
+ <corners android:radius="@dimen/corner_size"/>
</shape>
</item>
<item android:id="@android:id/background">
<shape android:shape="rectangle">
<solid android:color="?android:attr/colorBackgroundFloating"/>
- <corners android:radius="8dp"/>
+ <corners android:radius="@dimen/corner_size"/>
</shape>
</item>
-</ripple>
\ No newline at end of file
+</ripple>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_0.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_0.xml
new file mode 100644
index 0000000..4c77caf
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_0.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="18dp"
+ android:height="15dp"
+ android:viewportWidth="21.0"
+ android:viewportHeight="18.0">
+ <group
+ android:translateY="0.5"
+ android:translateX="0.5" >
+ <path
+ android:pathData="M9.57,8.5l2.79,-2.78c0.3,-0.3 0.3,-0.8 0,-1.1L9.04,1.29L9.02,1.27C8.7,0.98 8.21,1 7.91,1.31C7.78,1.45 7.71,1.64 7.71,1.84v4.79L4.69,3.61c-0.3,-0.3 -0.79,-0.3 -1.09,0s-0.3,0.79 0,1.09L7.39,8.5L3.6,12.29c-0.3,0.3 -0.3,0.79 0,1.09s0.79,0.3 1.09,0l3.01,-3.01v4.8c0,0.42 0.35,0.77 0.77,0.77c0.19,0 0.39,-0.07 0.53,-0.21l0.04,-0.04l3.32,-3.32c0.3,-0.3 0.3,-0.8 0,-1.1L9.57,8.5zM9.19,6.77v-3.2l1.6,1.6L9.19,6.77zM9.19,13.42v-3.2l1.6,1.6L9.19,13.42zM4.03,9.29c-0.44,0.44 -1.15,0.44 -1.58,0C2.02,8.86 2.02,8.16 2.45,7.72l0.01,-0.01C2.89,7.27 3.59,7.27 4.02,7.7l0.01,0.01C4.47,8.15 4.47,8.85 4.03,9.29zM14.44,7.71c0.44,0.44 0.44,1.15 0,1.58c-0.44,0.44 -1.15,0.44 -1.58,0c-0.44,-0.43 -0.44,-1.13 -0.01,-1.57l0.01,-0.01C13.3,7.28 14,7.27 14.43,7.7C14.44,7.7 14.44,7.71 14.44,7.71z"
+ android:fillColor="#FFFFFF"/>
+ <path
+ android:pathData="M15.77,1.064V15.94h3V1.064Z"
+ android:fillColor="#4DFFFFFF"/>
+ <path
+ android:pathData="M15.77,15.3V15.94h3V15.3Z"
+ android:fillColor="#FFFFFF"/>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_1.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_1.xml
new file mode 100644
index 0000000..a197711
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_1.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="18dp"
+ android:height="15dp"
+ android:viewportWidth="21.0"
+ android:viewportHeight="18.0">
+ <group
+ android:translateY="0.5"
+ android:translateX="0.5" >
+ <path
+ android:pathData="M9.57,8.5l2.79,-2.78c0.3,-0.3 0.3,-0.8 0,-1.1L9.04,1.29L9.02,1.27C8.7,0.98 8.21,1 7.91,1.31C7.78,1.45 7.71,1.64 7.71,1.84v4.79L4.69,3.61c-0.3,-0.3 -0.79,-0.3 -1.09,0s-0.3,0.79 0,1.09L7.39,8.5L3.6,12.29c-0.3,0.3 -0.3,0.79 0,1.09s0.79,0.3 1.09,0l3.01,-3.01v4.8c0,0.42 0.35,0.77 0.77,0.77c0.19,0 0.39,-0.07 0.53,-0.21l0.04,-0.04l3.32,-3.32c0.3,-0.3 0.3,-0.8 0,-1.1L9.57,8.5zM9.19,6.77v-3.2l1.6,1.6L9.19,6.77zM9.19,13.42v-3.2l1.6,1.6L9.19,13.42zM4.03,9.29c-0.44,0.44 -1.15,0.44 -1.58,0C2.02,8.86 2.02,8.16 2.45,7.72l0.01,-0.01C2.89,7.27 3.59,7.27 4.02,7.7l0.01,0.01C4.47,8.15 4.47,8.85 4.03,9.29zM14.44,7.71c0.44,0.44 0.44,1.15 0,1.58c-0.44,0.44 -1.15,0.44 -1.58,0c-0.44,-0.43 -0.44,-1.13 -0.01,-1.57l0.01,-0.01C13.3,7.28 14,7.27 14.43,7.7C14.44,7.7 14.44,7.71 14.44,7.71z"
+ android:fillColor="#FFFFFF"/>
+ <path
+ android:pathData="M15.77,1.064V15.94h3V1.064Z"
+ android:fillColor="#4DFFFFFF"/>
+ <path
+ android:pathData="M15.77,13.6V15.94h3V13.6Z"
+ android:fillColor="#FFFFFF"/>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_2.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_2.xml
new file mode 100644
index 0000000..96c4b3f
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_2.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="18dp"
+ android:height="15dp"
+ android:viewportWidth="21.0"
+ android:viewportHeight="18.0">
+ <group
+ android:translateY="0.5"
+ android:translateX="0.5" >
+ <path
+ android:pathData="M9.57,8.5l2.79,-2.78c0.3,-0.3 0.3,-0.8 0,-1.1L9.04,1.29L9.02,1.27C8.7,0.98 8.21,1 7.91,1.31C7.78,1.45 7.71,1.64 7.71,1.84v4.79L4.69,3.61c-0.3,-0.3 -0.79,-0.3 -1.09,0s-0.3,0.79 0,1.09L7.39,8.5L3.6,12.29c-0.3,0.3 -0.3,0.79 0,1.09s0.79,0.3 1.09,0l3.01,-3.01v4.8c0,0.42 0.35,0.77 0.77,0.77c0.19,0 0.39,-0.07 0.53,-0.21l0.04,-0.04l3.32,-3.32c0.3,-0.3 0.3,-0.8 0,-1.1L9.57,8.5zM9.19,6.77v-3.2l1.6,1.6L9.19,6.77zM9.19,13.42v-3.2l1.6,1.6L9.19,13.42zM4.03,9.29c-0.44,0.44 -1.15,0.44 -1.58,0C2.02,8.86 2.02,8.16 2.45,7.72l0.01,-0.01C2.89,7.27 3.59,7.27 4.02,7.7l0.01,0.01C4.47,8.15 4.47,8.85 4.03,9.29zM14.44,7.71c0.44,0.44 0.44,1.15 0,1.58c-0.44,0.44 -1.15,0.44 -1.58,0c-0.44,-0.43 -0.44,-1.13 -0.01,-1.57l0.01,-0.01C13.3,7.28 14,7.27 14.43,7.7C14.44,7.7 14.44,7.71 14.44,7.71z"
+ android:fillColor="#FFFFFF"/>
+ <path
+ android:pathData="M15.77,1.064V15.94h3V1.064Z"
+ android:fillColor="#4DFFFFFF"/>
+ <path
+ android:pathData="M15.77,11.9V15.94h3V11.9Z"
+ android:fillColor="#FFFFFF"/>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_3.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_3.xml
new file mode 100644
index 0000000..222ce62
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_3.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="18dp"
+ android:height="15dp"
+ android:viewportWidth="21.0"
+ android:viewportHeight="18.0">
+ <group
+ android:translateY="0.5"
+ android:translateX="0.5" >
+ <path
+ android:pathData="M9.57,8.5l2.79,-2.78c0.3,-0.3 0.3,-0.8 0,-1.1L9.04,1.29L9.02,1.27C8.7,0.98 8.21,1 7.91,1.31C7.78,1.45 7.71,1.64 7.71,1.84v4.79L4.69,3.61c-0.3,-0.3 -0.79,-0.3 -1.09,0s-0.3,0.79 0,1.09L7.39,8.5L3.6,12.29c-0.3,0.3 -0.3,0.79 0,1.09s0.79,0.3 1.09,0l3.01,-3.01v4.8c0,0.42 0.35,0.77 0.77,0.77c0.19,0 0.39,-0.07 0.53,-0.21l0.04,-0.04l3.32,-3.32c0.3,-0.3 0.3,-0.8 0,-1.1L9.57,8.5zM9.19,6.77v-3.2l1.6,1.6L9.19,6.77zM9.19,13.42v-3.2l1.6,1.6L9.19,13.42zM4.03,9.29c-0.44,0.44 -1.15,0.44 -1.58,0C2.02,8.86 2.02,8.16 2.45,7.72l0.01,-0.01C2.89,7.27 3.59,7.27 4.02,7.7l0.01,0.01C4.47,8.15 4.47,8.85 4.03,9.29zM14.44,7.71c0.44,0.44 0.44,1.15 0,1.58c-0.44,0.44 -1.15,0.44 -1.58,0c-0.44,-0.43 -0.44,-1.13 -0.01,-1.57l0.01,-0.01C13.3,7.28 14,7.27 14.43,7.7C14.44,7.7 14.44,7.71 14.44,7.71z"
+ android:fillColor="#FFFFFF"/>
+ <path
+ android:pathData="M15.77,1.064V15.94h3V1.064Z"
+ android:fillColor="#4DFFFFFF"/>
+ <path
+ android:pathData="M15.77,10.2V15.94h3V10.2Z"
+ android:fillColor="#FFFFFF"/>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_4.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_4.xml
new file mode 100644
index 0000000..cfc7342
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_4.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="18dp"
+ android:height="15dp"
+ android:viewportWidth="21.0"
+ android:viewportHeight="18.0">
+ <group
+ android:translateY="0.5"
+ android:translateX="0.5" >
+ <path
+ android:pathData="M9.57,8.5l2.79,-2.78c0.3,-0.3 0.3,-0.8 0,-1.1L9.04,1.29L9.02,1.27C8.7,0.98 8.21,1 7.91,1.31C7.78,1.45 7.71,1.64 7.71,1.84v4.79L4.69,3.61c-0.3,-0.3 -0.79,-0.3 -1.09,0s-0.3,0.79 0,1.09L7.39,8.5L3.6,12.29c-0.3,0.3 -0.3,0.79 0,1.09s0.79,0.3 1.09,0l3.01,-3.01v4.8c0,0.42 0.35,0.77 0.77,0.77c0.19,0 0.39,-0.07 0.53,-0.21l0.04,-0.04l3.32,-3.32c0.3,-0.3 0.3,-0.8 0,-1.1L9.57,8.5zM9.19,6.77v-3.2l1.6,1.6L9.19,6.77zM9.19,13.42v-3.2l1.6,1.6L9.19,13.42zM4.03,9.29c-0.44,0.44 -1.15,0.44 -1.58,0C2.02,8.86 2.02,8.16 2.45,7.72l0.01,-0.01C2.89,7.27 3.59,7.27 4.02,7.7l0.01,0.01C4.47,8.15 4.47,8.85 4.03,9.29zM14.44,7.71c0.44,0.44 0.44,1.15 0,1.58c-0.44,0.44 -1.15,0.44 -1.58,0c-0.44,-0.43 -0.44,-1.13 -0.01,-1.57l0.01,-0.01C13.3,7.28 14,7.27 14.43,7.7C14.44,7.7 14.44,7.71 14.44,7.71z"
+ android:fillColor="#FFFFFF"/>
+ <path
+ android:pathData="M15.77,1.064V15.94h3V1.064Z"
+ android:fillColor="#4DFFFFFF"/>
+ <path
+ android:pathData="M15.77,8.5V15.94h3V8.5Z"
+ android:fillColor="#FFFFFF"/>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_5.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_5.xml
new file mode 100644
index 0000000..5093e45
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_5.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="18dp"
+ android:height="15dp"
+ android:viewportWidth="21.0"
+ android:viewportHeight="18.0">
+ <group
+ android:translateY="0.5"
+ android:translateX="0.5" >
+ <path
+ android:pathData="M9.57,8.5l2.79,-2.78c0.3,-0.3 0.3,-0.8 0,-1.1L9.04,1.29L9.02,1.27C8.7,0.98 8.21,1 7.91,1.31C7.78,1.45 7.71,1.64 7.71,1.84v4.79L4.69,3.61c-0.3,-0.3 -0.79,-0.3 -1.09,0s-0.3,0.79 0,1.09L7.39,8.5L3.6,12.29c-0.3,0.3 -0.3,0.79 0,1.09s0.79,0.3 1.09,0l3.01,-3.01v4.8c0,0.42 0.35,0.77 0.77,0.77c0.19,0 0.39,-0.07 0.53,-0.21l0.04,-0.04l3.32,-3.32c0.3,-0.3 0.3,-0.8 0,-1.1L9.57,8.5zM9.19,6.77v-3.2l1.6,1.6L9.19,6.77zM9.19,13.42v-3.2l1.6,1.6L9.19,13.42zM4.03,9.29c-0.44,0.44 -1.15,0.44 -1.58,0C2.02,8.86 2.02,8.16 2.45,7.72l0.01,-0.01C2.89,7.27 3.59,7.27 4.02,7.7l0.01,0.01C4.47,8.15 4.47,8.85 4.03,9.29zM14.44,7.71c0.44,0.44 0.44,1.15 0,1.58c-0.44,0.44 -1.15,0.44 -1.58,0c-0.44,-0.43 -0.44,-1.13 -0.01,-1.57l0.01,-0.01C13.3,7.28 14,7.27 14.43,7.7C14.44,7.7 14.44,7.71 14.44,7.71z"
+ android:fillColor="#FFFFFF"/>
+ <path
+ android:pathData="M15.77,1.064V15.94h3V1.064Z"
+ android:fillColor="#4DFFFFFF"/>
+ <path
+ android:pathData="M15.77,6.8V15.94h3V6.8Z"
+ android:fillColor="#FFFFFF"/>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_6.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_6.xml
new file mode 100644
index 0000000..7f81e81
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_6.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="18dp"
+ android:height="15dp"
+ android:viewportWidth="21.0"
+ android:viewportHeight="18.0">
+ <group
+ android:translateY="0.5"
+ android:translateX="0.5" >
+ <path
+ android:pathData="M9.57,8.5l2.79,-2.78c0.3,-0.3 0.3,-0.8 0,-1.1L9.04,1.29L9.02,1.27C8.7,0.98 8.21,1 7.91,1.31C7.78,1.45 7.71,1.64 7.71,1.84v4.79L4.69,3.61c-0.3,-0.3 -0.79,-0.3 -1.09,0s-0.3,0.79 0,1.09L7.39,8.5L3.6,12.29c-0.3,0.3 -0.3,0.79 0,1.09s0.79,0.3 1.09,0l3.01,-3.01v4.8c0,0.42 0.35,0.77 0.77,0.77c0.19,0 0.39,-0.07 0.53,-0.21l0.04,-0.04l3.32,-3.32c0.3,-0.3 0.3,-0.8 0,-1.1L9.57,8.5zM9.19,6.77v-3.2l1.6,1.6L9.19,6.77zM9.19,13.42v-3.2l1.6,1.6L9.19,13.42zM4.03,9.29c-0.44,0.44 -1.15,0.44 -1.58,0C2.02,8.86 2.02,8.16 2.45,7.72l0.01,-0.01C2.89,7.27 3.59,7.27 4.02,7.7l0.01,0.01C4.47,8.15 4.47,8.85 4.03,9.29zM14.44,7.71c0.44,0.44 0.44,1.15 0,1.58c-0.44,0.44 -1.15,0.44 -1.58,0c-0.44,-0.43 -0.44,-1.13 -0.01,-1.57l0.01,-0.01C13.3,7.28 14,7.27 14.43,7.7C14.44,7.7 14.44,7.71 14.44,7.71z"
+ android:fillColor="#FFFFFF"/>
+ <path
+ android:pathData="M15.77,1.064V15.94h3V1.064Z"
+ android:fillColor="#4DFFFFFF"/>
+ <path
+ android:pathData="M15.77,5.1V15.94h3V5.1Z"
+ android:fillColor="#FFFFFF"/>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_7.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_7.xml
new file mode 100644
index 0000000..4808521
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_7.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="18dp"
+ android:height="15dp"
+ android:viewportWidth="21.0"
+ android:viewportHeight="18.0">
+ <group
+ android:translateY="0.5"
+ android:translateX="0.5" >
+ <path
+ android:pathData="M9.57,8.5l2.79,-2.78c0.3,-0.3 0.3,-0.8 0,-1.1L9.04,1.29L9.02,1.27C8.7,0.98 8.21,1 7.91,1.31C7.78,1.45 7.71,1.64 7.71,1.84v4.79L4.69,3.61c-0.3,-0.3 -0.79,-0.3 -1.09,0s-0.3,0.79 0,1.09L7.39,8.5L3.6,12.29c-0.3,0.3 -0.3,0.79 0,1.09s0.79,0.3 1.09,0l3.01,-3.01v4.8c0,0.42 0.35,0.77 0.77,0.77c0.19,0 0.39,-0.07 0.53,-0.21l0.04,-0.04l3.32,-3.32c0.3,-0.3 0.3,-0.8 0,-1.1L9.57,8.5zM9.19,6.77v-3.2l1.6,1.6L9.19,6.77zM9.19,13.42v-3.2l1.6,1.6L9.19,13.42zM4.03,9.29c-0.44,0.44 -1.15,0.44 -1.58,0C2.02,8.86 2.02,8.16 2.45,7.72l0.01,-0.01C2.89,7.27 3.59,7.27 4.02,7.7l0.01,0.01C4.47,8.15 4.47,8.85 4.03,9.29zM14.44,7.71c0.44,0.44 0.44,1.15 0,1.58c-0.44,0.44 -1.15,0.44 -1.58,0c-0.44,-0.43 -0.44,-1.13 -0.01,-1.57l0.01,-0.01C13.3,7.28 14,7.27 14.43,7.7C14.44,7.7 14.44,7.71 14.44,7.71z"
+ android:fillColor="#FFFFFF"/>
+ <path
+ android:pathData="M15.77,1.064V15.94h3V1.064Z"
+ android:fillColor="#4DFFFFFF"/>
+ <path
+ android:pathData="M15.77,3.4V15.94h3V3.4Z"
+ android:fillColor="#FFFFFF"/>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_8.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_8.xml
new file mode 100644
index 0000000..aef2496
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_8.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="18dp"
+ android:height="15dp"
+ android:viewportWidth="21.0"
+ android:viewportHeight="18.0">
+ <group
+ android:translateY="0.5"
+ android:translateX="0.5" >
+ <path
+ android:pathData="M9.57,8.5l2.79,-2.78c0.3,-0.3 0.3,-0.8 0,-1.1L9.04,1.29L9.02,1.27C8.7,0.98 8.21,1 7.91,1.31C7.78,1.45 7.71,1.64 7.71,1.84v4.79L4.69,3.61c-0.3,-0.3 -0.79,-0.3 -1.09,0s-0.3,0.79 0,1.09L7.39,8.5L3.6,12.29c-0.3,0.3 -0.3,0.79 0,1.09s0.79,0.3 1.09,0l3.01,-3.01v4.8c0,0.42 0.35,0.77 0.77,0.77c0.19,0 0.39,-0.07 0.53,-0.21l0.04,-0.04l3.32,-3.32c0.3,-0.3 0.3,-0.8 0,-1.1L9.57,8.5zM9.19,6.77v-3.2l1.6,1.6L9.19,6.77zM9.19,13.42v-3.2l1.6,1.6L9.19,13.42zM4.03,9.29c-0.44,0.44 -1.15,0.44 -1.58,0C2.02,8.86 2.02,8.16 2.45,7.72l0.01,-0.01C2.89,7.27 3.59,7.27 4.02,7.7l0.01,0.01C4.47,8.15 4.47,8.85 4.03,9.29zM14.44,7.71c0.44,0.44 0.44,1.15 0,1.58c-0.44,0.44 -1.15,0.44 -1.58,0c-0.44,-0.43 -0.44,-1.13 -0.01,-1.57l0.01,-0.01C13.3,7.28 14,7.27 14.43,7.7C14.44,7.7 14.44,7.71 14.44,7.71z"
+ android:fillColor="#FFFFFF"/>
+ <path
+ android:pathData="M15.77,1.064V15.94h3V1.064Z"
+ android:fillColor="#4DFFFFFF"/>
+ <path
+ android:pathData="M15.77,1.7V15.94h3V1.7Z"
+ android:fillColor="#FFFFFF"/>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_9.xml b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_9.xml
new file mode 100644
index 0000000..7af909a
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_9.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="18dp"
+ android:height="15dp"
+ android:viewportWidth="21.0"
+ android:viewportHeight="18.0">
+ <group
+ android:translateY="0.5"
+ android:translateX="0.5" >
+ <path
+ android:pathData="M9.57,8.5l2.79,-2.78c0.3,-0.3 0.3,-0.8 0,-1.1L9.04,1.29L9.02,1.27C8.7,0.98 8.21,1 7.91,1.31C7.78,1.45 7.71,1.64 7.71,1.84v4.79L4.69,3.61c-0.3,-0.3 -0.79,-0.3 -1.09,0s-0.3,0.79 0,1.09L7.39,8.5L3.6,12.29c-0.3,0.3 -0.3,0.79 0,1.09s0.79,0.3 1.09,0l3.01,-3.01v4.8c0,0.42 0.35,0.77 0.77,0.77c0.19,0 0.39,-0.07 0.53,-0.21l0.04,-0.04l3.32,-3.32c0.3,-0.3 0.3,-0.8 0,-1.1L9.57,8.5zM9.19,6.77v-3.2l1.6,1.6L9.19,6.77zM9.19,13.42v-3.2l1.6,1.6L9.19,13.42zM4.03,9.29c-0.44,0.44 -1.15,0.44 -1.58,0C2.02,8.86 2.02,8.16 2.45,7.72l0.01,-0.01C2.89,7.27 3.59,7.27 4.02,7.7l0.01,0.01C4.47,8.15 4.47,8.85 4.03,9.29zM14.44,7.71c0.44,0.44 0.44,1.15 0,1.58c-0.44,0.44 -1.15,0.44 -1.58,0c-0.44,-0.43 -0.44,-1.13 -0.01,-1.57l0.01,-0.01C13.3,7.28 14,7.27 14.43,7.7C14.44,7.7 14.44,7.71 14.44,7.71z"
+ android:fillColor="#FFFFFF"/>
+ <path
+ android:pathData="M15.77,1.064V15.94h3V1.064Z"
+ android:fillColor="#FFFFFF"/>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_network_traffic.xml b/packages/SystemUI/res/drawable/stat_sys_network_traffic.xml
new file mode 100644
index 0000000..000fecb
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_network_traffic.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 ion-OS
+
+ 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="5dp"
+ android:height="17dp"
+ android:viewportWidth="7.1"
+ android:viewportHeight="24.0">
+
+ <path
+ android:fillColor="#4DFFFFFF"
+ android:pathData="M3.6000004,10.8l3.5,0.0 -3.5,-7.3 0.0,0.0 0.0,0.0 0.0,0.0 0.0,0.0 -3.6,7.3z"/>
+ <path
+ android:fillColor="#4DFFFFFF"
+ android:pathData="M3.6000004,13.2l-3.6,0.0 3.6,7.3 0.0,0.0 0.0,0.0 0.0,0.0 0.0,0.0 3.5,-7.3z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/stat_sys_network_traffic_down.xml b/packages/SystemUI/res/drawable/stat_sys_network_traffic_down.xml
new file mode 100644
index 0000000..6088a29
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_network_traffic_down.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2017 The Android Open Source Project
+ Copyright (C) 2017 ABC rom
+ 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="5dp"
+ android:height="17.0dp"
+ android:viewportWidth="7.1"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#4dffffff"
+ android:pathData="M3.6000004,10.8l3.5,0.0 -3.5,-7.3 0.0,0.0 0.0,0.0 0.0,0.0 0.0,0.0 -3.6,7.3z"/>
+ <path
+ android:fillColor="#ffffffff"
+ android:pathData="M3.6000004,13.2l-3.6,0.0 3.6,7.3 0.0,0.0 0.0,0.0 0.0,0.0 0.0,0.0 3.5,-7.3z"/>
+</vector>
+
diff --git a/packages/SystemUI/res/drawable/stat_sys_network_traffic_up.xml b/packages/SystemUI/res/drawable/stat_sys_network_traffic_up.xml
new file mode 100644
index 0000000..3052ab4
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_network_traffic_up.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2017 The Android Open Source Project
+ Copyright (C) 2017 ABC rom
+ 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="5dp"
+ android:height="17.0dp"
+ android:viewportWidth="7.1"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#ffffffff"
+ android:pathData="M3.6000004,10.8l3.5,0.0 -3.5,-7.3 0.0,0.0 0.0,0.0 0.0,0.0 0.0,0.0 -3.6,7.3z"/>
+ <path
+ android:fillColor="#4dffffff"
+ android:pathData="M3.6000004,13.2l-3.6,0.0 3.6,7.3 0.0,0.0 0.0,0.0 0.0,0.0 0.0,0.0 3.5,-7.3z"/>
+</vector>
+
diff --git a/packages/SystemUI/res/drawable/stat_sys_network_traffic_updown.xml b/packages/SystemUI/res/drawable/stat_sys_network_traffic_updown.xml
new file mode 100644
index 0000000..3d0bf61
--- /dev/null
+++ b/packages/SystemUI/res/drawable/stat_sys_network_traffic_updown.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2017 The Android Open Source Project
+ Copyright (C) 2017 ABC rom
+ 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="5dp"
+ android:height="17.0dp"
+ android:viewportWidth="7.1"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#ffffffff"
+ android:pathData="M3.6000004,10.8l3.5,0.0 -3.5,-7.3 0.0,0.0 0.0,0.0 0.0,0.0 0.0,0.0 -3.6,7.3z"/>
+ <path
+ android:fillColor="#ffffffff"
+ android:pathData="M3.6000004,13.2l-3.6,0.0 3.6,7.3 0.0,0.0 0.0,0.0 0.0,0.0 0.0,0.0 3.5,-7.3z"/>
+</vector>
+
diff --git a/packages/SystemUI/res/drawable/status_bar_logo.xml b/packages/SystemUI/res/drawable/status_bar_logo.xml
new file mode 100644
index 0000000..d23eaf9
--- /dev/null
+++ b/packages/SystemUI/res/drawable/status_bar_logo.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:viewportWidth="128"
+ android:viewportHeight="128"
+ android:width="24dp"
+ android:height="24dp">
+ <group
+ android:scaleX="0.017"
+ android:scaleY="0.017"
+ android:translateX="24"
+ android:translateY="24">
+ <path
+ android:pathData="M3241.7 3992.9c50.5 -70.5 96.4 -135.9 143.5 -200.4 261.1 -357 545.5 -693.6 871.2 -993.8 278.8 -257 581.1 -480.6 921.9 -649.9 277.6 -137.8 570.1 -227.2 876.1 -273.8 41.3 -6.3 82.6 -12.9 123.5 -19.3 1.1 2.8 2.3 4.3 2 5.1 -82.8 173.1 -164.9 346.6 -248.9 519.1 -164.4 337.5 -362.1 654.2 -603.5 942.3 -75.5 90.1 -170.9 158.4 -270.4 220 -216.9 134.3 -453.7 220.5 -698.7 286.1 -301.5 80.8 -608.8 128.2 -919.7 152.8 -56.5 4.5 -113 7.9 -169.5 11.7 -7 0.5 -14.1 0.1 -27.5 0.1z"
+ android:fillColor="#FFFFFF" />
+ <path
+ android:pathData="M3043.3 3994.8c-58.6 -3.8 -110.9 -6.7 -163.3 -10.7 -306.9 -23.5 -610.6 -67.8 -909.1 -144.4 -240.4 -61.6 -473 -143.3 -690.1 -266 -175.9 -99.4 -318 -233.5 -439 -395.4C605.4 2862 414 2520.7 251.3 2162.1 205.3 2060.8 156.8 1960.7 108.4 1858c3.3 0 8.4 -0.5 13.3 0.1 598.7 71.4 1126.5 309.3 1599.1 678.5 351.3 274.5 659.1 592.3 936.2 940 129.1 162 249.1 331.3 373.1 497.3 3.7 4.6 6.4 9.8 13.2 20.9z"
+ android:fillColor="#FFFFFF" />
+ <path
+ android:pathData="M3102.5 3929c-9.8 -8.2 -19 -13.5 -24.9 -21.3 -123.5 -163.7 -245.2 -328.9 -370.5 -491.2 -58.3 -75.5 -121.6 -147.5 -186.3 -217.8 -111.7 -121.3 -224.7 -241.4 -340.1 -359.2 -64.6 -65.9 -135.3 -125.7 -202.6 -189.1 -8.6 -8.1 -15.4 -20.2 -18.7 -31.7 -98 -347.9 -126.5 -703.4 -114.2 -1063.1 7.6 -224.2 31.2 -446.6 74.4 -666.9 1.8 -9.1 3.8 -18.1 6.6 -30.9 9.4 6.6 17.1 11 23.7 16.6 167.7 141.5 309.5 306.5 436 484.9 300.2 423.1 493.3 892.9 606.4 1397.3 84.8 377.7 118.8 760.6 115.5 1147.2 0 4.7 -0.2 9.3 -0.7 14 -0.2 1.7 -1.4 3.4 -4.6 11.2z"
+ android:fillColor="#FFFFFF" />
+ <path
+ android:pathData="M3180.9 3931.6c-1.2 -14.2 -2 -19.4 -2 -24.7 -5 -457.7 43.5 -909 164.8 -1351.2 126.8 -462.3 324.1 -891.1 614.2 -1274.8 113.3 -149.8 237.7 -289.4 382.6 -409.8 4.1 -3.4 8.4 -6.5 12.8 -9.5 1 -0.7 2.5 -0.4 6.5 -0.9 1.8 7.1 4 14.4 5.4 21.9 67 346.6 91.3 696.1 72.1 1048.6 -12.6 230.3 -45.6 457.5 -108.8 679.6 -5.4 19.1 -19.1 37.7 -33.5 51.9 -32 31.7 -68 59.5 -100.5 90.8 -74.3 71.7 -150 142.2 -220.5 217.5 -103.9 111 -208.4 222 -304.5 339.6 -139.9 171 -272.7 347.8 -408.2 522.4 -18.3 23.6 -34 49.2 -51.9 73.1 -6.1 8.3 -15.4 14.1 -28.5 25.5z"
+ android:fillColor="#FFFFFF" />
+ <path
+ android:pathData="M3157.2 268c81.3 90 146.2 189 203.1 293.4 148 271.4 233.8 562.8 276.7 867.7 7.1 50.8 12.4 101.9 17.5 152.9 0.9 8.6 -1.2 18.8 -5.4 26.3 -76.7 135.7 -147.9 274.1 -204.3 419.6 -43 111 -86.1 222.1 -123.1 335.1 -55.9 171 -99.6 345.5 -129.3 523.1 -17 101.8 -31 204.1 -46.4 306.1 -0.2 1 -1.6 1.9 -4.1 4.6 -6 -42.9 -10.7 -84.3 -17.8 -125.4 -18.5 -107.6 -35.8 -215.5 -57.7 -322.4 -35.3 -172.6 -81.6 -342.6 -143.1 -507.6 -47.3 -127 -101.4 -251.5 -154.1 -376.3 -19.1 -45.3 -43.5 -88.3 -64.9 -132.7 -3 -6.2 -4.1 -14.2 -3.7 -21.2 21.6 -370.3 93.1 -729.4 242.5 -1070.7 54.7 -124.9 118.6 -244.7 200 -354.5 4.4 -5.8 9 -11.3 14.1 -18z"
+ android:fillColor="#FFFFFF" />
+ <path
+ android:pathData="M1859.3 2548.6c-56.8 -43.9 -109.7 -86.1 -163.8 -126.5 -135.5 -101.2 -276.1 -194.6 -425 -274.9 -56.2 -30.3 -113.8 -57.9 -170.2 -87.9 -9.7 -5.2 -19.5 -14.5 -24.1 -24.3C945 1756.7 855.4 1466.5 830.6 1158.5c-4.4 -54 -0.6 -108.7 -0.6 -165.7 9 2.8 19 5.1 28.4 8.8 155.7 61 296.2 148.8 430.3 247.2 171.9 126.2 327.6 270.6 472.7 426.6 8 8.6 13.4 23 13.9 34.9 1.6 44.6 -1.5 89.4 1.1 133.9 6.2 109.8 9.9 220.1 23.3 329.1 14.8 120 39.4 238.7 59.6 358 0.6 4.4 0 9.1 0 17.3z"
+ android:fillColor="#FFFFFF" />
+ <path
+ android:pathData="M5455.7 992c0.5 11 1.2 19.4 1.3 27.9 1.2 235.2 -43.9 462.8 -119.1 684.2 -37.9 111.5 -85.8 219.5 -130.9 328.5 -5.4 13 -19.1 25.8 -32.2 32 -181.4 86.3 -352.3 190.2 -514.9 307.7 -78.5 56.7 -155.1 116.1 -235.7 176.6 6.2 -30 13.1 -58.3 17.8 -86.9 15.6 -95.3 32.8 -190.5 44.7 -286.4 10.1 -81.4 15.5 -163.4 19.6 -245.4 3.8 -75.7 2.8 -151.6 4.8 -227.4 0.2 -9.1 3.2 -20.4 9.1 -26.8 198 -211.6 412.2 -404.4 662.6 -552.7 81.6 -48.3 170.1 -85.2 255.5 -127.1 4.2 -1.9 9 -2.2 17.4 -4.2z"
+ android:fillColor="#FFFFFF" />
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/layout/battery_percentage_view.xml b/packages/SystemUI/res/layout/battery_percentage_view.xml
index b9b1bb1..75024ad 100644
--- a/packages/SystemUI/res/layout/battery_percentage_view.xml
+++ b/packages/SystemUI/res/layout/battery_percentage_view.xml
@@ -25,6 +25,5 @@
android:textAppearance="@style/TextAppearance.StatusBar.Clock"
android:textColor="?android:attr/textColorPrimary"
android:gravity="center_vertical|start"
- android:paddingStart="@dimen/battery_level_padding_start"
android:importantForAccessibility="no"
/>
diff --git a/packages/SystemUI/res/layout/controls_more_item.xml b/packages/SystemUI/res/layout/controls_more_item.xml
index da9c43c..d5d1d7d 100644
--- a/packages/SystemUI/res/layout/controls_more_item.xml
+++ b/packages/SystemUI/res/layout/controls_more_item.xml
@@ -19,6 +19,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start"
+ android:textColor="?android:attr/textColorPrimary"
android:paddingStart="@dimen/control_menu_horizontal_padding"
android:paddingEnd="@dimen/control_menu_horizontal_padding"
android:textDirection="locale"/>
diff --git a/packages/SystemUI/res/layout/global_actions_grid_item_v2.xml b/packages/SystemUI/res/layout/global_actions_grid_item_v2.xml
index 99b9ced..e795c7a 100644
--- a/packages/SystemUI/res/layout/global_actions_grid_item_v2.xml
+++ b/packages/SystemUI/res/layout/global_actions_grid_item_v2.xml
@@ -28,14 +28,14 @@
android:layout_marginRight="@dimen/control_base_item_margin"
android:layout_marginLeft="@dimen/control_base_item_margin"
android:stateListAnimator="@anim/control_state_list_animator"
- android:background="@drawable/control_background">
+ android:background="@drawable/control_background_ripple">
<ImageView
android:id="@*android:id/icon"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginBottom="14dp"
android:scaleType="centerInside"
- android:tint="@color/control_primary_text" />
+ android:tint="?android:attr/textColorPrimary" />
<TextView
android:id="@*android:id/message"
android:layout_width="match_parent"
@@ -45,7 +45,7 @@
android:maxLines="2"
android:textSize="12sp"
android:gravity="center"
- android:textColor="@color/control_primary_text"
+ android:textColor="?android:attr/textColorPrimary"
android:breakStrategy="high_quality"
android:hyphenationFrequency="full"
android:textAppearance="?android:attr/textAppearanceSmall" />
diff --git a/packages/SystemUI/res/layout/global_actions_item.xml b/packages/SystemUI/res/layout/global_actions_item.xml
index 66a4b73..f055627 100644
--- a/packages/SystemUI/res/layout/global_actions_item.xml
+++ b/packages/SystemUI/res/layout/global_actions_item.xml
@@ -21,6 +21,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
+ android:background="@drawable/power_menu_item_ripple"
android:minWidth="92dp"
android:minHeight="92dp"
android:gravity="center"
diff --git a/packages/SystemUI/res/layout/global_actions_power_item.xml b/packages/SystemUI/res/layout/global_actions_power_item.xml
index 3bf5894..e88a750 100644
--- a/packages/SystemUI/res/layout/global_actions_power_item.xml
+++ b/packages/SystemUI/res/layout/global_actions_power_item.xml
@@ -24,22 +24,22 @@
android:stateListAnimator="@anim/control_state_list_animator">
<ImageView
android:id="@*android:id/icon"
- android:layout_width="24dp"
- android:layout_height="24dp"
+ android:layout_width="28dp"
+ android:layout_height="28dp"
android:layout_marginBottom="@dimen/global_actions_power_dialog_item_bottom_margin"
android:scaleType="centerInside"
- android:tint="@color/control_primary_text" />
+ android:tint="?android:attr/textColorPrimary" />
<TextView
android:id="@*android:id/message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:marqueeRepeatLimit="marquee_forever"
android:ellipsize="marquee"
- android:layout_marginBottom="16dp"
+ android:layout_marginBottom="14dp"
android:maxLines="1"
- android:textSize="16sp"
+ android:textSize="14sp"
android:gravity="center"
- android:textColor="@color/control_primary_text"
+ android:textColor="?android:attr/textColorPrimary"
android:textAppearance="?android:attr/textAppearanceSmall" />
</com.android.systemui.globalactions.GlobalActionsItem>
diff --git a/packages/SystemUI/res/layout/hybrid_conversation_notification.xml b/packages/SystemUI/res/layout/hybrid_conversation_notification.xml
index 214c44a..302812a 100644
--- a/packages/SystemUI/res/layout/hybrid_conversation_notification.xml
+++ b/packages/SystemUI/res/layout/hybrid_conversation_notification.xml
@@ -25,14 +25,16 @@
android:paddingEnd="12dp">
<FrameLayout
- android:layout_width="@*android:dimen/conversation_content_start"
+ android:layout_width="wrap_content"
+ android:paddingStart="14dp"
+ android:paddingEnd="8dp"
android:layout_height="25dp"
>
<ImageView
android:id="@*android:id/conversation_icon"
android:layout_width="20dp"
android:layout_height="20dp"
- android:layout_gravity="center"
+ android:layout_gravity="start|center_vertical"
/>
<ViewStub
@@ -40,7 +42,7 @@
android:layout="@*android:layout/conversation_face_pile_layout"
android:layout_width="25dp"
android:layout_height="25dp"
- android:layout_gravity="center"
+ android:layout_gravity="start|center_vertical"
/>
</FrameLayout>
diff --git a/packages/SystemUI/res/layout/keyguard_status_bar.xml b/packages/SystemUI/res/layout/keyguard_status_bar.xml
index 416ee81..0ba9d95 100644
--- a/packages/SystemUI/res/layout/keyguard_status_bar.xml
+++ b/packages/SystemUI/res/layout/keyguard_status_bar.xml
@@ -63,7 +63,7 @@
android:gravity="center"
android:visibility="gone" />
- <com.android.keyguard.CarrierText
+ <com.android.systemui.bliss.carrierlabel.CarrierLabel
android:id="@+id/keyguard_carrier_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -72,6 +72,7 @@
android:layout_toStartOf="@id/system_icons_container"
android:gravity="center_vertical"
android:ellipsize="marquee"
+ android:marqueeRepeatLimit="marquee_forever"
android:textDirection="locale"
android:textAppearance="@style/TextAppearance.StatusBar.Clock"
android:textColor="?attr/wallpaperTextColorSecondary"
diff --git a/packages/SystemUI/res/layout/notification_info.xml b/packages/SystemUI/res/layout/notification_info.xml
index 1c7c226..091ba13 100644
--- a/packages/SystemUI/res/layout/notification_info.xml
+++ b/packages/SystemUI/res/layout/notification_info.xml
@@ -92,6 +92,17 @@
<!-- Optional link to app. Only appears if the channel is not disabled and the app
asked for it -->
<ImageButton
+ android:id="@+id/force_stop"
+ android:layout_width="@dimen/notification_importance_toggle_size"
+ android:layout_height="@dimen/notification_importance_toggle_size"
+ android:layout_centerVertical="true"
+ android:background="@drawable/ripple_drawable"
+ android:contentDescription="@string/notification_app_settings"
+ android:src="@drawable/ic_force_stop"
+ android:layout_toStartOf="@id/app_settings"
+ android:tint="@color/notification_guts_link_icon_tint"/>
+
+ <ImageButton
android:id="@+id/app_settings"
android:layout_width="@dimen/notification_importance_toggle_size"
android:layout_height="@dimen/notification_importance_toggle_size"
diff --git a/packages/SystemUI/res/layout/qs_detail.xml b/packages/SystemUI/res/layout/qs_detail.xml
index 59e1a75..705a997 100644
--- a/packages/SystemUI/res/layout/qs_detail.xml
+++ b/packages/SystemUI/res/layout/qs_detail.xml
@@ -40,7 +40,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:alpha="0"
- android:background="@color/qs_detail_progress_track"
android:src="@drawable/indeterminate_anim"
android:scaleType="fitXY"
/>
diff --git a/packages/SystemUI/res/layout/qs_footer_impl.xml b/packages/SystemUI/res/layout/qs_footer_impl.xml
index 436188a..b970e23 100644
--- a/packages/SystemUI/res/layout/qs_footer_impl.xml
+++ b/packages/SystemUI/res/layout/qs_footer_impl.xml
@@ -97,6 +97,20 @@
android:scaleType="centerInside"/>
</com.android.systemui.statusbar.phone.MultiUserSwitch>
+ <com.android.systemui.statusbar.AlphaOptimizedImageView
+ android:id="@+id/running_services_button"
+ style="@android:style/Widget.Material.Button.Borderless"
+ android:layout_width="@dimen/qs_footer_action_button_size"
+ android:layout_height="@dimen/qs_footer_action_button_size"
+ android:padding="@dimen/qs_footer_icon_padding"
+ android:clickable="true"
+ android:clipToPadding="false"
+ android:focusable="true"
+ android:background="?android:attr/selectableItemBackgroundBorderless"
+ android:src="@drawable/ic_settings_memory"
+ android:tint="?android:attr/colorForeground"
+ android:contentDescription="@string/accessibility_quick_settings_running_services" />
+
<com.android.systemui.statusbar.AlphaOptimizedFrameLayout
android:id="@+id/settings_button_container"
android:layout_width="@dimen/qs_footer_action_button_size"
@@ -117,16 +131,6 @@
android:scaleType="centerInside"
android:tint="?android:attr/colorForeground"/>
- <com.android.systemui.statusbar.AlphaOptimizedImageView
- android:id="@+id/tuner_icon"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:paddingStart="36dp"
- android:paddingEnd="4dp"
- android:src="@drawable/tuner"
- android:tint="?android:attr/textColorTertiary"
- android:visibility="invisible"/>
-
</com.android.systemui.statusbar.AlphaOptimizedFrameLayout>
</com.android.keyguard.AlphaOptimizedLinearLayout>
</LinearLayout>
diff --git a/packages/SystemUI/res/layout/qs_panel.xml b/packages/SystemUI/res/layout/qs_panel.xml
index 4527c6c..c9611ce 100644
--- a/packages/SystemUI/res/layout/qs_panel.xml
+++ b/packages/SystemUI/res/layout/qs_panel.xml
@@ -29,25 +29,6 @@
android:elevation="4dp"
android:background="@drawable/qs_background_primary" />
- <!-- Black part behind the status bar -->
- <View
- android:id="@+id/quick_settings_status_bar_background"
- android:layout_width="match_parent"
- android:layout_height="@*android:dimen/quick_qs_offset_height"
- android:clipToPadding="false"
- android:clipChildren="false"
- android:background="#ff000000" />
-
- <!-- Gradient view behind QS -->
- <View
- android:id="@+id/quick_settings_gradient_view"
- android:layout_width="match_parent"
- android:layout_height="126dp"
- android:layout_marginTop="@*android:dimen/quick_qs_offset_height"
- android:clipToPadding="false"
- android:clipChildren="false"
- android:background="@drawable/qs_bg_gradient" />
-
<com.android.systemui.qs.NonInterceptingScrollView
android:id="@+id/expanded_qs_scroll_view"
android:layout_width="match_parent"
@@ -75,18 +56,4 @@
<include android:id="@+id/qs_customize" layout="@layout/qs_customize_panel"
android:visibility="gone" />
- <FrameLayout
- android:id="@+id/qs_drag_handle_view"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:elevation="4dp"
- android:paddingBottom="5dp">
- <View
- android:layout_width="46dp"
- android:layout_height="3dp"
- android:background="@drawable/qs_footer_drag_handle" />
- </FrameLayout>
-
-
</com.android.systemui.qs.QSContainerImpl>
diff --git a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
index 12127f5..701e825 100644
--- a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
+++ b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
@@ -30,4 +30,14 @@
android:importantForAccessibility="no"
systemui:text="@string/status_bar_settings_auto_brightness_label" />
+ <ImageButton
+ android:id="@+id/brightness_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="48dp"
+ android:layout_gravity="center_vertical"
+ android:padding="@dimen/qs_footer_icon_padding"
+ android:scaleType="centerInside"
+ android:background="?android:attr/selectableItemBackgroundBorderless"
+ android:src="@drawable/ic_qs_brightness_auto_off"
+ android:contentDescription="@null"/>
</LinearLayout>
diff --git a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
index dc341274..dfd9149b 100644
--- a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
@@ -22,6 +22,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="@integer/notification_panel_layout_gravity"
+ android:layout_marginStart="@dimen/qs_items_padding"
+ android:layout_marginEnd="@dimen/qs_items_padding"
android:background="@android:color/transparent"
android:baselineAligned="false"
android:clickable="false"
@@ -46,6 +48,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/quick_qs_status_icons"
+ android:paddingLeft="@dimen/qs_items_padding"
+ android:paddingRight="@dimen/qs_items_padding"
android:accessibilityTraversalAfter="@+id/date_time_group"
android:accessibilityTraversalBefore="@id/expand_indicator"
android:clipChildren="false"
diff --git a/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml b/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml
index 3c74801..c87bc3f8 100644
--- a/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml
+++ b/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml
@@ -47,6 +47,17 @@
systemui:showDark="false" />
</LinearLayout>
+ <com.android.systemui.statusbar.policy.NetworkTraffic
+ android:id="@+id/networkTraffic"
+ android:paddingEnd="@dimen/status_bar_left_clock_end_padding"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_marginStart="2dp"
+ android:layout_marginEnd="2dp"
+ android:singleLine="false"
+ android:lineSpacingMultiplier="1.2"
+ systemui:showDark="false"/>
+
<android.widget.Space
android:id="@+id/space"
android:layout_width="0dp"
diff --git a/packages/SystemUI/res/layout/screen_pinning_request_buttons.xml b/packages/SystemUI/res/layout/screen_pinning_request_buttons.xml
index f13f019..125a0d8 100644
--- a/packages/SystemUI/res/layout/screen_pinning_request_buttons.xml
+++ b/packages/SystemUI/res/layout/screen_pinning_request_buttons.xml
@@ -149,6 +149,7 @@
android:src="@drawable/screen_pinning_bg_circ" />
<ImageView
+ android:id="@+id/screen_pinning_recents_icon"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingEnd="@dimen/screen_pinning_request_nav_side_padding"
diff --git a/packages/SystemUI/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml
index f8db97d..a170a62 100644
--- a/packages/SystemUI/res/layout/status_bar.xml
+++ b/packages/SystemUI/res/layout/status_bar.xml
@@ -49,6 +49,7 @@
android:paddingTop="@dimen/status_bar_padding_top"
android:orientation="horizontal"
>
+
<FrameLayout
android:layout_height="match_parent"
android:layout_width="0dp"
@@ -63,6 +64,7 @@
android:id="@+id/status_bar_left_side"
android:layout_height="match_parent"
android:layout_width="match_parent"
+ android:orientation="horizontal"
android:clipChildren="false"
>
<ViewStub
@@ -71,17 +73,48 @@
android:layout_height="match_parent"
android:layout="@layout/operator_name" />
+ <ImageView
+ android:id="@+id/status_bar_logo"
+ android:layout_width="@dimen/status_bar_icon_size"
+ android:layout_height="@dimen/status_bar_icon_size"
+ android:src="@drawable/status_bar_logo"
+ android:scaleType="centerInside"
+ android:paddingEnd="@dimen/status_bar_left_clock_end_padding"
+ android:layout_gravity="center_vertical"
+ android:gravity="center_vertical"
+ android:visibility="gone" />
+
<com.android.systemui.statusbar.policy.Clock
android:id="@+id/clock"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textAppearance="@style/TextAppearance.StatusBar.Clock"
android:singleLine="true"
+ android:visibility="gone"
android:paddingStart="@dimen/status_bar_left_clock_starting_padding"
android:paddingEnd="@dimen/status_bar_left_clock_end_padding"
android:gravity="center_vertical|start"
/>
+ <com.android.keyguard.AlphaOptimizedLinearLayout
+ android:id="@+id/left_icon_area"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:orientation="horizontal" >
+
+ <com.android.systemui.bliss.carrierlabel.CarrierLabel
+ android:id="@+id/statusbar_carrier_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:gravity="start|center_vertical"
+ android:paddingStart="3dp"
+ android:paddingEnd="3dp"
+ android:textAppearance="@style/TextAppearance.StatusBar.Clock"
+ android:visibility="gone"
+ android:singleLine="true"/>
+ </com.android.keyguard.AlphaOptimizedLinearLayout>
+
<com.android.systemui.statusbar.AlphaOptimizedFrameLayout
android:id="@+id/notification_icon_area"
android:layout_width="0dp"
@@ -116,11 +149,41 @@
android:orientation="horizontal"
android:gravity="center_vertical|end"
>
-
<include layout="@layout/system_icons" />
+
</com.android.keyguard.AlphaOptimizedLinearLayout>
+
+ <com.android.systemui.statusbar.policy.ClockRight
+ android:id="@+id/right_clock"
+ android:textAppearance="@style/TextAppearance.StatusBar.Clock"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:singleLine="true"
+ android:visibility="gone"
+ android:paddingStart="@dimen/status_bar_clock_starting_padding"
+ android:paddingEnd="@dimen/status_bar_clock_end_padding"
+ android:gravity="center_vertical|start"
+ />
</LinearLayout>
+ <com.android.keyguard.AlphaOptimizedLinearLayout
+ android:id="@+id/center_clock_layout"
+ android:gravity="center"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ >
+ <com.android.systemui.statusbar.policy.ClockCenter
+ android:id="@+id/center_clock"
+ android:textAppearance="@style/TextAppearance.StatusBar.Clock"
+ android:gravity="center"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:visibility="gone"
+ android:singleLine="true"
+ />
+ </com.android.keyguard.AlphaOptimizedLinearLayout>
+
<ViewStub
android:id="@+id/emergency_cryptkeeper_text"
android:layout_width="wrap_content"
@@ -128,4 +191,9 @@
android:layout="@layout/emergency_cryptkeeper_text"
/>
+ <com.android.systemui.bliss.batterybar.BatteryBarController
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ systemui:viewLocation="1" />
+
</com.android.systemui.statusbar.phone.PhoneStatusBarView>
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index 1d4b982..75f76b4 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -92,13 +92,5 @@
layout="@layout/keyguard_bottom_area"
android:visibility="gone" />
- <com.android.systemui.statusbar.AlphaOptimizedView
- android:id="@+id/qs_navbar_scrim"
- android:layout_height="96dp"
- android:layout_width="match_parent"
- android:layout_gravity="bottom"
- android:visibility="invisible"
- android:background="@drawable/qs_navbar_scrim" />
-
<include layout="@layout/status_bar_expanded_plugin_frame"/>
</com.android.systemui.statusbar.phone.NotificationPanelView>
diff --git a/packages/SystemUI/res/layout/status_bar_toggle_slider.xml b/packages/SystemUI/res/layout/status_bar_toggle_slider.xml
index 942f3dd..f647cee 100644
--- a/packages/SystemUI/res/layout/status_bar_toggle_slider.xml
+++ b/packages/SystemUI/res/layout/status_bar_toggle_slider.xml
@@ -37,7 +37,7 @@
android:layout_alignParentStart="true"
android:layout_alignParentEnd="true"
android:paddingStart="20dp"
- android:paddingEnd="20dp"
+ android:paddingEnd="12dp"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:thumb="@drawable/ic_brightness_thumb"
diff --git a/packages/SystemUI/res/layout/super_notification_shade.xml b/packages/SystemUI/res/layout/super_notification_shade.xml
index d322e09..7314d04 100644
--- a/packages/SystemUI/res/layout/super_notification_shade.xml
+++ b/packages/SystemUI/res/layout/super_notification_shade.xml
@@ -66,6 +66,15 @@
sysui:ignoreRightInset="true"
/>
+ <com.android.systemui.statusbar.VisualizerView
+ android:id="@+id/visualizerview"
+ android:gravity="bottom"
+ android:layout_gravity="bottom"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="visible"
+ sysui:ignoreRightInset="true" />
+
<LinearLayout
android:id="@+id/lock_icon_container"
android:orientation="vertical"
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 0000000..8f08806
--- /dev/null
+++ b/packages/SystemUI/res/layout/tri_state_dialog.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 CypherOS
+ Copyright (C) 2020 crDroid Android 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.
+-->
+<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"
+ android:theme="@style/qs_theme">
+
+ <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"
+ android:tint="@color/accent_tint_color_selector" />
+ </FrameLayout>
+
+ <TextView
+ android:gravity="center_vertical"
+ android:id="@+id/tri_state_text"
+ android:layout_width="wrap_content"
+ android:layout_height="fill_parent"
+ android:textSize="14.0sp"
+ android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
+ android:textColor="?android:attr/textColorPrimary" />
+
+ <FrameLayout
+ android:layout_width="18.0dip"
+ android:layout_height="fill_parent" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml
index 7d6547b..d009e27 100644
--- a/packages/SystemUI/res/layout/volume_dialog.xml
+++ b/packages/SystemUI/res/layout/volume_dialog.xml
@@ -30,8 +30,6 @@
android:minWidth="@dimen/volume_dialog_panel_width"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:gravity="right"
- android:layout_gravity="right"
android:background="@android:color/transparent"
android:paddingRight="@dimen/volume_dialog_panel_transparent_padding_right"
android:paddingTop="@dimen/volume_dialog_panel_transparent_padding"
@@ -45,8 +43,6 @@
android:layout_width="@dimen/volume_dialog_ringer_size"
android:layout_height="@dimen/volume_dialog_ringer_size"
android:layout_marginBottom="@dimen/volume_dialog_spacer"
- android:gravity="right"
- android:layout_gravity="right"
android:translationZ="@dimen/volume_dialog_elevation"
android:clipToPadding="false"
android:background="@drawable/rounded_bg_full">
@@ -65,7 +61,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>
@@ -141,8 +136,7 @@
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"
android:layout_marginBottom="@dimen/volume_tool_tip_bottom_margin"/>
-</FrameLayout>
\ No newline at end of file
+</FrameLayout>
diff --git a/packages/SystemUI/res/menu/qs_customize_menu.xml b/packages/SystemUI/res/menu/qs_customize_menu.xml
new file mode 100644
index 0000000..5ff191a
--- /dev/null
+++ b/packages/SystemUI/res/menu/qs_customize_menu.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/menu_item_columns"
+ android:title="@string/qs_menu_item_columns">
+ <menu>
+ <item android:id="@+id/menu_item_columns_three"
+ android:title="@string/qs_menu_item_columns_three"
+ android:checkable="true" />
+ <item android:id="@+id/menu_item_columns_four"
+ android:title="@string/qs_menu_item_columns_four"
+ android:checkable="true" />
+ <item android:id="@+id/menu_item_columns_five"
+ android:title="@string/qs_menu_item_columns_five"
+ android:checkable="true" />
+ <item android:id="@+id/menu_item_columns_six"
+ android:title="@string/qs_menu_item_columns_six"
+ android:checkable="true" />
+ <item android:id="@+id/menu_item_columns_seven"
+ android:title="@string/qs_menu_item_columns_seven"
+ android:checkable="true" />
+ <item android:id="@+id/menu_item_columns_eight"
+ android:title="@string/qs_menu_item_columns_eight"
+ android:checkable="true" />
+ </menu>
+ </item>
+ <item android:id="@+id/menu_item_columns_landscape"
+ android:title="@string/qs_menu_item_columns_landscape">
+ <menu>
+ <item android:id="@+id/menu_item_columns_landscape_four"
+ android:title="@string/qs_menu_item_columns_four"
+ android:checkable="true" />
+ <item android:id="@+id/menu_item_columns_landscape_five"
+ android:title="@string/qs_menu_item_columns_five"
+ android:checkable="true" />
+ <item android:id="@+id/menu_item_columns_landscape_six"
+ android:title="@string/qs_menu_item_columns_six"
+ android:checkable="true" />
+ <item android:id="@+id/menu_item_columns_landscape_seven"
+ android:title="@string/qs_menu_item_columns_seven"
+ android:checkable="true" />
+ <item android:id="@+id/menu_item_columns_landscape_eight"
+ android:title="@string/qs_menu_item_columns_eight"
+ android:checkable="true" />
+ </menu>
+ </item>
+ <item android:id="@+id/menu_item_qs_columns"
+ android:title="@string/qs_menu_item_qs_columns">
+ <menu>
+ <item android:id="@+id/menu_item_qs_columns_six"
+ android:title="@string/qs_menu_item_columns_six"
+ android:checkable="true" />
+ <item android:id="@+id/menu_item_qs_columns_seven"
+ android:title="@string/qs_menu_item_columns_seven"
+ android:checkable="true" />
+ <item android:id="@+id/menu_item_qs_columns_eight"
+ android:title="@string/qs_menu_item_columns_eight"
+ android:checkable="true" />
+ <item android:id="@+id/menu_item_qs_columns_auto"
+ android:title="@string/qs_menu_item_columns_auto"
+ android:checkable="true" />
+ </menu>
+ </item>
+ <item android:id="@+id/menu_item_titles"
+ android:title="@string/qs_menu_item_titles"
+ android:checkable="true" />
+ <item android:id="@+id/menu_item_reset"
+ android:title="@string/qs_menu_item_reset"/>
+</menu>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 58af3df..a988d8b 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -853,7 +853,7 @@
<string name="right_keycode" msgid="2480715509844798438">"Right keycode"</string>
<string name="left_icon" msgid="5036278531966897006">"Left icon"</string>
<string name="right_icon" msgid="1103955040645237425">"Right icon"</string>
- <string name="drag_to_add_tiles" msgid="8933270127508303672">"Hold and drag to add tiles"</string>
+ <string name="drag_to_add_tiles" msgid="8933270127508303672">"Press on tiles to add or remove"</string>
<string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"Hold and drag to rearrange tiles"</string>
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Drag here to remove"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"You need at least <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> tiles"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index c0378ed..1e3f7d6 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -853,7 +853,7 @@
<string name="right_keycode" msgid="2480715509844798438">"Right keycode"</string>
<string name="left_icon" msgid="5036278531966897006">"Left icon"</string>
<string name="right_icon" msgid="1103955040645237425">"Right icon"</string>
- <string name="drag_to_add_tiles" msgid="8933270127508303672">"Hold and drag to add tiles"</string>
+ <string name="drag_to_add_tiles" msgid="8933270127508303672">"Press on tiles to add or remove"</string>
<string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"Hold and drag to rearrange tiles"</string>
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Drag here to remove"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"You need at least <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> tiles"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 58af3df..a988d8b 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -853,7 +853,7 @@
<string name="right_keycode" msgid="2480715509844798438">"Right keycode"</string>
<string name="left_icon" msgid="5036278531966897006">"Left icon"</string>
<string name="right_icon" msgid="1103955040645237425">"Right icon"</string>
- <string name="drag_to_add_tiles" msgid="8933270127508303672">"Hold and drag to add tiles"</string>
+ <string name="drag_to_add_tiles" msgid="8933270127508303672">"Press on tiles to add or remove"</string>
<string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"Hold and drag to rearrange tiles"</string>
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Drag here to remove"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"You need at least <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> tiles"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 58af3df..a988d8b 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -853,7 +853,7 @@
<string name="right_keycode" msgid="2480715509844798438">"Right keycode"</string>
<string name="left_icon" msgid="5036278531966897006">"Left icon"</string>
<string name="right_icon" msgid="1103955040645237425">"Right icon"</string>
- <string name="drag_to_add_tiles" msgid="8933270127508303672">"Hold and drag to add tiles"</string>
+ <string name="drag_to_add_tiles" msgid="8933270127508303672">"Press on tiles to add or remove"</string>
<string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"Hold and drag to rearrange tiles"</string>
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Drag here to remove"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"You need at least <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> tiles"</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index 808ce2b..f6166183 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -853,7 +853,7 @@
<string name="right_keycode" msgid="2480715509844798438">"Right keycode"</string>
<string name="left_icon" msgid="5036278531966897006">"Left icon"</string>
<string name="right_icon" msgid="1103955040645237425">"Right icon"</string>
- <string name="drag_to_add_tiles" msgid="8933270127508303672">"Hold and drag to add tiles"</string>
+ <string name="drag_to_add_tiles" msgid="8933270127508303672">"Press on tiles to add or remove"</string>
<string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"Hold and drag to rearrange tiles"</string>
<string name="drag_to_remove_tiles" msgid="4682194717573850385">"Drag here to remove"</string>
<string name="drag_to_remove_disabled" msgid="933046987838658850">"You need at least <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> tiles"</string>
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index fdf4e3b..aa574c7 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -32,6 +32,9 @@
<!-- Minimum fraction of the screen that should be taken up by the notification panel. -->
<item type="dimen" name="notification_panel_min_height_frac">40%</item>
+ <!-- Standard notification width -->
+ <dimen name="notification_panel_width">416dp</dimen>
+
<!-- How far to slide the panel out when you touch it -->
<!-- On tablets this is just the close_handle_height -->
<dimen name="peek_height">@dimen/close_handle_height</dimen>
diff --git a/packages/SystemUI/res/values/bliss_arrays.xml b/packages/SystemUI/res/values/bliss_arrays.xml
new file mode 100644
index 0000000..492e0a0
--- /dev/null
+++ b/packages/SystemUI/res/values/bliss_arrays.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 BlissRoms 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.
+-->
+<resources>
+
+</resources>
diff --git a/packages/SystemUI/res/values/bliss_attrs.xml b/packages/SystemUI/res/values/bliss_attrs.xml
new file mode 100644
index 0000000..5193bbf
--- /dev/null
+++ b/packages/SystemUI/res/values/bliss_attrs.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 BlissRoms 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.
+-->
+<resources>
+
+ <!-- Battery Bar -->
+ <declare-styleable name="BatteryBarController">
+ <attr name="viewLocation" format="integer" />
+ </declare-styleable>
+
+</resources>
diff --git a/packages/SystemUI/res/values/bliss_colors.xml b/packages/SystemUI/res/values/bliss_colors.xml
new file mode 100644
index 0000000..c95fb13
--- /dev/null
+++ b/packages/SystemUI/res/values/bliss_colors.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 BlissRoms 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.
+-->
+<resources>
+
+ <!-- Color of the FOD view -->
+ <color name="config_fodColor">#00ff00</color>
+ <color name="config_fodColorBackground">#20000000</color>
+
+ <color name="accent_device_default_light">@*android:color/accent_device_default_light</color>
+
+</resources>
diff --git a/packages/SystemUI/res/values/bliss_config.xml b/packages/SystemUI/res/values/bliss_config.xml
new file mode 100644
index 0000000..c7e9d86
--- /dev/null
+++ b/packages/SystemUI/res/values/bliss_config.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 BlissRoms 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.
+-->
+<resources>
+
+ <!-- The default tiles to display in QuickSettings -->
+ <string name="quick_settings_tiles_extra" translatable="false">
+ </string>
+
+ <!-- Allow devices override audio panel location to the left side -->
+ <bool name="config_audioPanelOnLeftSide">false</bool>
+</resources>
diff --git a/packages/SystemUI/res/values/bliss_dimens.xml b/packages/SystemUI/res/values/bliss_dimens.xml
new file mode 100644
index 0000000..1d24201
--- /dev/null
+++ b/packages/SystemUI/res/values/bliss_dimens.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 BlissRoms 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.
+-->
+<resources>
+
+ <!-- Sets a custom extra padding for the QS icons and statusbar date -->
+ <dimen name="qs_items_padding">8dp</dimen>
+ <dimen name="qs_tile_height_wo_label">48dp</dimen>
+
+ <!-- Tri-state UI -->
+ <dimen name="tri_state_down_dialog_position">850.0px</dimen>
+ <dimen name="tri_state_down_dialog_position_l">650.0px</dimen>
+ <dimen name="tri_state_middle_dialog_position">650.0px</dimen>
+ <dimen name="tri_state_middle_dialog_position_l">650.0px</dimen>
+ <dimen name="tri_state_up_dialog_position">450.0px</dimen>
+ <dimen name="tri_state_up_dialog_position_l">650.0px</dimen>
+ <dimen name="tri_state_up_dialog_position_deep">21.0px</dimen>
+ <dimen name="tri_state_up_dialog_position_deep_land">21.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_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="left_tri_state_down_bottom_left_radius">24.0dip</dimen>
+ <dimen name="left_tri_state_down_bottom_right_radius">24.0dip</dimen>
+ <dimen name="left_tri_state_down_top_left_radius">0.0dip</dimen>
+ <dimen name="left_tri_state_down_top_right_radius">24.0dip</dimen>
+ <dimen name="left_tri_state_up_bottom_left_radius">0.0dip</dimen>
+ <dimen name="left_tri_state_up_bottom_right_radius">24.0dip</dimen>
+ <dimen name="left_tri_state_up_top_left_radius">24.0dip</dimen>
+ <dimen name="left_tri_state_up_top_right_radius">24.0dip</dimen>
+ <dimen name="right_tri_state_down_bottom_left_radius">24.0dip</dimen>
+ <dimen name="right_tri_state_down_bottom_right_radius">24.0dip</dimen>
+ <dimen name="right_tri_state_down_top_left_radius">24.0dip</dimen>
+ <dimen name="right_tri_state_down_top_right_radius">0.0dip</dimen>
+ <dimen name="right_tri_state_up_bottom_left_radius">24.0dip</dimen>
+ <dimen name="right_tri_state_up_bottom_right_radius">0.0dip</dimen>
+ <dimen name="right_tri_state_up_top_left_radius">24.0dip</dimen>
+ <dimen name="right_tri_state_up_top_right_radius">24.0dip</dimen>
+ <dimen name="tri_state_position_padding_extra">@*android:dimen/status_bar_height</dimen>
+
+ <!-- Network traffic monitor -->
+ <dimen name="net_traffic_multi_text_size">8dp</dimen>
+ <dimen name="net_traffic_txt_img_padding">4dp</dimen>
+
+ <!-- Width of the battery icon in the status bar when set to circle style. -->
+ <dimen name="status_bar_battery_icon_circle_width">13.5dp</dimen>
+</resources>
diff --git a/packages/SystemUI/res/values/bliss_strings.xml b/packages/SystemUI/res/values/bliss_strings.xml
new file mode 100644
index 0000000..57a1f89
--- /dev/null
+++ b/packages/SystemUI/res/values/bliss_strings.xml
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 BlissRoms 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.
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- Text to use when the number in a notification info is too large
+ (greater than status_bar_notification_info_maxnum, defined in
+ values/config.xml) and must be truncated.
+ [CHAR LIMIT=4] -->
+ <string name="status_bar_notification_info_overflow" translatable="false">\u221E</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>
+
+ <!-- Ambient display QS tile -->
+ <string name="quick_settings_ambient_display_label">Ambient display</string>
+ <string name="accessibility_quick_settings_ambient_display_off">Ambient display off.</string>
+ <string name="accessibility_quick_settings_ambient_display_on">Ambient display on.</string>
+ <string name="accessibility_quick_settings_ambient_display_changed_off">Ambient display turned off.</string>
+ <string name="accessibility_quick_settings_ambient_display_changed_on">Ambient display turned on.</string>
+
+ <!-- USB tethering QS tile -->
+ <string name="quick_settings_usb_tether_label">USB tethering</string>
+
+ <!-- Sync QS Tile -->
+ <string name="quick_settings_sync_label">Sync</string>
+ <string name="accessibility_quick_settings_sync_off">Sync off</string>
+ <string name="accessibility_quick_settings_sync_on">Sync on</string>
+ <string name="accessibility_quick_settings_sync_changed_off">Sync turned off</string>
+ <string name="accessibility_quick_settings_sync_changed_on">Sync turned on</string>
+
+ <!-- Advance location quick setting tile -->
+ <string name="quick_settings_secondary_location_off"></string>
+ <string name="quick_settings_location_secondary_battery_saving">Battery Saving</string>
+ <string name="accessibility_quick_settings_location_battery_saving">Location reporting: battery saving mode.</string>
+ <string name="quick_settings_location_secondary_gps_only">Sensors Only</string>
+ <string name="accessibility_quick_settings_location_gps_only">Location reporting: sensors only mode.</string>
+ <string name="quick_settings_location_secondary_high_accuracy">High Accuracy</string>
+ <string name="accessibility_quick_settings_location_high_accuracy">Location reporting: high accuracy mode.</string>
+
+ <!-- Power Menu -->
+ <string name="global_action_restart_advanced">Advanced</string>
+ <string name="global_action_restart_recovery">Recovery</string>
+ <string name="global_action_restart_bootloader">Bootloader</string>
+ <string name="global_action_restart_ui">SystemUI</string>
+
+ <!-- QS Config -->
+ <string name="qs_menu_item_columns">Columns</string>
+ <string name="qs_menu_item_columns_landscape">Columns landscape</string>
+ <string name="qs_menu_item_columns_three">3</string>
+ <string name="qs_menu_item_columns_four">4</string>
+ <string name="qs_menu_item_columns_five">5</string>
+ <string name="qs_menu_item_columns_six">6</string>
+ <string name="qs_menu_item_columns_seven">7</string>
+ <string name="qs_menu_item_columns_eight">8</string>
+ <string name="qs_menu_item_columns_nine">9</string>
+ <string name="qs_menu_item_reset">Reset</string>
+ <string name="qs_menu_item_qs_columns">Quickbar columns</string>
+ <string name="qs_menu_item_columns_auto">Automatic</string>
+ <string name="qs_menu_item_titles">Show labels</string>
+
+ <!-- Sound QS Tile -->
+ <string name="quick_settings_sound_label">Sound</string>
+ <string name="quick_settings_sound_ring">Ring</string>
+ <string name="quick_settings_sound_vibrate">Vibrate</string>
+ <string name="quick_settings_sound_dnd">Do not disturb</string>
+
+ <!-- Screenshot QS tile -->
+ <string name="quick_settings_screenshot_label">Screenshot</string>
+ <string name="quick_settings_region_screenshot_label">Partial screenshot</string>
+
+ <!-- Spidey Analog clock -->
+ <string name="clock_title_spidey" translatable="false">Spidey</string>
+
+ <!-- Spectrum Analog clock -->
+ <string name="clock_title_spectrum" translatable="false">Spectrum</string>
+
+ <!-- Dot Analog clock -->
+ <string name="clock_title_dot" translatable="false">Dot</string>
+
+ <!-- Sneeky Analog clock -->
+ <string name="clock_title_sneeky" translatable="false">Sneeky</string>
+
+ <!-- Bliss Analog clock -->
+ <string name="clock_title_bliss" translatable="false">Bliss</string>
+
+ <!-- Custom num Analog clock -->
+ <string name="clock_title_custom_num" translatable="false">Custom-Num</string>
+
+ <!-- Oneplus Numbers clock -->
+ <string name="clock_title_oneplus_numbers" translatable="false">OnePlus Numbers</string>
+
+ <!-- Oneplus Analog clock -->
+ <string name="clock_title_oneplus_minimal" translatable="false">OnePlus Minimal</string>
+
+ <!-- Oneplus Analog clock -->
+ <string name="clock_title_oneplus_roman" translatable="false">OnePlus Roman</string>
+
+ <!-- Oneplus Analog clock -->
+ <string name="clock_title_oneplus_analog" translatable="false">OnePlus Analog</string>
+
+ <!-- Oneplus Analog clock -->
+ <string name="clock_title_minimalism" translatable="false">Minimalism</string>
+
+ <!-- Indication on the keyguard that is shown when the device is charging with a dash charger. Should match keyguard_plugged_in_dash_charging [CHAR LIMIT=40]-->
+ <string name="keyguard_indication_dash_charging_time">Dash Charging (<xliff:g id="charging_time_left" example="4 hours and 2 minutes">%s</xliff:g> until full)</string>
+ <string name="keyguard_plugged_in_dash_charging">Dash Charging</string>
+
+ <!-- Indication on the keyguard that is shown when the device is charging with a warp charger. Should match keyguard_plugged_in_warp_charging [CHAR LIMIT=40]-->
+ <string name="keyguard_indication_warp_charging_time" formatted="false"><xliff:g id="percentage">%2$s</xliff:g> • Warp Charging (<xliff:g id="charging_time_left" example="4 hours and 2 minutes">%s</xliff:g> until full)</string>
+ <string name="keyguard_plugged_in_warp_charging">Warp Charging</string>
+
+ <!-- Indication on the keyguard that is shown when the device is charging with a VOOC charger. Should match keyguard_plugged_in_vooc_charging [CHAR LIMIT=40]-->
+ <string name="keyguard_indication_vooc_charging_time" formatted="false"><xliff:g id="percentage">%2$s</xliff:g> • VOOC Charging (<xliff:g id="charging_time_left" example="4 hours and 2 minutes">%1$s</xliff:g> until full)</string>
+ <string name="keyguard_plugged_in_vooc_charging">VOOC Charging</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>
+ <string name="accessibility_quick_settings_heads_up_changed_off">Heads up turned off.</string>
+ <string name="accessibility_quick_settings_heads_up_changed_on">Heads up turned on.</string>
+
+ <!-- Heads up snooze toast -->
+ <string name="heads_up_snooze_message_one_minute"><xliff:g id="string">%s</xliff:g> - Peeking notification are snoozing for 1 minute.</string>
+ <string name="heads_up_snooze_message"><xliff:g id="string">%1$s</xliff:g> - Peeking notifications are snoozing for <xliff:g id="number">%1$d</xliff:g> minutes.</string>
+
+ <!-- Running service button -->
+ <string name="accessibility_quick_settings_running_services">Open Running Services screen.</string>
+
+ <!-- Kill button in notification guts -->
+ <string name="force_stop_dlg_title">Force stop?</string>
+ <string name="force_stop_dlg_text">If you force stop an app, it may misbehave.</string>
+ <string name="dlg_ok">@android:string/ok</string>
+ <string name="dlg_cancel">@android:string/cancel</string>
+ <string name="guts_force_close_app">Close App</string>
+</resources>
diff --git a/packages/SystemUI/res/values/bliss_styles.xml b/packages/SystemUI/res/values/bliss_styles.xml
new file mode 100644
index 0000000..181c850
--- /dev/null
+++ b/packages/SystemUI/res/values/bliss_styles.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2014-2021 BlissRoms 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.
+-->
+<resources>
+
+</resources>
diff --git a/packages/SystemUI/res/values/bliss_symbols.xml b/packages/SystemUI/res/values/bliss_symbols.xml
new file mode 100644
index 0000000..492e0a0
--- /dev/null
+++ b/packages/SystemUI/res/values/bliss_symbols.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014-2020 BlissRoms 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.
+-->
+<resources>
+
+</resources>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 994a181..df29778 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -52,7 +52,7 @@
<!-- The color of the background of the emergency button when home controls are visible -->
<color name="global_actions_emergency_background">@color/GM2_red_400</color>
- <color name="global_actions_emergency_text">@color/GM2_grey_100</color>
+ <color name="global_actions_emergency_text">@color/GM2_red_400</color>
<!-- Tint color for the content on the notification overflow card. -->
<color name="keyguard_overflow_content_color">#ff686868</color>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 5e5df6b..d3a0dce 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -114,7 +114,7 @@
<!-- Tiles native to System UI. Order should match "quick_settings_tiles_default" -->
<string name="quick_settings_tiles_stock" translatable="false">
- wifi,cell,battery,dnd,flashlight,rotation,bt,airplane,location,hotspot,inversion,saver,dark,work,cast,night,screenrecord,reverse
+ wifi,cell,battery,dnd,flashlight,rotation,bt,airplane,nfc,location,hotspot,inversion,saver,dark,work,cast,night,screenrecord,reverse,caffeine,ambient_display,usb_tether,sync,sound,screenshot,heads_up
</string>
<!-- The tiles to display in QuickSettings -->
@@ -319,6 +319,7 @@
<item>com.android.systemui.globalactions.GlobalActionsComponent</item>
<item>com.android.systemui.ScreenDecorations</item>
<item>com.android.systemui.biometrics.AuthController</item>
+ <item>com.android.systemui.biometrics.FODCircleViewImpl</item>
<item>com.android.systemui.SliceBroadcastRelayHandler</item>
<item>com.android.systemui.SizeCompatModeActivityController</item>
<item>com.android.systemui.statusbar.notification.InstantAppNotifier</item>
@@ -572,7 +573,7 @@
<integer name="controls_max_columns">2</integer>
<!-- Max number of columns for power menu -->
- <integer name="power_menu_max_columns">3</integer>
+ <integer name="power_menu_max_columns">4</integer>
<!-- If the dp width of the available space is <= this value, potentially adjust the number
of columns-->
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index f002a27..d309149 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -88,7 +88,7 @@
<dimen name="status_bar_left_clock_starting_padding">0dp</dimen>
<!-- End padding for left-aligned status bar clock -->
- <dimen name="status_bar_left_clock_end_padding">7dp</dimen>
+ <dimen name="status_bar_left_clock_end_padding">3dp</dimen>
<!-- Spacing after the wifi signals that is present if there are any icons following it. -->
<dimen name="status_bar_wifi_signal_spacer_width">2.5dp</dimen>
@@ -632,7 +632,7 @@
<dimen name="notification_section_divider_height">@dimen/notification_side_paddings</dimen>
<!-- Size of the face pile shown on one-line (children of a group) conversation notifications -->
- <dimen name="conversation_single_line_face_pile_size">25dp</dimen>
+ <dimen name="conversation_single_line_face_pile_size">20dp</dimen>
<!-- Size of an avatar shown on one-line (children of a group) conversation notifications -->
<dimen name="conversation_single_line_avatar_size">20dp</dimen>
@@ -694,7 +694,7 @@
<dimen name="edge_tap_area_width">48dp</dimen>
<!-- The padding between notification children when collapsed -->
- <dimen name="notification_children_padding">4dp</dimen>
+ <dimen name="notification_children_padding">2.5dp</dimen>
<!-- The padding on top of the first notification to the children container -->
<dimen name="notification_children_container_top_padding">8dp</dimen>
@@ -1060,9 +1060,9 @@
<dimen name="global_actions_wallet_top_margin">40dp</dimen>
<!-- Shutdown and restart actions are larger in power options dialog -->
- <dimen name="global_actions_power_dialog_item_height">190dp</dimen>
- <dimen name="global_actions_power_dialog_item_width">255dp</dimen>
- <dimen name="global_actions_power_dialog_item_bottom_margin">45dp</dimen>
+ <dimen name="global_actions_power_dialog_item_height">140dp</dimen>
+ <dimen name="global_actions_power_dialog_item_width">185dp</dimen>
+ <dimen name="global_actions_power_dialog_item_bottom_margin">15dp</dimen>
<!-- The maximum offset in either direction that elements are moved horizontally to prevent
burn-in on AOD. -->
@@ -1172,7 +1172,7 @@
<!-- Blur radius on status bar window and power menu -->
<dimen name="min_window_blur_radius">1px</dimen>
- <dimen name="max_window_blur_radius">150px</dimen>
+ <dimen name="max_window_blur_radius">175px</dimen>
<!-- How much into a DisplayCutout's bounds we can go, on each side -->
<dimen name="display_cutout_margin_consumption">0px</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 824521e..59f5184 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2205,7 +2205,7 @@
<string name="right_icon">Right icon</string>
<!-- Label for area where tiles can be dragged out of [CHAR LIMIT=60] -->
- <string name="drag_to_add_tiles">Hold and drag to add tiles</string>
+ <string name="drag_to_add_tiles">Press on tiles to add or remove</string>
<!-- Label for header of customize QS [CHAR LIMIT=60] -->
<string name="drag_to_rearrange_tiles">Hold and drag to rearrange tiles</string>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 990e092..60e105c 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -772,9 +772,9 @@
<item name="android:overlapAnchor">true</item>
<!-- used to override dark/light theming -->
- <item name="*android:colorBackgroundFloating">@color/GM2_grey_800</item>
- <item name="*android:colorPopupBackground">@color/GM2_grey_800</item>
- <item name="*android:dialogCornerRadius">8dp</item>
+ <item name="*android:colorBackgroundFloating">?android:attr/colorSecondary</item>
+ <item name="*android:colorPopupBackground">?android:attr/colorSecondary</item>
+ <item name="*android:dialogCornerRadius">@*android:dimen/config_dialogCornerRadius</item>
</style>
<style name="TextAppearance.ControlSetup">
diff --git a/packages/SystemUI/res/xml/status_bar_prefs.xml b/packages/SystemUI/res/xml/status_bar_prefs.xml
new file mode 100644
index 0000000..5f7e758
--- /dev/null
+++ b/packages/SystemUI/res/xml/status_bar_prefs.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:sysui="http://schemas.android.com/apk/res-auto"
+ android:key="status_bar"
+ android:title="@string/status_bar">
+
+ <com.android.systemui.tuner.StatusBarSwitch
+ android:key="rotate"
+ android:title="@string/status_bar_settings_auto_rotation" />
+
+ <com.android.systemui.tuner.StatusBarSwitch
+ android:key="headset"
+ android:title="@string/headset" />
+
+ <com.android.systemui.tuner.StatusBarSwitch
+ android:key="managed_profile"
+ android:title="@string/status_bar_work" />
+
+ <!-- ime -->
+ <!-- sync_failing -->
+ <!-- sync_active -->
+
+ <com.android.systemui.tuner.StatusBarSwitch
+ android:key="cast"
+ android:title="@string/quick_settings_cast_title" />
+
+ <com.android.systemui.tuner.StatusBarSwitch
+ android:key="hotspot"
+ android:title="@string/quick_settings_hotspot_label" />
+
+ <com.android.systemui.tuner.StatusBarSwitch
+ android:key="bluetooth"
+ android:title="@string/quick_settings_bluetooth_label" />
+
+ <!-- nfc -->
+ <!-- tty -->
+ <!-- speakerphone -->
+
+ <com.android.systemui.tuner.StatusBarSwitch
+ android:key="zen"
+ android:title="@string/quick_settings_dnd_label" />
+
+ <!-- mute -->
+
+ <com.android.systemui.tuner.StatusBarSwitch
+ android:key="volume"
+ android:title="@*android:string/volume_unknown" />
+
+ <com.android.systemui.tuner.StatusBarSwitch
+ android:key="wifi"
+ android:title="@string/quick_settings_wifi_label" />
+
+ <com.android.systemui.tuner.StatusBarSwitch
+ android:key="ethernet"
+ android:title="@string/status_bar_ethernet" />
+
+ <com.android.systemui.tuner.StatusBarSwitch
+ android:key="mobile"
+ android:title="@string/quick_settings_cellular_detail_title" />
+
+ <com.android.systemui.tuner.StatusBarSwitch
+ android:key="airplane"
+ android:title="@string/status_bar_airplane" />
+
+ <!-- other weird signal stuff -->
+
+ <com.android.systemui.tuner.BatteryPreference
+ android:title="@string/battery"
+ android:summary="%s"
+ android:entries="@array/battery_options" />
+
+ <com.android.systemui.tuner.StatusBarSwitch
+ android:key="alarm_clock"
+ android:title="@string/status_bar_alarm" />
+
+ <!-- secure -->
+
+ <com.android.systemui.tuner.TunerSwitch
+ android:key="low_priority"
+ android:title="@string/tuner_low_priority"
+ sysui:defValue="false" />
+
+</PreferenceScreen>
diff --git a/packages/SystemUI/res/xml/tuner_prefs.xml b/packages/SystemUI/res/xml/tuner_prefs.xml
index 6eec5dc..647d9d7 100644
--- a/packages/SystemUI/res/xml/tuner_prefs.xml
+++ b/packages/SystemUI/res/xml/tuner_prefs.xml
@@ -18,92 +18,10 @@
xmlns:sysui="http://schemas.android.com/apk/res-auto"
android:title="@string/system_ui_tuner">
- <PreferenceScreen
+ <Preference
android:key="status_bar"
- android:title="@string/status_bar" >
-
- <com.android.systemui.tuner.StatusBarSwitch
- android:key="rotate"
- android:title="@string/status_bar_settings_auto_rotation" />
-
- <com.android.systemui.tuner.StatusBarSwitch
- android:key="headset"
- android:title="@string/headset" />
-
- <com.android.systemui.tuner.StatusBarSwitch
- android:key="managed_profile"
- android:title="@string/status_bar_work" />
-
- <!-- ime -->
- <!-- sync_failing -->
- <!-- sync_active -->
-
- <com.android.systemui.tuner.StatusBarSwitch
- android:key="cast"
- android:title="@string/quick_settings_cast_title" />
-
- <com.android.systemui.tuner.StatusBarSwitch
- android:key="hotspot"
- android:title="@string/quick_settings_hotspot_label" />
-
- <com.android.systemui.tuner.StatusBarSwitch
- android:key="bluetooth"
- android:title="@string/quick_settings_bluetooth_label" />
-
- <!-- nfc -->
- <!-- tty -->
- <!-- speakerphone -->
-
- <com.android.systemui.tuner.StatusBarSwitch
- android:key="zen"
- android:title="@string/quick_settings_dnd_label" />
-
- <!-- mute -->
-
- <com.android.systemui.tuner.StatusBarSwitch
- android:key="volume"
- android:title="@*android:string/volume_unknown" />
-
- <com.android.systemui.tuner.StatusBarSwitch
- android:key="wifi"
- android:title="@string/quick_settings_wifi_label" />
-
- <com.android.systemui.tuner.StatusBarSwitch
- android:key="ethernet"
- android:title="@string/status_bar_ethernet" />
-
- <com.android.systemui.tuner.StatusBarSwitch
- android:key="mobile"
- android:title="@string/quick_settings_cellular_detail_title" />
-
- <com.android.systemui.tuner.StatusBarSwitch
- android:key="airplane"
- android:title="@string/status_bar_airplane" />
-
- <!-- other weird signal stuff -->
-
- <com.android.systemui.tuner.BatteryPreference
- android:title="@string/battery"
- android:summary="%s"
- android:entries="@array/battery_options" />
-
- <com.android.systemui.tuner.StatusBarSwitch
- android:key="alarm_clock"
- android:title="@string/status_bar_alarm" />
-
- <!-- secure -->
-
- <com.android.systemui.tuner.ClockPreference
- android:title="@string/tuner_time"
- android:summary="%s"
- android:entries="@array/clock_options" />
-
- <com.android.systemui.tuner.TunerSwitch
- android:key="low_priority"
- android:title="@string/tuner_low_priority"
- sysui:defValue="false" />
-
- </PreferenceScreen>
+ android:title="@string/status_bar"
+ android:fragment="com.android.systemui.tuner.StatusBarTuner" />
<PreferenceScreen
android:key="volume_and_do_not_disturb"
@@ -118,7 +36,7 @@
sysui:metricsAction="315" />
</PreferenceScreen>
-
+<!--
<PreferenceScreen
android:key="doze"
android:title="@string/tuner_doze">
@@ -129,7 +47,7 @@
sysui:defValue="true" />
</PreferenceScreen>
-
+-->
<Preference
android:key="nav_bar"
android:title="@string/nav_bar"
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java
index 88f4176..bbf71dc 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java
@@ -205,6 +205,7 @@
boolean isValidPassword) {
boolean dismissKeyguard = KeyguardUpdateMonitor.getCurrentUser() == userId;
if (matched) {
+ mLockPatternUtils.sanitizePassword();
mCallback.reportUnlockAttempt(userId, true, 0);
if (dismissKeyguard) {
mDismissing = true;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockAccessibilityDelegate.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockAccessibilityDelegate.java
deleted file mode 100644
index a78c293..0000000
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockAccessibilityDelegate.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.keyguard;
-
-import android.content.Context;
-import android.text.TextUtils;
-import android.view.View;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityNodeInfo;
-import android.widget.TextView;
-
-import com.android.systemui.R;
-
-/**
- * Replaces fancy colons with regular colons. Only works on TextViews.
- */
-class KeyguardClockAccessibilityDelegate extends View.AccessibilityDelegate {
- private final String mFancyColon;
-
- public KeyguardClockAccessibilityDelegate(Context context) {
- mFancyColon = context.getString(R.string.keyguard_fancy_colon);
- }
-
- @Override
- public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) {
- super.onInitializeAccessibilityEvent(host, event);
- if (TextUtils.isEmpty(mFancyColon)) {
- return;
- }
- CharSequence text = event.getContentDescription();
- if (!TextUtils.isEmpty(text)) {
- event.setContentDescription(replaceFancyColon(text));
- }
- }
-
- @Override
- public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
- if (TextUtils.isEmpty(mFancyColon)) {
- super.onPopulateAccessibilityEvent(host, event);
- } else {
- CharSequence text = ((TextView) host).getText();
- if (!TextUtils.isEmpty(text)) {
- event.getText().add(replaceFancyColon(text));
- }
- }
- }
-
- @Override
- public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
- super.onInitializeAccessibilityNodeInfo(host, info);
- if (TextUtils.isEmpty(mFancyColon)) {
- return;
- }
- if (!TextUtils.isEmpty(info.getText())) {
- info.setText(replaceFancyColon(info.getText()));
- }
- if (!TextUtils.isEmpty(info.getContentDescription())) {
- info.setContentDescription(replaceFancyColon(info.getContentDescription()));
- }
- }
-
- private CharSequence replaceFancyColon(CharSequence text) {
- if (TextUtils.isEmpty(mFancyColon)) {
- return text;
- }
- return text.toString().replace(mFancyColon, ":");
- }
-
- public static boolean isNeeded(Context context) {
- return !TextUtils.isEmpty(context.getString(R.string.keyguard_fancy_colon));
- }
-}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
index 6f06f69..6ae0123 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -18,6 +18,7 @@
import android.util.AttributeSet;
import android.util.Log;
import android.util.MathUtils;
+import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
@@ -29,6 +30,7 @@
import com.android.internal.colorextraction.ColorExtractor;
import com.android.internal.colorextraction.ColorExtractor.OnColorsChangedListener;
import com.android.keyguard.clock.ClockManager;
+import com.android.keyguard.KeyguardSliceView;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.colorextraction.SysuiColorExtractor;
@@ -51,7 +53,6 @@
public class KeyguardClockSwitch extends RelativeLayout {
private static final String TAG = "KeyguardClockSwitch";
- private static final boolean CUSTOM_CLOCKS_ENABLED = true;
/**
* Animation fraction when text is transitioned to/from bold.
@@ -111,7 +112,7 @@
* Status area (date and other stuff) shown below the clock. Plugin can decide whether or not to
* show it below the alternate clock.
*/
- private View mKeyguardStatusArea;
+ private KeyguardSliceView mKeyguardStatusArea;
/**
* Maintain state so that a newly connected plugin can be initialized.
@@ -129,6 +130,7 @@
private boolean mShowingHeader;
private boolean mSupportsDarkText;
private int[] mColorPalette;
+ private boolean mShowCurrentUserTime;
/**
* Track the state of the status bar to know when to hide the big_clock_container.
@@ -188,6 +190,10 @@
return mClockPlugin != null;
}
+ public boolean hasCustomClockInBigContainer() {
+ return hasCustomClock() && mClockPlugin.shouldShowInBigContainer();
+ }
+
@Override
protected void onFinishInflate() {
super.onFinishInflate();
@@ -200,9 +206,7 @@
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
- if (CUSTOM_CLOCKS_ENABLED) {
- mClockManager.addOnClockChangedListener(mClockChangedListener);
- }
+ mClockManager.addOnClockChangedListener(mClockChangedListener);
mStatusBarStateController.addCallback(mStateListener);
mSysuiColorExtractor.addOnColorsChangedListener(mColorsListener);
updateColors();
@@ -211,9 +215,7 @@
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
- if (CUSTOM_CLOCKS_ENABLED) {
- mClockManager.removeOnClockChangedListener(mClockChangedListener);
- }
+ mClockManager.removeOnClockChangedListener(mClockChangedListener);
mStatusBarStateController.removeCallback(mStateListener);
mSysuiColorExtractor.removeOnColorsChangedListener(mColorsListener);
setClockPlugin(null);
@@ -226,6 +228,10 @@
if (smallClockView != null && smallClockView.getParent() == mSmallClockFrame) {
mSmallClockFrame.removeView(smallClockView);
}
+ View bigClockView = mClockPlugin.getBigClockView();
+ if (bigClockView != null && bigClockView.getParent() == mSmallClockFrame) {
+ mSmallClockFrame.removeView(bigClockView);
+ }
if (mBigClockContainer != null) {
mBigClockContainer.removeAllViews();
updateBigClockVisibility();
@@ -233,6 +239,7 @@
mClockPlugin.onDestroyView();
mClockPlugin = null;
}
+ adjustStatusAreaPadding(plugin);
if (plugin == null) {
if (mShowingHeader) {
mClockView.setVisibility(View.GONE);
@@ -244,24 +251,37 @@
mKeyguardStatusArea.setVisibility(View.VISIBLE);
return;
}
+
+
// Attach small and big clock views to hierarchy.
View smallClockView = plugin.getView();
- if (smallClockView != null) {
- mSmallClockFrame.addView(smallClockView, -1,
- new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
+ View bigClockView = plugin.getBigClockView();
+
+ if (plugin.shouldShowInBigContainer()) {
+ if (smallClockView != null) {
+ mSmallClockFrame.addView(smallClockView, -1,
+ new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
+ mClockView.setVisibility(View.GONE);
+ mClockViewBold.setVisibility(View.GONE);
+ }
+ if (bigClockView != null && mBigClockContainer != null) {
+ mBigClockContainer.addView(bigClockView);
+ updateBigClockVisibility();
+ }
+ } else {
mClockView.setVisibility(View.GONE);
mClockViewBold.setVisibility(View.GONE);
+
+ if (bigClockView != null ) {
+ mSmallClockFrame.addView(bigClockView, -1,
+ new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT));
+ }
}
- View bigClockView = plugin.getBigClockView();
- if (bigClockView != null && mBigClockContainer != null) {
- mBigClockContainer.addView(bigClockView);
- updateBigClockVisibility();
- }
- // Hide default clock.
- if (!plugin.shouldShowStatusArea()) {
- mKeyguardStatusArea.setVisibility(View.GONE);
- }
+
+ // Show / hide status area
+ mKeyguardStatusArea.setVisibility(plugin.shouldShowStatusArea() ? View.VISIBLE : View.GONE);
// Initialize plugin parameters.
mClockPlugin = plugin;
mClockPlugin.setStyle(getPaint().getStyle());
@@ -277,12 +297,16 @@
*/
public void setBigClockContainer(ViewGroup container) {
if (mClockPlugin != null && container != null) {
- View bigClockView = mClockPlugin.getBigClockView();
- if (bigClockView != null) {
- container.addView(bigClockView);
+ if (mClockPlugin.shouldShowInBigContainer()) {
+ View bigClockView = mClockPlugin.getBigClockView();
+ if (bigClockView != null) {
+ container.addView(bigClockView);
+ }
+ mBigClockContainer = container;
+ } else {
+ mBigClockContainer = null;
}
}
- mBigClockContainer = container;
updateBigClockVisibility();
}
@@ -311,6 +335,7 @@
public void setShowCurrentUserTime(boolean showCurrentUserTime) {
mClockView.setShowCurrentUserTime(showCurrentUserTime);
mClockViewBold.setShowCurrentUserTime(showCurrentUserTime);
+ mShowCurrentUserTime = showCurrentUserTime;
}
public void setTextSize(int unit, float size) {
@@ -394,7 +419,8 @@
}
if (Build.IS_DEBUGGABLE) {
// Log for debugging b/130888082 (sysui waking up, but clock not updating)
- Log.d(TAG, "Updating clock: " + mClockView.getText());
+ Log.d(TAG, "Updating clock: " + mClockView.getText().toString()
+ .replaceAll("[^\\x00-\\x7F]", ":"));
}
}
@@ -443,6 +469,14 @@
}
}
+ private void adjustStatusAreaPadding(ClockPlugin plugin) {
+ final boolean mIsTypeClock = plugin != null && plugin.getName().equals("type");
+ mKeyguardStatusArea.setRowGravity(mIsTypeClock ? Gravity.LEFT : Gravity.CENTER);
+ mKeyguardStatusArea.setRowPadding(mIsTypeClock ? mContext.getResources()
+ .getDimensionPixelSize(R.dimen.keyguard_status_area_typeclock_padding) : 0, 0, 0,
+ 0);
+ }
+
/**
* Sets if the keyguard slice is showing a center-aligned header. We need a smaller clock in
* these cases.
@@ -452,49 +486,6 @@
return;
}
mShowingHeader = hasHeader;
- if (hasCustomClock()) {
- return;
- }
-
- float smallFontSize = mContext.getResources().getDimensionPixelSize(
- R.dimen.widget_small_font_size);
- float bigFontSize = mContext.getResources().getDimensionPixelSize(
- R.dimen.widget_big_font_size);
- mClockTransition.setScale(smallFontSize / bigFontSize);
- mBoldClockTransition.setScale(bigFontSize / smallFontSize);
-
- // End any current transitions before starting a new transition so that the new transition
- // starts from a good state instead of a potentially bad intermediate state arrived at
- // during a transition animation.
- TransitionManager.endTransitions((ViewGroup) mClockView.getParent());
-
- if (hasHeader) {
- // After the transition, make the default clock GONE so that it doesn't make the
- // KeyguardStatusView appear taller in KeyguardClockPositionAlgorithm and elsewhere.
- mTransition.addListener(new TransitionListenerAdapter() {
- @Override
- public void onTransitionEnd(Transition transition) {
- super.onTransitionEnd(transition);
- // Check that header is actually showing. I saw issues where this event was
- // fired after the big clock transitioned back to visible, which causes the time
- // to completely disappear.
- if (mShowingHeader) {
- mClockView.setVisibility(View.GONE);
- }
- transition.removeListener(this);
- }
- });
- }
-
- TransitionManager.beginDelayedTransition((ViewGroup) mClockView.getParent(), mTransition);
- mClockView.setVisibility(hasHeader ? View.INVISIBLE : View.VISIBLE);
- mClockViewBold.setVisibility(hasHeader ? View.VISIBLE : View.INVISIBLE);
- int paddingBottom = mContext.getResources().getDimensionPixelSize(hasHeader
- ? R.dimen.widget_vertical_padding_clock : R.dimen.title_clock_padding);
- mClockView.setPadding(mClockView.getPaddingLeft(), mClockView.getPaddingTop(),
- mClockView.getPaddingRight(), paddingBottom);
- mClockViewBold.setPadding(mClockViewBold.getPaddingLeft(), mClockViewBold.getPaddingTop(),
- mClockViewBold.getPaddingRight(), paddingBottom);
}
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
index 12ea1d5..27caf53 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
@@ -17,11 +17,22 @@
package com.android.keyguard;
import android.content.Context;
+import android.os.UserHandle;
+import android.provider.Settings;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AnimationUtils;
+import android.widget.LinearLayout;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import com.android.internal.widget.LockPatternUtils.RequestThrottledException;
+import com.android.internal.widget.LockscreenCredential;
+import com.android.keyguard.PasswordTextView.QuickUnlockListener;
import com.android.settingslib.animation.AppearAnimationUtils;
import com.android.settingslib.animation.DisappearAnimationUtils;
import com.android.systemui.Dependency;
@@ -45,6 +56,9 @@
private View[][] mViews;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+ private static List<Integer> sNumbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 0);
+ private final int userId = KeyguardUpdateMonitor.getCurrentUser();
+
public KeyguardPINView(Context context) {
this(context, null);
}
@@ -120,6 +134,46 @@
mCallback.onCancelClicked();
});
}
+
+ boolean scramblePin = (Settings.System.getIntForUser(getContext().getContentResolver(),
+ Settings.System.LOCKSCREEN_PIN_SCRAMBLE_LAYOUT, 0, UserHandle.USER_CURRENT) == 1);
+
+ if (scramblePin) {
+ Collections.shuffle(sNumbers);
+ // get all children who are NumPadKey's
+ LinearLayout container = (LinearLayout) findViewById(R.id.container);
+ List<NumPadKey> views = new ArrayList<NumPadKey>();
+ for (int i = 0; i < container.getChildCount(); i++) {
+ if (container.getChildAt(i) instanceof LinearLayout) {
+ LinearLayout nestedLayout = ((LinearLayout) container.getChildAt(i));
+ for (int j = 0; j < nestedLayout.getChildCount(); j++){
+ View view = nestedLayout.getChildAt(j);
+ if (view.getClass() == NumPadKey.class) {
+ views.add((NumPadKey) view);
+ }
+ }
+ }
+ }
+
+ // reset the digits in the views
+ for (int i = 0; i < sNumbers.size(); i++) {
+ NumPadKey view = views.get(i);
+ view.setDigit(sNumbers.get(i));
+ }
+ }
+
+ boolean quickUnlock = (Settings.System.getIntForUser(getContext().getContentResolver(),
+ Settings.System.LOCKSCREEN_QUICK_UNLOCK_CONTROL, 0, UserHandle.USER_CURRENT) == 1);
+
+ if (quickUnlock) {
+ mPasswordEntry.setQuickUnlockListener(new QuickUnlockListener() {
+ public void onValidateQuickUnlock(String password) {
+ validateQuickUnlock(password);
+ }
+ });
+ } else {
+ mPasswordEntry.setQuickUnlockListener(null);
+ }
}
@Override
@@ -183,4 +237,24 @@
public boolean hasOverlappingRendering() {
return false;
}
+
+ private void validateQuickUnlock(String password) {
+ if (password != null) {
+ if (password.length() > MINIMUM_PASSWORD_LENGTH_BEFORE_REPORT
+ && kpvCheckPassword(password)) {
+ mPasswordEntry.setEnabled(false);
+ mCallback.reportUnlockAttempt(userId, true, 0);
+ mCallback.dismiss(true, userId);
+ resetPasswordText(true, true);
+ }
+ }
+ }
+
+ private boolean kpvCheckPassword(String password) {
+ try {
+ return mLockPatternUtils.checkCredential(LockscreenCredential.createPinOrNone(password), userId, null);
+ } catch (RequestThrottledException ex) {
+ return false;
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
index 97317cf..9470c12 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
@@ -19,6 +19,7 @@
import android.content.Context;
import android.graphics.Rect;
import android.os.UserHandle;
+import android.provider.Settings;
import android.text.Editable;
import android.text.InputType;
import android.text.TextUtils;
@@ -37,6 +38,7 @@
import android.widget.TextView.OnEditorActionListener;
import com.android.internal.widget.LockscreenCredential;
+import com.android.internal.widget.LockPatternUtils.RequestThrottledException;
import com.android.internal.widget.TextViewInputDisabler;
import com.android.systemui.R;
@@ -64,6 +66,10 @@
private Interpolator mLinearOutSlowInInterpolator;
private Interpolator mFastOutLinearInInterpolator;
+ private final boolean quickUnlock = (Settings.System.getIntForUser(getContext().getContentResolver(),
+ Settings.System.LOCKSCREEN_QUICK_UNLOCK_CONTROL, 0, UserHandle.USER_CURRENT) == 1);
+ private final int userId = KeyguardUpdateMonitor.getCurrentUser();
+
public KeyguardPasswordView(Context context) {
this(context, null);
}
@@ -362,6 +368,15 @@
// is from the user.
if (!TextUtils.isEmpty(s)) {
onUserInput();
+ if (quickUnlock) {
+ LockscreenCredential entry = getEnteredCredential();
+ if (entry.size() > MINIMUM_PASSWORD_LENGTH_BEFORE_REPORT
+ && kpvCheckPassword(entry)) {
+ mCallback.reportUnlockAttempt(userId, true, 0);
+ mCallback.dismiss(true, userId);
+ resetPasswordText(true, true);
+ }
+ }
}
}
@@ -387,4 +402,12 @@
return getContext().getString(
com.android.internal.R.string.keyguard_accessibility_password_unlock);
}
+
+ private boolean kpvCheckPassword(LockscreenCredential entry) {
+ try {
+ return mLockPatternUtils.checkCredential(entry, userId, null);
+ } catch (RequestThrottledException ex) {
+ return false;
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
index c4a9fcb..6b79b24 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
@@ -349,6 +349,7 @@
boolean isValidPattern) {
boolean dismissKeyguard = KeyguardUpdateMonitor.getCurrentUser() == userId;
if (matched) {
+ mLockPatternUtils.sanitizePassword();
mCallback.reportUnlockAttempt(userId, true, 0);
if (dismissKeyguard) {
mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Correct);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 1db2e32..0daafe1 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -33,6 +33,7 @@
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
import android.graphics.Insets;
import android.graphics.Rect;
@@ -124,6 +125,7 @@
private InjectionInflationController mInjectionInflationController;
private boolean mSwipeUpToRetry;
private AdminSecondaryLockScreenController mSecondaryLockScreenController;
+ private boolean mHasFod;
private final ViewConfiguration mViewConfiguration;
private final SpringAnimation mSpringAnimation;
@@ -261,6 +263,10 @@
mKeyguardStateController = Dependency.get(KeyguardStateController.class);
mSecondaryLockScreenController = new AdminSecondaryLockScreenController(context, this,
mUpdateMonitor, mCallback, new Handler(Looper.myLooper()));
+
+ PackageManager packageManager = mContext.getPackageManager();
+ mHasFod = context.getResources().getBoolean(
+ com.android.internal.R.bool.config_needCustomFODView);
}
public void setSecurityCallback(SecurityCallback callback) {
@@ -517,6 +523,10 @@
// Consume bottom insets because we're setting the padding locally (for IME and navbar.)
int inset;
+ int minBottomMargin = mHasFod && mUpdateMonitor.isFingerprintDetectionRunning() ?
+ getResources().getDimensionPixelSize(
+ R.dimen.kg_security_container_min_bottom_margin) : 0;
+
if (sNewInsetsMode == NEW_INSETS_MODE_FULL) {
int bottomInset = insets.getInsetsIgnoringVisibility(systemBars()).bottom;
int imeInset = insets.getInsets(ime()).bottom;
@@ -524,7 +534,8 @@
} else {
inset = insets.getSystemWindowInsetBottom();
}
- setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(), inset);
+ setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(),
+ minBottomMargin > inset ? minBottomMargin : inset);
return insets.inset(0, 0, 0, inset);
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
index 76adf04..5ced99f 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java
@@ -215,6 +215,7 @@
((EmergencyCarrierArea) mEcaView).setCarrierTextVisible(true);
}
mSimImageView = findViewById(R.id.keyguard_sim);
+ mPasswordEntry.setQuickUnlockListener(null);
}
@Override
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
index a84664c..11f40f4 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
@@ -272,6 +272,7 @@
((EmergencyCarrierArea) mEcaView).setCarrierTextVisible(true);
}
mSimImageView = findViewById(R.id.keyguard_sim);
+ mPasswordEntry.setQuickUnlockListener(null);
}
@Override
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
index f639c88..f311e7a 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
@@ -188,7 +188,15 @@
@Override
public void onVisibilityAggregated(boolean isVisible) {
super.onVisibilityAggregated(isVisible);
- setLayoutTransition(isVisible ? mLayoutTransition : null);
+ setLayoutTransition(null);
+ }
+
+ public void setRowGravity(int gravity) {
+ mRow.setGravity(gravity);
+ }
+
+ public void setRowPadding(int left, int top, int right, int bottom) {
+ mRow.setPadding(left, top, right, bottom);
}
/**
@@ -325,10 +333,14 @@
@Override
public void onClick(View v) {
- final PendingIntent action = mClickActions.get(v);
+ /*final PendingIntent action = mClickActions.get(v);
if (action != null) {
mActivityStarter.startPendingIntentDismissingKeyguard(action);
- }
+ }*/ //not being used by aosp actually for any slice - see KeyguardSliceProvider.addPrimaryActionLocked
+ }
+
+ public View getTitleView() {
+ return mTitle;
}
/**
@@ -492,7 +504,7 @@
@Override
public void onVisibilityAggregated(boolean isVisible) {
super.onVisibilityAggregated(isVisible);
- setLayoutTransition(isVisible ? mLayoutTransition : null);
+ setLayoutTransition(null);
}
@Override
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index 5a1c997..0acd940 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -18,18 +18,21 @@
import android.app.ActivityManager;
import android.app.IActivityManager;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
import android.os.Handler;
import android.os.RemoteException;
import android.os.UserHandle;
+import android.provider.Settings;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Slog;
import android.util.TypedValue;
+import android.view.Gravity;
import android.view.View;
import android.widget.GridLayout;
import android.widget.LinearLayout;
@@ -145,6 +148,10 @@
return mClockView.hasCustomClock();
}
+ public boolean hasCustomClockInBigContainer() {
+ return mClockView.hasCustomClockInBigContainer();
+ }
+
/**
* Set whether or not the lock screen is showing notifications.
*/
@@ -188,9 +195,6 @@
mClockView = findViewById(R.id.keyguard_clock_container);
mClockView.setShowCurrentUserTime(true);
- if (KeyguardClockAccessibilityDelegate.isNeeded(mContext)) {
- mClockView.setAccessibilityDelegate(new KeyguardClockAccessibilityDelegate(mContext));
- }
mOwnerInfo = findViewById(R.id.owner_info);
mKeyguardSlice = findViewById(R.id.keyguard_status_area);
mTextColor = mClockView.getCurrentTextColor();
@@ -206,6 +210,10 @@
updateDark();
}
+ public KeyguardSliceView getKeyguardSliceView() {
+ return mKeyguardSlice;
+ }
+
/**
* Moves clock, adjusting margins when slice content changes.
*/
@@ -300,6 +308,21 @@
if (mOwnerInfo == null) return;
String info = mLockPatternUtils.getDeviceOwnerInfo();
if (info == null) {
+ final ContentResolver resolver = mContext.getContentResolver();
+ String currentClock = Settings.Secure.getString(
+ resolver, Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE);
+ boolean mClockSelection = currentClock == null ? false : currentClock.contains("Type");
+
+ // If text style clock, align the textView to start else keep it center.
+ if (mClockSelection) {
+ mOwnerInfo.setPaddingRelative((int) mContext.getResources()
+ .getDimension(R.dimen.custom_clock_left_padding) + 8, 0, 0, 0);
+ mOwnerInfo.setGravity(Gravity.START);
+ } else {
+ mOwnerInfo.setPaddingRelative(0, 0, 0, 0);
+ mOwnerInfo.setGravity(Gravity.CENTER);
+ }
+
// Use the current user owner information if enabled.
final boolean ownerInfoEnabled = mLockPatternUtils.isOwnerInfoEnabled(
KeyguardUpdateMonitor.getCurrentUser());
@@ -378,10 +401,6 @@
clockView24 = DateFormat.getBestDateTimePattern(locale, clockView24Skel);
- // Use fancy colon.
- clockView24 = clockView24.replace(':', '\uee01');
- clockView12 = clockView12.replace(':', '\uee01');
-
cacheKey = key;
}
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 60cd240..0976284 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -1280,7 +1280,7 @@
@Override
public void onAuthenticationError(int errMsgId, CharSequence errString) {
- handleFingerprintError(errMsgId, errString.toString());
+ handleFingerprintError(errMsgId, errString != null ? errString.toString() : "");
}
@Override
@@ -1696,7 +1696,7 @@
}
// 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);
+ mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0, 0, 0, 0, 0, false, false, false);
// Watch for interesting updates
final IntentFilter filter = new IntentFilter();
@@ -2574,8 +2574,16 @@
return true;
}
+ // change in battery temperature
+ if (old.temperature != current.temperature) {
+ return true;
+ }
+
// change in charging current while plugged in
- if (nowPluggedIn && current.maxChargingWattage != old.maxChargingWattage) {
+ if (nowPluggedIn &&
+ (current.maxChargingWattage != old.maxChargingWattage ||
+ current.maxChargingCurrent != old.maxChargingCurrent ||
+ current.maxChargingVoltage != old.maxChargingVoltage)) {
return true;
}
@@ -2584,6 +2592,21 @@
return true;
}
+ // change in dash charging while plugged in
+ if (nowPluggedIn && current.dashChargeStatus != old.dashChargeStatus) {
+ return true;
+ }
+
+ // change in warp charging while plugged in
+ if (nowPluggedIn && current.warpChargeStatus != old.warpChargeStatus) {
+ return true;
+ }
+
+ // change in VOOC charging while plugged in
+ if (nowPluggedIn && current.voocChargeStatus != old.voocChargeStatus) {
+ return true;
+ }
+
return false;
}
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
index b0457fc..c565312 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
@@ -20,6 +20,7 @@
import android.content.res.TypedArray;
import android.os.PowerManager;
import android.os.SystemClock;
+import android.provider.Settings;
import android.util.AttributeSet;
import android.view.HapticFeedbackConstants;
import android.view.LayoutInflater;
@@ -102,21 +103,7 @@
mDigitText.setText(Integer.toString(mDigit));
mKlondikeText = (TextView) findViewById(R.id.klondike_text);
- if (mDigit >= 0) {
- if (sKlondike == null) {
- sKlondike = getResources().getStringArray(R.array.lockscreen_num_pad_klondike);
- }
- if (sKlondike != null && sKlondike.length > mDigit) {
- String klondike = sKlondike[mDigit];
- final int len = klondike.length();
- if (len > 0) {
- mKlondikeText.setText(klondike);
- } else {
- mKlondikeText.setVisibility(View.INVISIBLE);
- }
- }
- }
-
+ updateText();
a = context.obtainStyledAttributes(attrs, android.R.styleable.View);
if (!a.hasValueOrEmpty(android.R.styleable.View_background)) {
setBackground(mContext.getDrawable(R.drawable.ripple_drawable_pin));
@@ -125,6 +112,31 @@
setContentDescription(mDigitText.getText().toString());
}
+ public void setDigit(int digit) {
+ mDigit = digit;
+ updateText();
+ }
+
+ private void updateText() {
+ boolean scramblePin = (Settings.System.getInt(getContext().getContentResolver(),
+ Settings.System.LOCKSCREEN_PIN_SCRAMBLE_LAYOUT, 0) == 1);
+ if (mDigit >= 0) {
+ mDigitText.setText(Integer.toString(mDigit));
+ if (sKlondike == null) {
+ sKlondike = getResources().getStringArray(R.array.lockscreen_num_pad_klondike);
+ }
+ if (sKlondike != null && sKlondike.length > mDigit) {
+ String klondike = sKlondike[mDigit];
+ final int len = klondike.length();
+ if (len > 0 || scramblePin) {
+ mKlondikeText.setText(klondike);
+ } else {
+ mKlondikeText.setVisibility(View.INVISIBLE);
+ }
+ }
+ }
+ }
+
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
diff --git a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
index c92174a..e50bc5b 100644
--- a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
+++ b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
@@ -100,11 +100,25 @@
private Interpolator mFastOutSlowInInterpolator;
private boolean mShowPassword;
private UserActivityListener mUserActivityListener;
+ protected QuickUnlockListener mQuickUnlockListener;
public interface UserActivityListener {
void onUserActivity();
}
+ /* Quick unlock management for PIN view. */
+ public interface QuickUnlockListener {
+ /**
+ * Validate current password and prepare callback if verified.
+ * @param password The password string to be verified.
+ */
+ void onValidateQuickUnlock(String password);
+ }
+
+ public void setQuickUnlockListener(QuickUnlockListener listener) {
+ mQuickUnlockListener = listener;
+ }
+
public PasswordTextView(Context context) {
this(context, null);
}
@@ -237,6 +251,10 @@
}
userActivity();
sendAccessibilityEventTypeViewTextChanged(textbefore, textbefore.length(), 0, 1);
+
+ if (mQuickUnlockListener != null) {
+ mQuickUnlockListener.onValidateQuickUnlock(mText);
+ }
}
public void setUserActivityListener(UserActivityListener userActivitiListener) {
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java
index 99e122e..83eb2b5 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java
@@ -23,8 +23,11 @@
import android.graphics.Paint.Style;
import android.view.LayoutInflater;
import android.view.View;
+import android.widget.FrameLayout;
import android.widget.TextClock;
+import androidx.core.graphics.ColorUtils;
+
import com.android.internal.colorextraction.ColorExtractor;
import com.android.systemui.R;
import com.android.systemui.colorextraction.SysuiColorExtractor;
@@ -53,11 +56,6 @@
private final SysuiColorExtractor mColorExtractor;
/**
- * Computes preferred position of clock.
- */
- private final SmallClockPosition mClockPosition;
-
- /**
* Renders preview from clock view.
*/
private final ViewPreviewer mRenderer = new ViewPreviewer();
@@ -68,19 +66,12 @@
private ClockLayout mBigClockView;
private ImageClock mAnalogClock;
- /**
- * Small clock shown on lock screen above stack scroller.
- */
- private View mView;
- private TextClock mLockClock;
+ private int mHourColor;
+ private int mMinuteColor;
+ private int mBackgroundColor;
/**
- * Helper to extract colors from wallpaper palette for clock face.
- */
- private final ClockPalette mPalette = new ClockPalette();
-
- /**
- * Create a BubbleClockController instance.
+ * Create a AnalogClockController instance.
*
* @param res Resources contains title and thumbnail.
* @param inflater Inflater used to inflate custom clock views.
@@ -91,23 +82,21 @@
mResources = res;
mLayoutInflater = inflater;
mColorExtractor = colorExtractor;
- mClockPosition = new SmallClockPosition(res);
}
private void createViews() {
mBigClockView = (ClockLayout) mLayoutInflater.inflate(R.layout.analog_clock, null);
mAnalogClock = mBigClockView.findViewById(R.id.analog_clock);
-
- mView = mLayoutInflater.inflate(R.layout.digital_clock, null);
- mLockClock = mView.findViewById(R.id.lock_screen_clock);
+ mHourColor = mResources.getColor(R.color.analog_clock_hour_color);
+ mMinuteColor = mResources.getColor(R.color.analog_clock_minute_color);
+ mBackgroundColor = mResources.getColor(R.color.analog_clock_bg_color);
+ mAnalogClock.setClockColors(mHourColor, mMinuteColor);
}
@Override
public void onDestroyView() {
mBigClockView = null;
mAnalogClock = null;
- mView = null;
- mLockClock = null;
}
@Override
@@ -127,27 +116,19 @@
@Override
public Bitmap getPreview(int width, int height) {
-
- // Use the big clock view for the preview
- View view = getBigClockView();
-
- // Initialize state of plugin before generating preview.
- setDarkAmount(1f);
- setTextColor(Color.WHITE);
- ColorExtractor.GradientColors colors = mColorExtractor.getColors(
- WallpaperManager.FLAG_LOCK);
- setColorPalette(colors.supportsDarkText(), colors.getColorPalette());
- onTimeTick();
-
- return mRenderer.createPreview(view, width, height);
+ View previewClock = mLayoutInflater.inflate(R.layout.analog_clock_preview, null);
+ ImageClock analogClock = previewClock.findViewById(R.id.analog_clock);
+ analogClock.setClockColors(Color.WHITE, Color.WHITE);
+ analogClock.setBackgroundResource(R.drawable.analog_clock_background_dark);
+ analogClock.onTimeChanged();
+ TextClock textDate = previewClock.findViewById(R.id.date);
+ textDate.setTextColor(Color.WHITE);
+ return mRenderer.createPreview(previewClock, width, height);
}
@Override
public View getView() {
- if (mView == null) {
- createViews();
- }
- return mView;
+ return null;
}
@Override
@@ -160,41 +141,34 @@
@Override
public int getPreferredY(int totalHeight) {
- return mClockPosition.getPreferredY();
+ return totalHeight / 2;
}
@Override
- public void setStyle(Style style) {}
-
- @Override
public void setTextColor(int color) {
- updateColor();
}
@Override
public void setColorPalette(boolean supportsDarkText, int[] colorPalette) {
- mPalette.setColorPalette(supportsDarkText, colorPalette);
- updateColor();
- }
-
- private void updateColor() {
- final int primary = mPalette.getPrimaryColor();
- final int secondary = mPalette.getSecondaryColor();
- mLockClock.setTextColor(secondary);
- mAnalogClock.setClockColors(primary, secondary);
}
@Override
public void onTimeTick() {
mAnalogClock.onTimeChanged();
mBigClockView.onTimeChanged();
- mLockClock.refreshTime();
}
@Override
public void setDarkAmount(float darkAmount) {
- mPalette.setDarkAmount(darkAmount);
- mClockPosition.setDarkAmount(darkAmount);
+ int hourColor = ColorUtils.blendARGB(mHourColor, Color.WHITE, darkAmount);
+ int minuteColor = ColorUtils.blendARGB(mMinuteColor, Color.WHITE, darkAmount);
+ if (darkAmount == 1f) {
+ mAnalogClock.setBackgroundResource(R.drawable.analog_clock_background_dark);
+ } else {
+ mAnalogClock.setBackgroundResource(R.drawable.analog_clock_background);
+ }
+
+ mAnalogClock.setClockColors(hourColor, minuteColor);
mBigClockView.setDarkAmount(darkAmount);
}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/BinaryClock.java b/packages/SystemUI/src/com/android/keyguard/clock/BinaryClock.java
new file mode 100644
index 0000000..c95a19a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/clock/BinaryClock.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2018-2019 The OmniROM 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.keyguard.clock;
+
+import android.app.ActivityManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.text.format.DateFormat;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+
+import com.android.systemui.R;
+
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.TimeZone;
+
+public class BinaryClock extends View {
+ private static final String TAG = "BinaryClock";
+ private final Calendar mCalendar = Calendar.getInstance(TimeZone.getDefault());
+ private int mMinutes;
+ private int mHour;
+ private Paint mDotPaint;
+ private Paint mEmptyDotPaint;
+ private Paint mAmbientDotPaint;
+ private Paint mAmbienEmptyDotPaint;
+ private boolean mIsAmbientDisplay;
+ private int mDotSize;
+ private int[][] mDots = new int[4][4];
+ private TimeZone mTimeZone;
+ private String mDescFormat;
+
+ public BinaryClock(Context context) {
+ this(context, null);
+ }
+
+ public BinaryClock(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public BinaryClock(Context context, AttributeSet attrs,
+ int defStyle) {
+ super(context, attrs, defStyle);
+ Resources r = context.getResources();
+
+ mDotPaint = new Paint();
+ mDotPaint.setAntiAlias(true);
+ mDotPaint.setStyle(Paint.Style.FILL);
+ mDotPaint.setColor(r.getColor(R.color.binary_clock_dot_color));
+
+ mEmptyDotPaint = new Paint();
+ mEmptyDotPaint.setAntiAlias(true);
+ mEmptyDotPaint.setStyle(Paint.Style.STROKE);
+ mEmptyDotPaint.setColor(r.getColor(R.color.binary_clock_empty_dot_color));
+
+ mAmbientDotPaint = new Paint();
+ mAmbientDotPaint.setAntiAlias(true);
+ mAmbientDotPaint.setStyle(Paint.Style.FILL);
+ mAmbientDotPaint.setColor(r.getColor(R.color.binary_clock_ambient_dot_color));
+
+ mAmbienEmptyDotPaint = new Paint();
+ mAmbienEmptyDotPaint.setAntiAlias(true);
+ mAmbienEmptyDotPaint.setStyle(Paint.Style.STROKE);
+ mAmbienEmptyDotPaint.setColor(r.getColor(R.color.binary_clock_ambient_empty_dot_color));
+
+ mDescFormat = ((SimpleDateFormat) DateFormat.getTimeFormat(context)).toLocalizedPattern();
+
+ onDensityOrFontScaleChanged();
+ }
+
+ public void onDensityOrFontScaleChanged() {
+ Resources r = getContext().getResources();
+ mDotSize = r.getDimensionPixelSize(R.dimen.binary_clock_dot_size);
+ mDotPaint.setStrokeWidth(r.getDimensionPixelSize(R.dimen.binary_clock_stroke_width));
+ mEmptyDotPaint.setStrokeWidth(r.getDimensionPixelSize(R.dimen.binary_clock_stroke_width));
+ mAmbientDotPaint.setStrokeWidth(r.getDimensionPixelSize(R.dimen.binary_clock_stroke_width));
+ mAmbienEmptyDotPaint.setStrokeWidth(r.getDimensionPixelSize(R.dimen.binary_clock_stroke_width));
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ mCalendar.setTimeZone(mTimeZone != null ? mTimeZone : TimeZone.getDefault());
+ onTimeChanged();
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+
+ int availableWidth = getWidth();
+ int cellWidth = availableWidth / 4;
+ int availableHeight = getHeight();
+ int cellHeight = availableHeight / 4;
+
+ int yLine = cellHeight / 2;
+
+ for (int y = 3; y >= 0 ; y--) {
+ int xLine = cellWidth / 2;
+ for (int x = 0; x < 4; x++) {
+ if (y >= 2 && x == 0) {
+ xLine += cellWidth;
+ continue;
+ }
+ if (mDots[x][y] == 1) {
+ canvas.drawCircle(xLine, yLine, mDotSize, mIsAmbientDisplay ? mAmbientDotPaint : mDotPaint);
+ } else {
+ canvas.drawCircle(xLine, yLine, mDotSize, mIsAmbientDisplay ? mAmbienEmptyDotPaint : mEmptyDotPaint);
+ }
+ xLine += cellWidth;
+ }
+ yLine += cellHeight;
+ }
+ }
+
+
+ private void calculateDotMatrix() {
+ int hour0 = (int) (mHour >= 10 ? mHour / 10 : 0);
+ int hour1 = (int) (mHour - hour0 * 10);
+ int minute0 = (int) (mMinutes >= 10 ? mMinutes / 10 : 0);
+ int minute1 = (int) (mMinutes - minute0 * 10);
+
+ mDots = new int[4][4];
+ if (hour0 != 0) {
+ String hour0Bin = Integer.toBinaryString(hour0);
+ for (int i = 0; i < hour0Bin.length(); i++) {
+ mDots[0][hour0Bin.length() - 1 - i] = hour0Bin.charAt(i) == '1' ? 1 : 0;
+ }
+ }
+ if (hour1 != 0) {
+ String hour1Bin = Integer.toBinaryString(hour1);
+ for (int i = 0; i < hour1Bin.length(); i++) {
+ mDots[1][hour1Bin.length() - 1 - i] = hour1Bin.charAt(i) == '1' ? 1 : 0;
+ }
+ }
+ if (minute0 != 0) {
+ String minute0Bin = Integer.toBinaryString(minute0);
+ for (int i = 0; i < minute0Bin.length(); i++) {
+ mDots[2][minute0Bin.length() - 1 - i] = minute0Bin.charAt(i) == '1' ? 1 : 0;
+ }
+ }
+ if (minute1 != 0) {
+ String minute1Bin = Integer.toBinaryString(minute1);
+ for (int i = 0; i < minute1Bin.length(); i++) {
+ mDots[3][minute1Bin.length() - 1 - i] = minute1Bin.charAt(i) == '1' ? 1 : 0;
+ }
+ }
+ }
+
+ public void onTimeChanged() {
+ mCalendar.setTimeInMillis(System.currentTimeMillis());
+ final boolean is24 = DateFormat.is24HourFormat(getContext(), ActivityManager.getCurrentUser());
+ mHour = mCalendar.get(is24 ? Calendar.HOUR_OF_DAY : Calendar.HOUR);
+ mMinutes = mCalendar.get(Calendar.MINUTE);
+ setContentDescription(DateFormat.format(mDescFormat, mCalendar));
+ calculateDotMatrix();
+ invalidate();
+ }
+
+ public void onTimeZoneChanged(TimeZone timeZone) {
+ mTimeZone = timeZone;
+ mCalendar.setTimeZone(timeZone);
+ }
+
+ public void setDark(boolean dark) {
+ if (mIsAmbientDisplay != dark) {
+ mIsAmbientDisplay = dark;
+ invalidate();
+ }
+ }
+
+ public void setTintColor(int color) {
+ mDotPaint.setColor(color);
+ mEmptyDotPaint.setColor(color);
+ invalidate();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/BinaryClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/BinaryClockController.java
new file mode 100644
index 0000000..095b920
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/clock/BinaryClockController.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.keyguard.clock;
+
+import android.app.WallpaperManager;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.graphics.Paint.Style;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextClock;
+
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.systemui.R;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.plugins.ClockPlugin;
+
+import java.util.TimeZone;
+
+/**
+ * Controller for binary clock that can appear on lock screen and AOD.
+ */
+public class BinaryClockController implements ClockPlugin {
+
+ /**
+ * Resources used to get title and thumbnail.
+ */
+ private final Resources mResources;
+
+ /**
+ * LayoutInflater used to inflate custom clock views.
+ */
+ private final LayoutInflater mLayoutInflater;
+
+ /**
+ * Extracts accent color from wallpaper.
+ */
+ private final SysuiColorExtractor mColorExtractor;
+
+ /**
+ * Renders preview from clock view.
+ */
+ private final ViewPreviewer mRenderer = new ViewPreviewer();
+
+ /**
+ * Custom clock shown on AOD screen and behind stack scroller on lock.
+ */
+ private BinaryClock mBinaryClock;
+ private ClockLayout mBigClockView;
+
+ /**
+ * Create a BinaryClockController instance.
+ *
+ * @param res Resources contains title and thumbnail.
+ * @param inflater Inflater used to inflate custom clock views.
+ * @param colorExtractor Extracts accent color from wallpaper.
+ */
+ public BinaryClockController(Resources res, LayoutInflater inflater,
+ SysuiColorExtractor colorExtractor) {
+ mResources = res;
+ mLayoutInflater = inflater;
+ mColorExtractor = colorExtractor;
+ }
+
+ private void createViews() {
+ mBigClockView = (ClockLayout) mLayoutInflater.inflate(R.layout.binary_clock, null);
+ mBinaryClock = mBigClockView.findViewById(R.id.binary_clock);
+ }
+
+ @Override
+ public void onDestroyView() {
+ mBigClockView = null;
+ mBinaryClock = null;
+ }
+
+ @Override
+ public String getName() {
+ return "binary";
+ }
+
+ @Override
+ public String getTitle() {
+ return mResources.getString(R.string.clock_title_binary);
+ }
+
+ @Override
+ public Bitmap getThumbnail() {
+ return BitmapFactory.decodeResource(mResources, R.drawable.binary_thumbnail);
+ }
+
+ @Override
+ public Bitmap getPreview(int width, int height) {
+ View previewClock = mLayoutInflater.inflate(R.layout.binary_clock_preview, null);
+ BinaryClock binaryClock = previewClock.findViewById(R.id.binary_clock);
+ binaryClock.setDark(true);
+ binaryClock.onTimeChanged();
+ TextClock textDate = previewClock.findViewById(R.id.date);
+ textDate.setTextColor(Color.WHITE);
+ return mRenderer.createPreview(previewClock, width, height);
+ }
+
+ @Override
+ public View getView() {
+ return null;
+ }
+
+ @Override
+ public View getBigClockView() {
+ if (mBigClockView == null) {
+ createViews();
+ }
+ return mBigClockView;
+ }
+
+ @Override
+ public int getPreferredY(int totalHeight) {
+ return totalHeight / 2;
+ }
+
+ @Override
+ public void setTextColor(int color) {
+ mBinaryClock.setTintColor(color);
+ }
+
+ @Override
+ public void setColorPalette(boolean supportsDarkText, int[] colorPalette) {}
+
+ @Override
+ public void onTimeTick() {
+ mBinaryClock.onTimeChanged();
+ mBigClockView.onTimeChanged();
+ }
+
+ @Override
+ public void setDarkAmount(float darkAmount) {
+ mBigClockView.setDarkAmount(darkAmount);
+ boolean dark = darkAmount == 1;
+ mBinaryClock.setDark(dark);
+ }
+
+ @Override
+ public void onTimeZoneChanged(TimeZone timeZone) {
+ mBinaryClock.onTimeZoneChanged(timeZone);
+ }
+
+ @Override
+ public boolean shouldShowStatusArea() {
+ return true;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/BlissClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/BlissClockController.java
new file mode 100644
index 0000000..2e236d3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/clock/BlissClockController.java
@@ -0,0 +1,181 @@
+/*
+* Copyright (C) 2014-2020 The BlissRoms 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.keyguard.clock;
+
+import android.app.WallpaperManager;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.graphics.Paint.Style;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextClock;
+
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.systemui.R;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.plugins.ClockPlugin;
+
+import java.util.TimeZone;
+
+/**
+ * Controller for Stretch clock that can appear on lock screen and AOD.
+ */
+public class BlissClockController implements ClockPlugin {
+
+ /**
+ * Resources used to get title and thumbnail.
+ */
+ private final Resources mResources;
+
+ /**
+ * LayoutInflater used to inflate custom clock views.
+ */
+ private final LayoutInflater mLayoutInflater;
+
+ /**
+ * Extracts accent color from wallpaper.
+ */
+ private final SysuiColorExtractor mColorExtractor;
+
+ /**
+ * Renders preview from clock view.
+ */
+ private final ViewPreviewer mRenderer = new ViewPreviewer();
+
+ /**
+ * Custom clock shown on AOD screen and behind stack scroller on lock.
+ */
+ private ClockLayout mBigClockView;
+ private ImageClock mBlissClock;
+
+ /**
+ * Helper to extract colors from wallpaper palette for clock face.
+ */
+ private final ClockPalette mPalette = new ClockPalette();
+
+ /**
+ * Create a BubbleClockController instance.
+ *
+ * @param res Resources contains title and thumbnail.
+ * @param inflater Inflater used to inflate custom clock views.
+ * @param colorExtractor Extracts accent color from wallpaper.
+ */
+ public BlissClockController(Resources res, LayoutInflater inflater,
+ SysuiColorExtractor colorExtractor) {
+ mResources = res;
+ mLayoutInflater = inflater;
+ mColorExtractor = colorExtractor;
+ }
+
+ private void createViews() {
+ mBigClockView = (ClockLayout) mLayoutInflater.inflate(R.layout.bliss_clock, null);
+ mBlissClock = mBigClockView.findViewById(R.id.analog_clock);
+ }
+
+ @Override
+ public void onDestroyView() {
+ mBigClockView = null;
+ mBlissClock = null;
+ }
+
+ @Override
+ public String getName() {
+ return "Bliss";
+ }
+
+ @Override
+ public String getTitle() {
+ return mResources.getString(R.string.clock_title_bliss);
+ }
+
+ @Override
+ public Bitmap getThumbnail() {
+ return BitmapFactory.decodeResource(mResources, R.drawable.bliss_thumbnail);
+ }
+
+ @Override
+ public Bitmap getPreview(int width, int height) {
+
+ // Use the big clock view for the preview
+ View view = getBigClockView();
+
+ // Initialize state of plugin before generating preview.
+ setDarkAmount(1f);
+ setTextColor(Color.WHITE);
+ ColorExtractor.GradientColors colors = mColorExtractor.getColors(
+ WallpaperManager.FLAG_LOCK);
+ setColorPalette(colors.supportsDarkText(), colors.getColorPalette());
+ onTimeTick();
+
+ return mRenderer.createPreview(view, width, height);
+ }
+
+ @Override
+ public View getView() {
+ return null;
+ }
+
+ @Override
+ public View getBigClockView() {
+ if (mBigClockView == null) {
+ createViews();
+ }
+ return mBigClockView;
+ }
+
+ @Override
+ public int getPreferredY(int totalHeight) {
+ return totalHeight / 2;
+ }
+
+ @Override
+ public void setTextColor(int color) {
+ updateColor();
+ }
+
+ @Override
+ public void setColorPalette(boolean supportsDarkText, int[] colorPalette) {
+ mPalette.setColorPalette(supportsDarkText, colorPalette);
+ updateColor();
+ }
+
+ private void updateColor() {
+ final int primary = mPalette.getPrimaryColor();
+ final int secondary = mPalette.getSecondaryColor();
+ //mBlissClock.setClockColors(primary, secondary);
+ }
+
+ @Override
+ public void onTimeTick() {
+ mBlissClock.onTimeChanged();
+ mBigClockView.onTimeChanged();
+ }
+
+ @Override
+ public void setDarkAmount(float darkAmount) {
+ mPalette.setDarkAmount(darkAmount);
+ mBigClockView.setDarkAmount(darkAmount);
+ }
+
+ @Override
+ public void onTimeZoneChanged(TimeZone timeZone) {
+ mBlissClock.onTimeZoneChanged(timeZone);
+ }
+
+ @Override
+ public boolean shouldShowStatusArea() {
+ return true;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java
deleted file mode 100644
index fac923c01..0000000
--- a/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.keyguard.clock;
-
-import android.app.WallpaperManager;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Color;
-import android.graphics.Paint.Style;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.TextClock;
-
-import com.android.internal.colorextraction.ColorExtractor;
-import com.android.systemui.R;
-import com.android.systemui.colorextraction.SysuiColorExtractor;
-import com.android.systemui.plugins.ClockPlugin;
-
-import java.util.TimeZone;
-
-/**
- * Controller for Bubble clock that can appear on lock screen and AOD.
- */
-public class BubbleClockController implements ClockPlugin {
-
- /**
- * Resources used to get title and thumbnail.
- */
- private final Resources mResources;
-
- /**
- * LayoutInflater used to inflate custom clock views.
- */
- private final LayoutInflater mLayoutInflater;
-
- /**
- * Extracts accent color from wallpaper.
- */
- private final SysuiColorExtractor mColorExtractor;
-
- /**
- * Computes preferred position of clock.
- */
- private final SmallClockPosition mClockPosition;
-
- /**
- * Renders preview from clock view.
- */
- private final ViewPreviewer mRenderer = new ViewPreviewer();
-
- /**
- * Custom clock shown on AOD screen and behind stack scroller on lock.
- */
- private ClockLayout mView;
- private ImageClock mAnalogClock;
-
- /**
- * Small clock shown on lock screen above stack scroller.
- */
- private View mLockClockContainer;
- private TextClock mLockClock;
-
- /**
- * Helper to extract colors from wallpaper palette for clock face.
- */
- private final ClockPalette mPalette = new ClockPalette();
-
- /**
- * Create a BubbleClockController instance.
- *
- * @param res Resources contains title and thumbnail.
- * @param inflater Inflater used to inflate custom clock views.
- * @param colorExtractor Extracts accent color from wallpaper.
- */
- public BubbleClockController(Resources res, LayoutInflater inflater,
- SysuiColorExtractor colorExtractor) {
- mResources = res;
- mLayoutInflater = inflater;
- mColorExtractor = colorExtractor;
- mClockPosition = new SmallClockPosition(res);
- }
-
- private void createViews() {
- mView = (ClockLayout) mLayoutInflater.inflate(R.layout.bubble_clock, null);
- mAnalogClock = (ImageClock) mView.findViewById(R.id.analog_clock);
-
- mLockClockContainer = mLayoutInflater.inflate(R.layout.digital_clock, null);
- mLockClock = (TextClock) mLockClockContainer.findViewById(R.id.lock_screen_clock);
- }
-
- @Override
- public void onDestroyView() {
- mView = null;
- mAnalogClock = null;
- mLockClockContainer = null;
- mLockClock = null;
- }
-
- @Override
- public String getName() {
- return "bubble";
- }
-
- @Override
- public String getTitle() {
- return mResources.getString(R.string.clock_title_bubble);
- }
-
- @Override
- public Bitmap getThumbnail() {
- return BitmapFactory.decodeResource(mResources, R.drawable.bubble_thumbnail);
- }
-
- @Override
- public Bitmap getPreview(int width, int height) {
-
- // Use the big clock view for the preview
- View view = getBigClockView();
-
- // Initialize state of plugin before generating preview.
- setDarkAmount(1f);
- setTextColor(Color.WHITE);
- ColorExtractor.GradientColors colors = mColorExtractor.getColors(
- WallpaperManager.FLAG_LOCK);
- setColorPalette(colors.supportsDarkText(), colors.getColorPalette());
- onTimeTick();
-
- return mRenderer.createPreview(view, width, height);
- }
-
- @Override
- public View getView() {
- if (mLockClockContainer == null) {
- createViews();
- }
- return mLockClockContainer;
- }
-
- @Override
- public View getBigClockView() {
- if (mView == null) {
- createViews();
- }
- return mView;
- }
-
- @Override
- public int getPreferredY(int totalHeight) {
- return mClockPosition.getPreferredY();
- }
-
- @Override
- public void setStyle(Style style) {}
-
- @Override
- public void setTextColor(int color) {
- updateColor();
- }
-
- @Override
- public void setColorPalette(boolean supportsDarkText, int[] colorPalette) {
- mPalette.setColorPalette(supportsDarkText, colorPalette);
- updateColor();
- }
-
- private void updateColor() {
- final int primary = mPalette.getPrimaryColor();
- final int secondary = mPalette.getSecondaryColor();
- mLockClock.setTextColor(secondary);
- mAnalogClock.setClockColors(primary, secondary);
- }
-
- @Override
- public void setDarkAmount(float darkAmount) {
- mPalette.setDarkAmount(darkAmount);
- mClockPosition.setDarkAmount(darkAmount);
- mView.setDarkAmount(darkAmount);
- }
-
- @Override
- public void onTimeTick() {
- mAnalogClock.onTimeChanged();
- mView.onTimeChanged();
- mLockClock.refreshTime();
- }
-
- @Override
- public void onTimeZoneChanged(TimeZone timeZone) {
- mAnalogClock.onTimeZoneChanged(timeZone);
- }
-
- @Override
- public boolean shouldShowStatusArea() {
- return true;
- }
-}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java b/packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java
index d44d89e..d04b957 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java
@@ -37,6 +37,7 @@
* Clock face views.
*/
private View mAnalogClock;
+ private View mTypeClock;
/**
* Pixel shifting amplitudes used to prevent screen burn-in.
@@ -45,6 +46,7 @@
private int mBurnInPreventionOffsetY;
private float mDarkAmount;
+ private boolean mBurnInProtection;
public ClockLayout(Context context) {
this(context, null);
@@ -62,6 +64,7 @@
protected void onFinishInflate() {
super.onFinishInflate();
mAnalogClock = findViewById(R.id.analog_clock);
+ mTypeClock = findViewById(R.id.type_clock);
// Get pixel shifting X, Y amplitudes from resources.
Resources resources = getResources();
@@ -90,6 +93,9 @@
}
private void positionChildren() {
+ if (!mBurnInProtection || mAnalogClock == null) {
+ return;
+ }
final float offsetX = MathUtils.lerp(0f,
getBurnInOffset(mBurnInPreventionOffsetX * 2, true) - mBurnInPreventionOffsetX,
mDarkAmount);
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java b/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java
index 2200b22..c930174 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java
@@ -150,6 +150,27 @@
LayoutInflater layoutInflater = injectionInflater.injectable(LayoutInflater.from(context));
addBuiltinClock(() -> new DefaultClockController(res, layoutInflater, colorExtractor));
+ addBuiltinClock(() -> new DefaultBoldClockController(res, layoutInflater, colorExtractor));
+ addBuiltinClock(() -> new SamsungClockController(res, layoutInflater, colorExtractor));
+ addBuiltinClock(() -> new SamsungBoldClockController(res, layoutInflater, colorExtractor));
+ addBuiltinClock(() -> new AnalogClockController(res, layoutInflater, colorExtractor));
+ addBuiltinClock(() -> new SpideyClockController(res, layoutInflater, colorExtractor));
+ addBuiltinClock(() -> new SpectrumClockController(res, layoutInflater, colorExtractor));
+ addBuiltinClock(() -> new DotClockController(res, layoutInflater, colorExtractor));
+ addBuiltinClock(() -> new SneekyClockController(res, layoutInflater, colorExtractor));
+ addBuiltinClock(() -> new BlissClockController(res, layoutInflater, colorExtractor));
+ addBuiltinClock(() -> new CustomNumClockController(res, layoutInflater, colorExtractor));
+ addBuiltinClock(() -> new TypeClockController(res, layoutInflater, colorExtractor));
+ addBuiltinClock(() -> new BinaryClockController(res, layoutInflater, colorExtractor));
+ addBuiltinClock(() -> new DividedLinesClockController(res, layoutInflater, colorExtractor));
+ addBuiltinClock(() -> new SfunyClockController(res, layoutInflater, colorExtractor));
+ addBuiltinClock(() -> new MNMLBoxClockController(res, layoutInflater, colorExtractor));
+ addBuiltinClock(() -> new MNMLMinimalClockController(res, layoutInflater, colorExtractor));
+ addBuiltinClock(() -> new OPMinimalClockController(res, layoutInflater, colorExtractor));
+ addBuiltinClock(() -> new OPAnalogClockController(res, layoutInflater, colorExtractor));
+ addBuiltinClock(() -> new OPNumbersClockController(res, layoutInflater, colorExtractor));
+ addBuiltinClock(() -> new OPMinimalismClockController(res, layoutInflater, colorExtractor));
+ addBuiltinClock(() -> new OPRomanClockController(res, layoutInflater, colorExtractor));
// Store the size of the display for generation of clock preview.
DisplayMetrics dm = res.getDisplayMetrics();
@@ -327,7 +348,8 @@
.setTitle(plugin::getTitle)
.setId(id)
.setThumbnail(plugin::getThumbnail)
- .setPreview(() -> plugin.getPreview(mWidth, mHeight))
+ // to make the preview bigger in ThemePicker
+ .setPreview(() -> plugin.getPreview(mWidth * 2 / 5, mHeight * 2 / 5))
.build());
}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/CustomNumClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/CustomNumClockController.java
new file mode 100644
index 0000000..bf1b7e6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/clock/CustomNumClockController.java
@@ -0,0 +1,181 @@
+/*
+* Copyright (C) 2014-2020 The BlissRoms 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.keyguard.clock;
+
+import android.app.WallpaperManager;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.graphics.Paint.Style;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextClock;
+
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.systemui.R;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.plugins.ClockPlugin;
+
+import java.util.TimeZone;
+
+/**
+ * Controller for Stretch clock that can appear on lock screen and AOD.
+ */
+public class CustomNumClockController implements ClockPlugin {
+
+ /**
+ * Resources used to get title and thumbnail.
+ */
+ private final Resources mResources;
+
+ /**
+ * LayoutInflater used to inflate custom clock views.
+ */
+ private final LayoutInflater mLayoutInflater;
+
+ /**
+ * Extracts accent color from wallpaper.
+ */
+ private final SysuiColorExtractor mColorExtractor;
+
+ /**
+ * Renders preview from clock view.
+ */
+ private final ViewPreviewer mRenderer = new ViewPreviewer();
+
+ /**
+ * Custom clock shown on AOD screen and behind stack scroller on lock.
+ */
+ private ClockLayout mBigClockView;
+ private ImageClock mCustomNumClock;
+
+ /**
+ * Helper to extract colors from wallpaper palette for clock face.
+ */
+ private final ClockPalette mPalette = new ClockPalette();
+
+ /**
+ * Create a BubbleClockController instance.
+ *
+ * @param res Resources contains title and thumbnail.
+ * @param inflater Inflater used to inflate custom clock views.
+ * @param colorExtractor Extracts accent color from wallpaper.
+ */
+ public CustomNumClockController(Resources res, LayoutInflater inflater,
+ SysuiColorExtractor colorExtractor) {
+ mResources = res;
+ mLayoutInflater = inflater;
+ mColorExtractor = colorExtractor;
+ }
+
+ private void createViews() {
+ mBigClockView = (ClockLayout) mLayoutInflater.inflate(R.layout.custom_num_clock, null);
+ mCustomNumClock = mBigClockView.findViewById(R.id.analog_clock);
+ }
+
+ @Override
+ public void onDestroyView() {
+ mBigClockView = null;
+ mCustomNumClock = null;
+ }
+
+ @Override
+ public String getName() {
+ return "Custom-Num";
+ }
+
+ @Override
+ public String getTitle() {
+ return mResources.getString(R.string.clock_title_custom_num);
+ }
+
+ @Override
+ public Bitmap getThumbnail() {
+ return BitmapFactory.decodeResource(mResources, R.drawable.custom_num_clock_thumbnail);
+ }
+
+ @Override
+ public Bitmap getPreview(int width, int height) {
+
+ // Use the big clock view for the preview
+ View view = getBigClockView();
+
+ // Initialize state of plugin before generating preview.
+ setDarkAmount(1f);
+ setTextColor(Color.WHITE);
+ ColorExtractor.GradientColors colors = mColorExtractor.getColors(
+ WallpaperManager.FLAG_LOCK);
+ setColorPalette(colors.supportsDarkText(), colors.getColorPalette());
+ onTimeTick();
+
+ return mRenderer.createPreview(view, width, height);
+ }
+
+ @Override
+ public View getView() {
+ return null;
+ }
+
+ @Override
+ public View getBigClockView() {
+ if (mBigClockView == null) {
+ createViews();
+ }
+ return mBigClockView;
+ }
+
+ @Override
+ public int getPreferredY(int totalHeight) {
+ return totalHeight / 2;
+ }
+
+ @Override
+ public void setTextColor(int color) {
+ updateColor();
+ }
+
+ @Override
+ public void setColorPalette(boolean supportsDarkText, int[] colorPalette) {
+ mPalette.setColorPalette(supportsDarkText, colorPalette);
+ updateColor();
+ }
+
+ private void updateColor() {
+ final int primary = mPalette.getPrimaryColor();
+ final int secondary = mPalette.getSecondaryColor();
+ //mCustomNumClock.setClockColors(primary, secondary);
+ }
+
+ @Override
+ public void onTimeTick() {
+ mCustomNumClock.onTimeChanged();
+ mBigClockView.onTimeChanged();
+ }
+
+ @Override
+ public void setDarkAmount(float darkAmount) {
+ mPalette.setDarkAmount(darkAmount);
+ mBigClockView.setDarkAmount(darkAmount);
+ }
+
+ @Override
+ public void onTimeZoneChanged(TimeZone timeZone) {
+ mCustomNumClock.onTimeZoneChanged(timeZone);
+ }
+
+ @Override
+ public boolean shouldShowStatusArea() {
+ return true;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/DefaultBoldClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/DefaultBoldClockController.java
new file mode 100644
index 0000000..77b7e77
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/clock/DefaultBoldClockController.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.keyguard.clock;
+
+import android.app.WallpaperManager;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.graphics.Paint.Style;
+import android.text.Html;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextClock;
+
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.systemui.R;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.plugins.ClockPlugin;
+
+import java.util.TimeZone;
+
+import static com.android.systemui.statusbar.phone
+ .KeyguardClockPositionAlgorithm.CLOCK_USE_DEFAULT_Y;
+
+/**
+ * Plugin for the default clock face used only to provide a preview.
+ */
+public class DefaultBoldClockController implements ClockPlugin {
+
+ /**
+ * Resources used to get title and thumbnail.
+ */
+ private final Resources mResources;
+
+ /**
+ * LayoutInflater used to inflate custom clock views.
+ */
+ private final LayoutInflater mLayoutInflater;
+
+ /**
+ * Extracts accent color from wallpaper.
+ */
+ private final SysuiColorExtractor mColorExtractor;
+
+ /**
+ * Renders preview from clock view.
+ */
+ private final ViewPreviewer mRenderer = new ViewPreviewer();
+
+ /**
+ * Root view of clock.
+ */
+ private ClockLayout mView;
+
+ /**
+ * Text clock in preview view hierarchy.
+ */
+ private TextClock mClock;
+
+ /**
+ * Create a DefaultClockController instance.
+ *
+ * @param res Resources contains title and thumbnail.
+ * @param inflater Inflater used to inflate custom clock views.
+ * @param colorExtractor Extracts accent color from wallpaper.
+ */
+ public DefaultBoldClockController(Resources res, LayoutInflater inflater,
+ SysuiColorExtractor colorExtractor) {
+ mResources = res;
+ mLayoutInflater = inflater;
+ mColorExtractor = colorExtractor;
+ }
+
+ private void createViews() {
+ mView = (ClockLayout) mLayoutInflater
+ .inflate(R.layout.digital_clock_custom, null);
+ mClock = mView.findViewById(R.id.clock);
+ mClock.setFormat12Hour(Html.fromHtml("<strong>h</strong>:mm"));
+ mClock.setFormat24Hour(Html.fromHtml("<strong>kk</strong>:mm"));
+ }
+
+ @Override
+ public void onDestroyView() {
+ mView = null;
+ mClock = null;
+ }
+
+ @Override
+ public String getName() {
+ return "default_bold";
+ }
+
+ @Override
+ public String getTitle() {
+ return mResources.getString(R.string.clock_title_default_bold);
+ }
+
+ @Override
+ public Bitmap getThumbnail() {
+ return BitmapFactory.decodeResource(mResources, R.drawable.default_bold_thumbnail);
+ }
+
+ @Override
+ public Bitmap getPreview(int width, int height) {
+
+ View previewView = mLayoutInflater.inflate(R.layout.default_clock_preview, null);
+ TextClock previewTime = previewView.findViewById(R.id.time);
+ previewTime.setFormat12Hour(Html.fromHtml("<strong>h</strong>:mm"));
+ previewTime.setFormat24Hour(Html.fromHtml("<strong>kk</strong>:mm"));
+ TextClock previewDate = previewView.findViewById(R.id.date);
+
+ // Initialize state of plugin before generating preview.
+ previewTime.setTextColor(Color.WHITE);
+ previewDate.setTextColor(Color.WHITE);
+ ColorExtractor.GradientColors colors = mColorExtractor.getColors(
+ WallpaperManager.FLAG_LOCK);
+ setColorPalette(colors.supportsDarkText(), colors.getColorPalette());
+ onTimeTick();
+
+ return mRenderer.createPreview(previewView, width, height);
+ }
+
+ @Override
+ public View getView() {
+ if (mView == null) {
+ createViews();
+ }
+ return mView;
+ }
+
+ @Override
+ public View getBigClockView() {
+ return null;
+ }
+
+ @Override
+ public int getPreferredY(int totalHeight) {
+ return CLOCK_USE_DEFAULT_Y;
+ }
+
+ @Override
+ public void setStyle(Style style) {}
+
+ @Override
+ public void setTextColor(int color) {
+ mClock.setTextColor(color);
+ }
+
+ @Override
+ public void setColorPalette(boolean supportsDarkText, int[] colorPalette) {}
+
+ @Override
+ public void onTimeTick() {
+ mView.onTimeChanged();
+ mClock.refreshTime();
+ }
+
+ @Override
+ public void setDarkAmount(float darkAmount) {
+ mView.setDarkAmount(darkAmount);
+ }
+
+ @Override
+ public void onTimeZoneChanged(TimeZone timeZone) {}
+
+ @Override
+ public boolean shouldShowStatusArea() {
+ return true;
+ }
+
+ @Override
+ public boolean shouldShowInBigContainer() {
+ return true;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/DividedLinesClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/DividedLinesClockController.java
new file mode 100644
index 0000000..0384a50
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/clock/DividedLinesClockController.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 Projekt Spicy Future
+ * Copyright (C) 2020 Bootleggers ROM
+ *
+ * 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.keyguard.clock;
+
+import android.app.WallpaperManager;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.graphics.Paint.Style;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextClock;
+import android.widget.TextView;
+
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.systemui.R;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.plugins.ClockPlugin;
+
+import java.util.TimeZone;
+
+/**
+ * Plugin for the default clock face used only to provide a preview.
+ */
+public class DividedLinesClockController implements ClockPlugin {
+
+ /**
+ * Resources used to get title and thumbnail.
+ */
+ private final Resources mResources;
+
+ /**
+ * LayoutInflater used to inflate custom clock views.
+ */
+ private final LayoutInflater mLayoutInflater;
+
+ /**
+ * Extracts accent color from wallpaper.
+ */
+ private final SysuiColorExtractor mColorExtractor;
+
+ /**
+ * Renders preview from clock view.
+ */
+ private final ViewPreviewer mRenderer = new ViewPreviewer();
+
+ /**
+ * Root view of clock.
+ */
+ private ClockLayout mBigClockView;
+
+ /**
+ * Text clock in preview view hierarchy.
+ */
+ private TextClock mClock;
+
+ /**
+ * Text date in preview view hierarchy.
+ */
+ private TextClock mDate;
+
+ /**
+ * Top and bottom dividers in preview view hierarchy.
+ */
+ private View mTopLine;
+ private View mBottomLine;
+
+ /**
+ * Helper to extract colors from wallpaper palette for clock face.
+ */
+ private final ClockPalette mPalette = new ClockPalette();
+
+ /**
+ * Create a DefaultClockController instance.
+ *
+ * @param res Resources contains title and thumbnail.
+ * @param inflater Inflater used to inflate custom clock views.
+ * @param colorExtractor Extracts accent color from wallpaper.
+ */
+ public DividedLinesClockController(Resources res, LayoutInflater inflater,
+ SysuiColorExtractor colorExtractor) {
+ mResources = res;
+ mLayoutInflater = inflater;
+ mColorExtractor = colorExtractor;
+ }
+
+ private void createViews() {
+ mBigClockView = (ClockLayout) mLayoutInflater
+ .inflate(R.layout.divided_lines_clock, null);
+ mClock = mBigClockView.findViewById(R.id.clock);
+ mClock.setFormat12Hour("h:mm");
+ onTimeTick();
+ }
+
+ @Override
+ public void onDestroyView() {
+ mBigClockView = null;
+ mClock = null;
+ mDate = null;
+ mTopLine = null;
+ mBottomLine = null;
+ }
+
+ @Override
+ public String getName() {
+ return "dividedlines";
+ }
+
+ @Override
+ public String getTitle() {
+ return "Divided Lines";
+ }
+
+ @Override
+ public Bitmap getThumbnail() {
+ return BitmapFactory.decodeResource(mResources, R.drawable.divided_lines_thumbnail);
+ }
+
+ @Override
+ public Bitmap getPreview(int width, int height) {
+ View previewView = mLayoutInflater.inflate(R.layout.divided_lines_preview, null);
+ TextClock previewTime = previewView.findViewById(R.id.clock);
+ TextClock previewDate = previewView.findViewById(R.id.date);
+ View previewTLine = previewView.findViewById(R.id.topLine);
+ View previewBLine = previewView.findViewById(R.id.bottomLine);
+
+ // Initialize state of plugin before generating preview.
+ previewTime.setTextColor(Color.WHITE);
+ previewDate.setTextColor(Color.WHITE);
+ previewTLine.setBackgroundColor(Color.WHITE);
+ previewBLine.setBackgroundColor(Color.WHITE);
+ ColorExtractor.GradientColors colors = mColorExtractor.getColors(
+ WallpaperManager.FLAG_LOCK);
+ setColorPalette(colors.supportsDarkText(), colors.getColorPalette());
+
+ return mRenderer.createPreview(previewView, width, height);
+ }
+
+ @Override
+ public View getView() {
+ return null;
+ }
+
+ @Override
+ public View getBigClockView() {
+ if (mBigClockView == null) {
+ createViews();
+ }
+ return mBigClockView;
+ }
+
+ @Override
+ public int getPreferredY(int totalHeight) {
+ return totalHeight / 2;
+ }
+
+ @Override
+ public void setStyle(Style style) {}
+
+ @Override
+ public void setTextColor(int color) {
+ updateColor();
+ }
+
+ @Override
+ public void setColorPalette(boolean supportsDarkText, int[] colorPalette) {
+ mPalette.setColorPalette(supportsDarkText, colorPalette);
+ updateColor();
+ }
+
+ private void updateColor() {
+ final int primary = mPalette.getPrimaryColor();
+ final int secondary = mPalette.getSecondaryColor();
+ }
+
+ @Override
+ public void onTimeTick() {
+ }
+
+ @Override
+ public void setDarkAmount(float darkAmount) {
+ mBigClockView.setDarkAmount(darkAmount);
+ }
+
+ @Override
+ public void onTimeZoneChanged(TimeZone timeZone) {}
+
+ @Override
+ public boolean shouldShowStatusArea() {
+ return false;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/DotClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/DotClockController.java
new file mode 100644
index 0000000..2d3c6d9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/clock/DotClockController.java
@@ -0,0 +1,181 @@
+/*
+* Copyright (C) 2014-2020 The BlissRoms 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.keyguard.clock;
+
+import android.app.WallpaperManager;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.graphics.Paint.Style;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextClock;
+
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.systemui.R;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.plugins.ClockPlugin;
+
+import java.util.TimeZone;
+
+/**
+ * Controller for Stretch clock that can appear on lock screen and AOD.
+ */
+public class DotClockController implements ClockPlugin {
+
+ /**
+ * Resources used to get title and thumbnail.
+ */
+ private final Resources mResources;
+
+ /**
+ * LayoutInflater used to inflate custom clock views.
+ */
+ private final LayoutInflater mLayoutInflater;
+
+ /**
+ * Extracts accent color from wallpaper.
+ */
+ private final SysuiColorExtractor mColorExtractor;
+
+ /**
+ * Renders preview from clock view.
+ */
+ private final ViewPreviewer mRenderer = new ViewPreviewer();
+
+ /**
+ * Custom clock shown on AOD screen and behind stack scroller on lock.
+ */
+ private ClockLayout mBigClockView;
+ private ImageClock mDotClock;
+
+ /**
+ * Helper to extract colors from wallpaper palette for clock face.
+ */
+ private final ClockPalette mPalette = new ClockPalette();
+
+ /**
+ * Create a BubbleClockController instance.
+ *
+ * @param res Resources contains title and thumbnail.
+ * @param inflater Inflater used to inflate custom clock views.
+ * @param colorExtractor Extracts accent color from wallpaper.
+ */
+ public DotClockController(Resources res, LayoutInflater inflater,
+ SysuiColorExtractor colorExtractor) {
+ mResources = res;
+ mLayoutInflater = inflater;
+ mColorExtractor = colorExtractor;
+ }
+
+ private void createViews() {
+ mBigClockView = (ClockLayout) mLayoutInflater.inflate(R.layout.dot_clock, null);
+ mDotClock = mBigClockView.findViewById(R.id.analog_clock);
+ }
+
+ @Override
+ public void onDestroyView() {
+ mBigClockView = null;
+ mDotClock = null;
+ }
+
+ @Override
+ public String getName() {
+ return "dot";
+ }
+
+ @Override
+ public String getTitle() {
+ return mResources.getString(R.string.clock_title_dot);
+ }
+
+ @Override
+ public Bitmap getThumbnail() {
+ return BitmapFactory.decodeResource(mResources, R.drawable.dot_thumbnail);
+ }
+
+ @Override
+ public Bitmap getPreview(int width, int height) {
+
+ // Use the big clock view for the preview
+ View view = getBigClockView();
+
+ // Initialize state of plugin before generating preview.
+ setDarkAmount(1f);
+ setTextColor(Color.WHITE);
+ ColorExtractor.GradientColors colors = mColorExtractor.getColors(
+ WallpaperManager.FLAG_LOCK);
+ setColorPalette(colors.supportsDarkText(), colors.getColorPalette());
+ onTimeTick();
+
+ return mRenderer.createPreview(view, width, height);
+ }
+
+ @Override
+ public View getView() {
+ return null;
+ }
+
+ @Override
+ public View getBigClockView() {
+ if (mBigClockView == null) {
+ createViews();
+ }
+ return mBigClockView;
+ }
+
+ @Override
+ public int getPreferredY(int totalHeight) {
+ return totalHeight / 2;
+ }
+
+ @Override
+ public void setTextColor(int color) {
+ updateColor();
+ }
+
+ @Override
+ public void setColorPalette(boolean supportsDarkText, int[] colorPalette) {
+ mPalette.setColorPalette(supportsDarkText, colorPalette);
+ updateColor();
+ }
+
+ private void updateColor() {
+ final int primary = mPalette.getPrimaryColor();
+ final int secondary = mPalette.getSecondaryColor();
+ //mDotClock.setClockColors(primary, secondary);
+ }
+
+ @Override
+ public void onTimeTick() {
+ mDotClock.onTimeChanged();
+ mBigClockView.onTimeChanged();
+ }
+
+ @Override
+ public void setDarkAmount(float darkAmount) {
+ mPalette.setDarkAmount(darkAmount);
+ mBigClockView.setDarkAmount(darkAmount);
+ }
+
+ @Override
+ public void onTimeZoneChanged(TimeZone timeZone) {
+ mDotClock.onTimeZoneChanged(timeZone);
+ }
+
+ @Override
+ public boolean shouldShowStatusArea() {
+ return true;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/MNMLBoxClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/MNMLBoxClockController.java
new file mode 100644
index 0000000..401c7ab
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/clock/MNMLBoxClockController.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2017-2018 I N F I N I T Y (Amal Das)
+ * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 Bootleggers ROM
+ *
+ * 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.keyguard.clock;
+
+import android.app.WallpaperManager;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.graphics.Paint.Style;
+import android.icu.text.DateFormat;
+import android.icu.text.DisplayContext;
+import android.text.Html;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextView;
+
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.systemui.R;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.plugins.ClockPlugin;
+
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Locale;
+import java.util.TimeZone;
+
+/**
+ * Plugin for the default clock face used only to provide a preview.
+ */
+public class MNMLBoxClockController implements ClockPlugin {
+
+ /**
+ * Resources used to get title and thumbnail.
+ */
+ private final Resources mResources;
+
+ /**
+ * LayoutInflater used to inflate custom clock views.
+ */
+ private final LayoutInflater mLayoutInflater;
+
+ /**
+ * Extracts accent color from wallpaper.
+ */
+ private final SysuiColorExtractor mColorExtractor;
+
+ /**
+ * Renders preview from clock view.
+ */
+ private final ViewPreviewer mRenderer = new ViewPreviewer();
+
+ /**
+ * Root view of clock.
+ */
+ private ClockLayout mBigClockView;
+
+ /**
+ * Text clock in preview view hierarchy.
+ */
+ private TextView mClock;
+ private TextView mDate;
+
+ /**
+ * Time and calendars to check the date
+ */
+ private final Calendar mTime = Calendar.getInstance(TimeZone.getDefault());
+ private String mDescFormat;
+ private TimeZone mTimeZone;
+
+ /**
+ * Create a DefaultClockController instance.
+ *
+ * @param res Resources contains title and thumbnail.
+ * @param inflater Inflater used to inflate custom clock views.
+ * @param colorExtractor Extracts accent color from wallpaper.
+ */
+ public MNMLBoxClockController(Resources res, LayoutInflater inflater,
+ SysuiColorExtractor colorExtractor) {
+ mResources = res;
+ mLayoutInflater = inflater;
+ mColorExtractor = colorExtractor;
+ }
+
+ private void createViews() {
+ mBigClockView = (ClockLayout) mLayoutInflater
+ .inflate(R.layout.digital_mnml_box, null);
+ mClock = mBigClockView.findViewById(R.id.clock);
+ mDate = mBigClockView.findViewById(R.id.bigDate);
+ onTimeTick();
+ }
+
+ @Override
+ public void onDestroyView() {
+ mBigClockView = null;
+ mClock = null;
+ mDate = null;
+ }
+
+ @Override
+ public String getName() {
+ return "mnml_box";
+ }
+
+ @Override
+ public String getTitle() {
+ return mResources.getString(R.string.clock_title_mnml_box);
+ }
+
+ @Override
+ public Bitmap getThumbnail() {
+ return BitmapFactory.decodeResource(mResources, R.drawable.mmnl_box);
+ }
+
+ @Override
+ public Bitmap getPreview(int width, int height) {
+
+ View previewView = mLayoutInflater.inflate(R.layout.digital_mnml_box, null);
+ TextView previewTime = previewView.findViewById(R.id.clock);
+ TextView previewDate = previewView.findViewById(R.id.bigDate);
+
+ // Initialize state of plugin before generating preview.
+ ColorExtractor.GradientColors colors = mColorExtractor.getColors(
+ WallpaperManager.FLAG_LOCK);
+ final int hour = mTime.get(Calendar.HOUR) % 12;
+ // lazy and ugly workaround for the it's string
+ String typeHeader = mResources.getQuantityText(
+ R.plurals.type_clock_header, hour).toString();
+ typeHeader = typeHeader.replaceAll("\\n", "") + " ";
+ SimpleDateFormat timeformat = new SimpleDateFormat("HH:mm");
+ previewTime.setText(typeHeader.substring(0, typeHeader.indexOf("^")) + " " + timeformat.format(mTime.getInstance().getTimeInMillis()));
+ DateFormat dateFormat = DateFormat.getInstanceForSkeleton("EEEEMMMMd", Locale.getDefault());
+ dateFormat.setContext(DisplayContext.CAPITALIZATION_FOR_STANDALONE);
+ previewDate.setText(dateFormat.format(mTime.getInstance().getTimeInMillis()));
+
+ return mRenderer.createPreview(previewView, width, height);
+ }
+
+ @Override
+ public View getView() {
+ return null;
+ }
+
+ @Override
+ public View getBigClockView() {
+ if (mBigClockView == null) {
+ createViews();
+ }
+ return mBigClockView;
+ }
+
+ @Override
+ public int getPreferredY(int totalHeight) {
+ return totalHeight / 2;
+ }
+
+ @Override
+ public void setStyle(Style style) {}
+
+ @Override
+ public void setTextColor(int color) {
+ mClock.setTextColor(color);
+ }
+
+ @Override
+ public void setColorPalette(boolean supportsDarkText, int[] colorPalette) {}
+
+ @Override
+ public void onTimeTick() {
+ mTime.setTimeInMillis(System.currentTimeMillis());
+ final int hour = mTime.get(Calendar.HOUR) % 12;
+ // lazy and ugly workaround for the it's string
+ String typeHeader = mResources.getQuantityText(
+ R.plurals.type_clock_header, hour).toString();
+ typeHeader = typeHeader.replaceAll("\\n", "");
+ SimpleDateFormat timeformat = new SimpleDateFormat("HH:mm");
+ mClock.setText(typeHeader.substring(0, typeHeader.indexOf("^")) + " " + timeformat.format(mTime.getInstance().getTimeInMillis()));
+ DateFormat dateFormat = DateFormat.getInstanceForSkeleton("EEEEMMMMd", Locale.getDefault());
+ dateFormat.setContext(DisplayContext.CAPITALIZATION_FOR_STANDALONE);
+ mDate.setText(dateFormat.format(mTime.getInstance().getTimeInMillis()));
+ }
+
+ @Override
+ public void setDarkAmount(float darkAmount) {
+ mBigClockView.setDarkAmount(darkAmount);
+ }
+
+ @Override
+ public void onTimeZoneChanged(TimeZone timeZone) {}
+
+ @Override
+ public boolean shouldShowStatusArea() {
+ return false;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/MNMLMinimalClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/MNMLMinimalClockController.java
new file mode 100644
index 0000000..a1c98f4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/clock/MNMLMinimalClockController.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.keyguard.clock;
+
+import android.app.WallpaperManager;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.graphics.drawable.GradientDrawable;
+import android.graphics.Paint.Style;
+import android.text.Html;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextClock;
+
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.systemui.R;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.plugins.ClockPlugin;
+
+import java.util.TimeZone;
+
+/**
+ * Plugin for the default clock face used only to provide a preview.
+ */
+public class MNMLMinimalClockController implements ClockPlugin {
+
+ /**
+ * Resources used to get title and thumbnail.
+ */
+ private final Resources mResources;
+
+ /**
+ * LayoutInflater used to inflate custom clock views.
+ */
+ private final LayoutInflater mLayoutInflater;
+
+ /**
+ * Extracts accent color from wallpaper.
+ */
+ private final SysuiColorExtractor mColorExtractor;
+
+ /**
+ * Renders preview from clock view.
+ */
+ private final ViewPreviewer mRenderer = new ViewPreviewer();
+
+ /**
+ * Root view of clock.
+ */
+ private ClockLayout mBigClockView;
+
+ /**
+ * Text clock in preview view hierarchy.
+ */
+ private TextClock mClock;
+ private TextClock mDate;
+
+ /**
+ * Create a DefaultClockController instance.
+ *
+ * @param res Resources contains title and thumbnail.
+ * @param inflater Inflater used to inflate custom clock views.
+ * @param colorExtractor Extracts accent color from wallpaper.
+ */
+ public MNMLMinimalClockController(Resources res, LayoutInflater inflater,
+ SysuiColorExtractor colorExtractor) {
+ mResources = res;
+ mLayoutInflater = inflater;
+ mColorExtractor = colorExtractor;
+ }
+
+ private void createViews() {
+ mBigClockView = (ClockLayout) mLayoutInflater
+ .inflate(R.layout.digital_mnml_minimal, null);
+ mClock = mBigClockView.findViewById(R.id.clock);
+ mDate = mBigClockView.findViewById(R.id.date);
+ ColorExtractor.GradientColors colors = mColorExtractor.getColors(
+ WallpaperManager.FLAG_LOCK);
+ setColorPalette(colors.supportsDarkText(), colors.getColorPalette());
+ }
+
+ @Override
+ public void onDestroyView() {
+ mBigClockView = null;
+ mClock = null;
+ mDate = null;
+ }
+
+ @Override
+ public String getName() {
+ return "mnml_mnml";
+ }
+
+ @Override
+ public String getTitle() {
+ return mResources.getString(R.string.clock_title_mnml_minimal);
+ }
+
+ @Override
+ public Bitmap getThumbnail() {
+ return BitmapFactory.decodeResource(mResources, R.drawable.mmnl_minimal);
+ }
+
+ @Override
+ public Bitmap getPreview(int width, int height) {
+
+ // Use the big clock view for the preview
+ View view = getBigClockView();
+
+ // Initialize state of plugin before generating preview.
+ ColorExtractor.GradientColors colors = mColorExtractor.getColors(
+ WallpaperManager.FLAG_LOCK);
+ setColorPalette(colors.supportsDarkText(), colors.getColorPalette());
+ onTimeTick();
+
+ return mRenderer.createPreview(view, width, height);
+ }
+
+ @Override
+ public View getView() {
+ return null;
+ }
+
+ @Override
+ public View getBigClockView() {
+ if (mBigClockView == null) {
+ createViews();
+ }
+ return mBigClockView;
+ }
+
+ @Override
+ public int getPreferredY(int totalHeight) {
+ return totalHeight / 2;
+ }
+
+ @Override
+ public void setStyle(Style style) {}
+
+ @Override
+ public void setTextColor(int color) {
+ }
+
+ @Override
+ public void setColorPalette(boolean supportsDarkText, int[] colorPalette) {
+ if (colorPalette == null || colorPalette.length == 0) {
+ return;
+ }
+ final int accentColor = colorPalette[Math.max(0, colorPalette.length - 5)];
+ GradientDrawable dateBg = (GradientDrawable) mDate.getBackground();
+ dateBg.setColor(accentColor);
+ dateBg.setStroke(0,Color.TRANSPARENT);
+ }
+
+ @Override
+ public void onTimeTick() {
+ }
+
+ @Override
+ public void setDarkAmount(float darkAmount) {
+ mBigClockView.setDarkAmount(darkAmount);
+ }
+
+ @Override
+ public void onTimeZoneChanged(TimeZone timeZone) {}
+
+ @Override
+ public boolean shouldShowStatusArea() {
+ return false;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/OPAnalogClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/OPAnalogClockController.java
new file mode 100644
index 0000000..65e190a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/clock/OPAnalogClockController.java
@@ -0,0 +1,181 @@
+/*
+* Copyright (C) 2014-2020 The BlissRoms 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.keyguard.clock;
+
+import android.app.WallpaperManager;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.graphics.Paint.Style;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextClock;
+
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.systemui.R;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.plugins.ClockPlugin;
+
+import java.util.TimeZone;
+
+/**
+ * Controller for Stretch clock that can appear on lock screen and AOD.
+ */
+public class OPAnalogClockController implements ClockPlugin {
+
+ /**
+ * Resources used to get title and thumbnail.
+ */
+ private final Resources mResources;
+
+ /**
+ * LayoutInflater used to inflate custom clock views.
+ */
+ private final LayoutInflater mLayoutInflater;
+
+ /**
+ * Extracts accent color from wallpaper.
+ */
+ private final SysuiColorExtractor mColorExtractor;
+
+ /**
+ * Renders preview from clock view.
+ */
+ private final ViewPreviewer mRenderer = new ViewPreviewer();
+
+ /**
+ * Custom clock shown on AOD screen and behind stack scroller on lock.
+ */
+ private ClockLayout mBigClockView;
+ private ImageClock mOneplusClock;
+
+ /**
+ * Helper to extract colors from wallpaper palette for clock face.
+ */
+ private final ClockPalette mPalette = new ClockPalette();
+
+ /**
+ * Create a BubbleClockController instance.
+ *
+ * @param res Resources contains title and thumbnail.
+ * @param inflater Inflater used to inflate custom clock views.
+ * @param colorExtractor Extracts accent color from wallpaper.
+ */
+ public OPAnalogClockController(Resources res, LayoutInflater inflater,
+ SysuiColorExtractor colorExtractor) {
+ mResources = res;
+ mLayoutInflater = inflater;
+ mColorExtractor = colorExtractor;
+ }
+
+ private void createViews() {
+ mBigClockView = (ClockLayout) mLayoutInflater.inflate(R.layout.op_analog_clock, null);
+ mOneplusClock = mBigClockView.findViewById(R.id.analog_clock);
+ }
+
+ @Override
+ public void onDestroyView() {
+ mBigClockView = null;
+ mOneplusClock = null;
+ }
+
+ @Override
+ public String getName() {
+ return "Oneplus Analog";
+ }
+
+ @Override
+ public String getTitle() {
+ return mResources.getString(R.string.clock_title_oneplus_analog);
+ }
+
+ @Override
+ public Bitmap getThumbnail() {
+ return BitmapFactory.decodeResource(mResources, R.drawable.op_analog_thumbnail);
+ }
+
+ @Override
+ public Bitmap getPreview(int width, int height) {
+
+ // Use the big clock view for the preview
+ View view = getBigClockView();
+
+ // Initialize state of plugin before generating preview.
+ setDarkAmount(1f);
+ setTextColor(Color.WHITE);
+ ColorExtractor.GradientColors colors = mColorExtractor.getColors(
+ WallpaperManager.FLAG_LOCK);
+ setColorPalette(colors.supportsDarkText(), colors.getColorPalette());
+ onTimeTick();
+
+ return mRenderer.createPreview(view, width, height);
+ }
+
+ @Override
+ public View getView() {
+ return null;
+ }
+
+ @Override
+ public View getBigClockView() {
+ if (mBigClockView == null) {
+ createViews();
+ }
+ return mBigClockView;
+ }
+
+ @Override
+ public int getPreferredY(int totalHeight) {
+ return totalHeight / 2;
+ }
+
+ @Override
+ public void setTextColor(int color) {
+ updateColor();
+ }
+
+ @Override
+ public void setColorPalette(boolean supportsDarkText, int[] colorPalette) {
+ mPalette.setColorPalette(supportsDarkText, colorPalette);
+ updateColor();
+ }
+
+ private void updateColor() {
+ final int primary = mPalette.getPrimaryColor();
+ final int secondary = mPalette.getSecondaryColor();
+ //mOneplusClock.setClockColors(primary, secondary);
+ }
+
+ @Override
+ public void onTimeTick() {
+ mOneplusClock.onTimeChanged();
+ mBigClockView.onTimeChanged();
+ }
+
+ @Override
+ public void setDarkAmount(float darkAmount) {
+ mPalette.setDarkAmount(darkAmount);
+ mBigClockView.setDarkAmount(darkAmount);
+ }
+
+ @Override
+ public void onTimeZoneChanged(TimeZone timeZone) {
+ mOneplusClock.onTimeZoneChanged(timeZone);
+ }
+
+ @Override
+ public boolean shouldShowStatusArea() {
+ return true;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/OPMinimalClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/OPMinimalClockController.java
new file mode 100644
index 0000000..571257d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/clock/OPMinimalClockController.java
@@ -0,0 +1,181 @@
+/*
+* Copyright (C) 2014-2020 The BlissRoms 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.keyguard.clock;
+
+import android.app.WallpaperManager;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.graphics.Paint.Style;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextClock;
+
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.systemui.R;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.plugins.ClockPlugin;
+
+import java.util.TimeZone;
+
+/**
+ * Controller for Stretch clock that can appear on lock screen and AOD.
+ */
+public class OPMinimalClockController implements ClockPlugin {
+
+ /**
+ * Resources used to get title and thumbnail.
+ */
+ private final Resources mResources;
+
+ /**
+ * LayoutInflater used to inflate custom clock views.
+ */
+ private final LayoutInflater mLayoutInflater;
+
+ /**
+ * Extracts accent color from wallpaper.
+ */
+ private final SysuiColorExtractor mColorExtractor;
+
+ /**
+ * Renders preview from clock view.
+ */
+ private final ViewPreviewer mRenderer = new ViewPreviewer();
+
+ /**
+ * Custom clock shown on AOD screen and behind stack scroller on lock.
+ */
+ private ClockLayout mBigClockView;
+ private ImageClock mOneplusClock;
+
+ /**
+ * Helper to extract colors from wallpaper palette for clock face.
+ */
+ private final ClockPalette mPalette = new ClockPalette();
+
+ /**
+ * Create a BubbleClockController instance.
+ *
+ * @param res Resources contains title and thumbnail.
+ * @param inflater Inflater used to inflate custom clock views.
+ * @param colorExtractor Extracts accent color from wallpaper.
+ */
+ public OPMinimalClockController(Resources res, LayoutInflater inflater,
+ SysuiColorExtractor colorExtractor) {
+ mResources = res;
+ mLayoutInflater = inflater;
+ mColorExtractor = colorExtractor;
+ }
+
+ private void createViews() {
+ mBigClockView = (ClockLayout) mLayoutInflater.inflate(R.layout.op_minimal_clock, null);
+ mOneplusClock = mBigClockView.findViewById(R.id.analog_clock);
+ }
+
+ @Override
+ public void onDestroyView() {
+ mBigClockView = null;
+ mOneplusClock = null;
+ }
+
+ @Override
+ public String getName() {
+ return "Oneplus Minimal";
+ }
+
+ @Override
+ public String getTitle() {
+ return mResources.getString(R.string.clock_title_oneplus_minimal);
+ }
+
+ @Override
+ public Bitmap getThumbnail() {
+ return BitmapFactory.decodeResource(mResources, R.drawable.oneplus_minimal_thumbnail);
+ }
+
+ @Override
+ public Bitmap getPreview(int width, int height) {
+
+ // Use the big clock view for the preview
+ View view = getBigClockView();
+
+ // Initialize state of plugin before generating preview.
+ setDarkAmount(1f);
+ setTextColor(Color.WHITE);
+ ColorExtractor.GradientColors colors = mColorExtractor.getColors(
+ WallpaperManager.FLAG_LOCK);
+ setColorPalette(colors.supportsDarkText(), colors.getColorPalette());
+ onTimeTick();
+
+ return mRenderer.createPreview(view, width, height);
+ }
+
+ @Override
+ public View getView() {
+ return null;
+ }
+
+ @Override
+ public View getBigClockView() {
+ if (mBigClockView == null) {
+ createViews();
+ }
+ return mBigClockView;
+ }
+
+ @Override
+ public int getPreferredY(int totalHeight) {
+ return totalHeight / 2;
+ }
+
+ @Override
+ public void setTextColor(int color) {
+ updateColor();
+ }
+
+ @Override
+ public void setColorPalette(boolean supportsDarkText, int[] colorPalette) {
+ mPalette.setColorPalette(supportsDarkText, colorPalette);
+ updateColor();
+ }
+
+ private void updateColor() {
+ final int primary = mPalette.getPrimaryColor();
+ final int secondary = mPalette.getSecondaryColor();
+ //mOneplusClock.setClockColors(primary, secondary);
+ }
+
+ @Override
+ public void onTimeTick() {
+ mOneplusClock.onTimeChanged();
+ mBigClockView.onTimeChanged();
+ }
+
+ @Override
+ public void setDarkAmount(float darkAmount) {
+ mPalette.setDarkAmount(darkAmount);
+ mBigClockView.setDarkAmount(darkAmount);
+ }
+
+ @Override
+ public void onTimeZoneChanged(TimeZone timeZone) {
+ mOneplusClock.onTimeZoneChanged(timeZone);
+ }
+
+ @Override
+ public boolean shouldShowStatusArea() {
+ return true;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/OPMinimalismClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/OPMinimalismClockController.java
new file mode 100644
index 0000000..6abe632
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/clock/OPMinimalismClockController.java
@@ -0,0 +1,181 @@
+/*
+* Copyright (C) 2014-2020 The BlissRoms 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.keyguard.clock;
+
+import android.app.WallpaperManager;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.graphics.Paint.Style;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextClock;
+
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.systemui.R;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.plugins.ClockPlugin;
+
+import java.util.TimeZone;
+
+/**
+ * Controller for Stretch clock that can appear on lock screen and AOD.
+ */
+public class OPMinimalismClockController implements ClockPlugin {
+
+ /**
+ * Resources used to get title and thumbnail.
+ */
+ private final Resources mResources;
+
+ /**
+ * LayoutInflater used to inflate custom clock views.
+ */
+ private final LayoutInflater mLayoutInflater;
+
+ /**
+ * Extracts accent color from wallpaper.
+ */
+ private final SysuiColorExtractor mColorExtractor;
+
+ /**
+ * Renders preview from clock view.
+ */
+ private final ViewPreviewer mRenderer = new ViewPreviewer();
+
+ /**
+ * Custom clock shown on AOD screen and behind stack scroller on lock.
+ */
+ private ClockLayout mBigClockView;
+ private ImageClock mOneplusClock;
+
+ /**
+ * Helper to extract colors from wallpaper palette for clock face.
+ */
+ private final ClockPalette mPalette = new ClockPalette();
+
+ /**
+ * Create a BubbleClockController instance.
+ *
+ * @param res Resources contains title and thumbnail.
+ * @param inflater Inflater used to inflate custom clock views.
+ * @param colorExtractor Extracts accent color from wallpaper.
+ */
+ public OPMinimalismClockController(Resources res, LayoutInflater inflater,
+ SysuiColorExtractor colorExtractor) {
+ mResources = res;
+ mLayoutInflater = inflater;
+ mColorExtractor = colorExtractor;
+ }
+
+ private void createViews() {
+ mBigClockView = (ClockLayout) mLayoutInflater.inflate(R.layout.op_minimalism_clock, null);
+ mOneplusClock = mBigClockView.findViewById(R.id.analog_clock);
+ }
+
+ @Override
+ public void onDestroyView() {
+ mBigClockView = null;
+ mOneplusClock = null;
+ }
+
+ @Override
+ public String getName() {
+ return "Oneplus Analog";
+ }
+
+ @Override
+ public String getTitle() {
+ return mResources.getString(R.string.clock_title_minimalism);
+ }
+
+ @Override
+ public Bitmap getThumbnail() {
+ return BitmapFactory.decodeResource(mResources, R.drawable.op_minimalism_thumbnail);
+ }
+
+ @Override
+ public Bitmap getPreview(int width, int height) {
+
+ // Use the big clock view for the preview
+ View view = getBigClockView();
+
+ // Initialize state of plugin before generating preview.
+ setDarkAmount(1f);
+ setTextColor(Color.WHITE);
+ ColorExtractor.GradientColors colors = mColorExtractor.getColors(
+ WallpaperManager.FLAG_LOCK);
+ setColorPalette(colors.supportsDarkText(), colors.getColorPalette());
+ onTimeTick();
+
+ return mRenderer.createPreview(view, width, height);
+ }
+
+ @Override
+ public View getView() {
+ return null;
+ }
+
+ @Override
+ public View getBigClockView() {
+ if (mBigClockView == null) {
+ createViews();
+ }
+ return mBigClockView;
+ }
+
+ @Override
+ public int getPreferredY(int totalHeight) {
+ return totalHeight / 2;
+ }
+
+ @Override
+ public void setTextColor(int color) {
+ updateColor();
+ }
+
+ @Override
+ public void setColorPalette(boolean supportsDarkText, int[] colorPalette) {
+ mPalette.setColorPalette(supportsDarkText, colorPalette);
+ updateColor();
+ }
+
+ private void updateColor() {
+ final int primary = mPalette.getPrimaryColor();
+ final int secondary = mPalette.getSecondaryColor();
+ //mOneplusClock.setClockColors(primary, secondary);
+ }
+
+ @Override
+ public void onTimeTick() {
+ mOneplusClock.onTimeChanged();
+ mBigClockView.onTimeChanged();
+ }
+
+ @Override
+ public void setDarkAmount(float darkAmount) {
+ mPalette.setDarkAmount(darkAmount);
+ mBigClockView.setDarkAmount(darkAmount);
+ }
+
+ @Override
+ public void onTimeZoneChanged(TimeZone timeZone) {
+ mOneplusClock.onTimeZoneChanged(timeZone);
+ }
+
+ @Override
+ public boolean shouldShowStatusArea() {
+ return true;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/OPNumbersClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/OPNumbersClockController.java
new file mode 100644
index 0000000..14df7ef
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/clock/OPNumbersClockController.java
@@ -0,0 +1,181 @@
+/*
+* Copyright (C) 2014-2020 The BlissRoms 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.keyguard.clock;
+
+import android.app.WallpaperManager;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.graphics.Paint.Style;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextClock;
+
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.systemui.R;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.plugins.ClockPlugin;
+
+import java.util.TimeZone;
+
+/**
+ * Controller for Stretch clock that can appear on lock screen and AOD.
+ */
+public class OPNumbersClockController implements ClockPlugin {
+
+ /**
+ * Resources used to get title and thumbnail.
+ */
+ private final Resources mResources;
+
+ /**
+ * LayoutInflater used to inflate custom clock views.
+ */
+ private final LayoutInflater mLayoutInflater;
+
+ /**
+ * Extracts accent color from wallpaper.
+ */
+ private final SysuiColorExtractor mColorExtractor;
+
+ /**
+ * Renders preview from clock view.
+ */
+ private final ViewPreviewer mRenderer = new ViewPreviewer();
+
+ /**
+ * Custom clock shown on AOD screen and behind stack scroller on lock.
+ */
+ private ClockLayout mBigClockView;
+ private ImageClock mOneplusClock;
+
+ /**
+ * Helper to extract colors from wallpaper palette for clock face.
+ */
+ private final ClockPalette mPalette = new ClockPalette();
+
+ /**
+ * Create a BubbleClockController instance.
+ *
+ * @param res Resources contains title and thumbnail.
+ * @param inflater Inflater used to inflate custom clock views.
+ * @param colorExtractor Extracts accent color from wallpaper.
+ */
+ public OPNumbersClockController(Resources res, LayoutInflater inflater,
+ SysuiColorExtractor colorExtractor) {
+ mResources = res;
+ mLayoutInflater = inflater;
+ mColorExtractor = colorExtractor;
+ }
+
+ private void createViews() {
+ mBigClockView = (ClockLayout) mLayoutInflater.inflate(R.layout.oneplus_numbers_clock, null);
+ mOneplusClock = mBigClockView.findViewById(R.id.analog_clock);
+ }
+
+ @Override
+ public void onDestroyView() {
+ mBigClockView = null;
+ mOneplusClock = null;
+ }
+
+ @Override
+ public String getName() {
+ return "Oneplus";
+ }
+
+ @Override
+ public String getTitle() {
+ return mResources.getString(R.string.clock_title_oneplus_numbers);
+ }
+
+ @Override
+ public Bitmap getThumbnail() {
+ return BitmapFactory.decodeResource(mResources, R.drawable.oneplus_numbers_thumbnail);
+ }
+
+ @Override
+ public Bitmap getPreview(int width, int height) {
+
+ // Use the big clock view for the preview
+ View view = getBigClockView();
+
+ // Initialize state of plugin before generating preview.
+ setDarkAmount(1f);
+ setTextColor(Color.WHITE);
+ ColorExtractor.GradientColors colors = mColorExtractor.getColors(
+ WallpaperManager.FLAG_LOCK);
+ setColorPalette(colors.supportsDarkText(), colors.getColorPalette());
+ onTimeTick();
+
+ return mRenderer.createPreview(view, width, height);
+ }
+
+ @Override
+ public View getView() {
+ return null;
+ }
+
+ @Override
+ public View getBigClockView() {
+ if (mBigClockView == null) {
+ createViews();
+ }
+ return mBigClockView;
+ }
+
+ @Override
+ public int getPreferredY(int totalHeight) {
+ return totalHeight / 2;
+ }
+
+ @Override
+ public void setTextColor(int color) {
+ updateColor();
+ }
+
+ @Override
+ public void setColorPalette(boolean supportsDarkText, int[] colorPalette) {
+ mPalette.setColorPalette(supportsDarkText, colorPalette);
+ updateColor();
+ }
+
+ private void updateColor() {
+ final int primary = mPalette.getPrimaryColor();
+ final int secondary = mPalette.getSecondaryColor();
+ //mOneplusClock.setClockColors(primary, secondary);
+ }
+
+ @Override
+ public void onTimeTick() {
+ mOneplusClock.onTimeChanged();
+ mBigClockView.onTimeChanged();
+ }
+
+ @Override
+ public void setDarkAmount(float darkAmount) {
+ mPalette.setDarkAmount(darkAmount);
+ mBigClockView.setDarkAmount(darkAmount);
+ }
+
+ @Override
+ public void onTimeZoneChanged(TimeZone timeZone) {
+ mOneplusClock.onTimeZoneChanged(timeZone);
+ }
+
+ @Override
+ public boolean shouldShowStatusArea() {
+ return true;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/OPRomanClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/OPRomanClockController.java
new file mode 100644
index 0000000..d89cbde
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/clock/OPRomanClockController.java
@@ -0,0 +1,181 @@
+/*
+* Copyright (C) 2014-2020 The BlissRoms 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.keyguard.clock;
+
+import android.app.WallpaperManager;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.graphics.Paint.Style;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextClock;
+
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.systemui.R;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.plugins.ClockPlugin;
+
+import java.util.TimeZone;
+
+/**
+ * Controller for Stretch clock that can appear on lock screen and AOD.
+ */
+public class OPRomanClockController implements ClockPlugin {
+
+ /**
+ * Resources used to get title and thumbnail.
+ */
+ private final Resources mResources;
+
+ /**
+ * LayoutInflater used to inflate custom clock views.
+ */
+ private final LayoutInflater mLayoutInflater;
+
+ /**
+ * Extracts accent color from wallpaper.
+ */
+ private final SysuiColorExtractor mColorExtractor;
+
+ /**
+ * Renders preview from clock view.
+ */
+ private final ViewPreviewer mRenderer = new ViewPreviewer();
+
+ /**
+ * Custom clock shown on AOD screen and behind stack scroller on lock.
+ */
+ private ClockLayout mBigClockView;
+ private ImageClock mOneplusClock;
+
+ /**
+ * Helper to extract colors from wallpaper palette for clock face.
+ */
+ private final ClockPalette mPalette = new ClockPalette();
+
+ /**
+ * Create a BubbleClockController instance.
+ *
+ * @param res Resources contains title and thumbnail.
+ * @param inflater Inflater used to inflate custom clock views.
+ * @param colorExtractor Extracts accent color from wallpaper.
+ */
+ public OPRomanClockController(Resources res, LayoutInflater inflater,
+ SysuiColorExtractor colorExtractor) {
+ mResources = res;
+ mLayoutInflater = inflater;
+ mColorExtractor = colorExtractor;
+ }
+
+ private void createViews() {
+ mBigClockView = (ClockLayout) mLayoutInflater.inflate(R.layout.op_roman_clock, null);
+ mOneplusClock = mBigClockView.findViewById(R.id.analog_clock);
+ }
+
+ @Override
+ public void onDestroyView() {
+ mBigClockView = null;
+ mOneplusClock = null;
+ }
+
+ @Override
+ public String getName() {
+ return "Oneplus Roman";
+ }
+
+ @Override
+ public String getTitle() {
+ return mResources.getString(R.string.clock_title_oneplus_roman);
+ }
+
+ @Override
+ public Bitmap getThumbnail() {
+ return BitmapFactory.decodeResource(mResources, R.drawable.oneplus_roman_thumbnail);
+ }
+
+ @Override
+ public Bitmap getPreview(int width, int height) {
+
+ // Use the big clock view for the preview
+ View view = getBigClockView();
+
+ // Initialize state of plugin before generating preview.
+ setDarkAmount(1f);
+ setTextColor(Color.WHITE);
+ ColorExtractor.GradientColors colors = mColorExtractor.getColors(
+ WallpaperManager.FLAG_LOCK);
+ setColorPalette(colors.supportsDarkText(), colors.getColorPalette());
+ onTimeTick();
+
+ return mRenderer.createPreview(view, width, height);
+ }
+
+ @Override
+ public View getView() {
+ return null;
+ }
+
+ @Override
+ public View getBigClockView() {
+ if (mBigClockView == null) {
+ createViews();
+ }
+ return mBigClockView;
+ }
+
+ @Override
+ public int getPreferredY(int totalHeight) {
+ return totalHeight / 2;
+ }
+
+ @Override
+ public void setTextColor(int color) {
+ updateColor();
+ }
+
+ @Override
+ public void setColorPalette(boolean supportsDarkText, int[] colorPalette) {
+ mPalette.setColorPalette(supportsDarkText, colorPalette);
+ updateColor();
+ }
+
+ private void updateColor() {
+ final int primary = mPalette.getPrimaryColor();
+ final int secondary = mPalette.getSecondaryColor();
+ //mOneplusClock.setClockColors(primary, secondary);
+ }
+
+ @Override
+ public void onTimeTick() {
+ mOneplusClock.onTimeChanged();
+ mBigClockView.onTimeChanged();
+ }
+
+ @Override
+ public void setDarkAmount(float darkAmount) {
+ mPalette.setDarkAmount(darkAmount);
+ mBigClockView.setDarkAmount(darkAmount);
+ }
+
+ @Override
+ public void onTimeZoneChanged(TimeZone timeZone) {
+ mOneplusClock.onTimeZoneChanged(timeZone);
+ }
+
+ @Override
+ public boolean shouldShowStatusArea() {
+ return true;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/SamsungBoldClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/SamsungBoldClockController.java
new file mode 100644
index 0000000..8b34135
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/clock/SamsungBoldClockController.java
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.keyguard.clock;
+
+import android.app.WallpaperManager;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.graphics.Paint.Style;
+import android.text.Html;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextClock;
+
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.systemui.R;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.plugins.ClockPlugin;
+
+import java.util.TimeZone;
+
+import static com.android.systemui.statusbar.phone
+ .KeyguardClockPositionAlgorithm.CLOCK_USE_DEFAULT_Y;
+
+/**
+ * Plugin for the default clock face used only to provide a preview.
+ */
+public class SamsungBoldClockController implements ClockPlugin {
+
+ /**
+ * Resources used to get title and thumbnail.
+ */
+ private final Resources mResources;
+
+ /**
+ * LayoutInflater used to inflate custom clock views.
+ */
+ private final LayoutInflater mLayoutInflater;
+
+ /**
+ * Extracts accent color from wallpaper.
+ */
+ private final SysuiColorExtractor mColorExtractor;
+
+ /**
+ * Renders preview from clock view.
+ */
+ private final ViewPreviewer mRenderer = new ViewPreviewer();
+
+ /**
+ * Root view of clock.
+ */
+ private ClockLayout mView;
+
+ /**
+ * Text clock in preview view hierarchy.
+ */
+ private TextClock mClock;
+
+ /**
+ * Create a DefaultClockController instance.
+ *
+ * @param res Resources contains title and thumbnail.
+ * @param inflater Inflater used to inflate custom clock views.
+ * @param colorExtractor Extracts accent color from wallpaper.
+ */
+ public SamsungBoldClockController(Resources res, LayoutInflater inflater,
+ SysuiColorExtractor colorExtractor) {
+ mResources = res;
+ mLayoutInflater = inflater;
+ mColorExtractor = colorExtractor;
+ }
+
+ private void createViews() {
+ mView = (ClockLayout) mLayoutInflater
+ .inflate(R.layout.digital_clock_custom, null);
+ mClock = mView.findViewById(R.id.clock);
+ mClock.setLineSpacing(0, 0.8f);
+ mClock.setFormat12Hour(Html.fromHtml("<strong>hh</strong><br>mm"));
+ mClock.setFormat24Hour(Html.fromHtml("<strong>kk</strong><br>mm"));
+ }
+
+ @Override
+ public void onDestroyView() {
+ mView = null;
+ mClock = null;
+ }
+
+ @Override
+ public String getName() {
+ return "samsung_bold";
+ }
+
+ @Override
+ public String getTitle() {
+ return mResources.getString(R.string.clock_title_samsung_bold);
+ }
+
+ @Override
+ public Bitmap getThumbnail() {
+ return BitmapFactory.decodeResource(mResources, R.drawable.samsung_bold_thumbnail);
+ }
+
+ @Override
+ public Bitmap getPreview(int width, int height) {
+
+ View previewView = mLayoutInflater.inflate(R.layout.default_clock_preview, null);
+ TextClock previewTime = previewView.findViewById(R.id.time);
+ previewTime.setLineSpacing(0, 0.8f);
+ previewTime.setFormat12Hour(Html.fromHtml("<strong>hh</strong><br>mm"));
+ previewTime.setFormat24Hour(Html.fromHtml("<strong>kk</strong><br>mm"));
+ TextClock previewDate = previewView.findViewById(R.id.date);
+
+ // Initialize state of plugin before generating preview.
+ previewTime.setTextColor(Color.WHITE);
+ previewDate.setTextColor(Color.WHITE);
+ ColorExtractor.GradientColors colors = mColorExtractor.getColors(
+ WallpaperManager.FLAG_LOCK);
+ setColorPalette(colors.supportsDarkText(), colors.getColorPalette());
+ onTimeTick();
+
+ return mRenderer.createPreview(previewView, width, height);
+ }
+
+ @Override
+ public View getView() {
+ if (mView == null) {
+ createViews();
+ }
+ return mView;
+ }
+
+ @Override
+ public View getBigClockView() {
+ return null;
+ }
+
+ @Override
+ public int getPreferredY(int totalHeight) {
+ return CLOCK_USE_DEFAULT_Y;
+ }
+
+ @Override
+ public void setStyle(Style style) {}
+
+ @Override
+ public void setTextColor(int color) {
+ mClock.setTextColor(color);
+ }
+
+ @Override
+ public void setColorPalette(boolean supportsDarkText, int[] colorPalette) {}
+
+ @Override
+ public void onTimeTick() {
+ mView.onTimeChanged();
+ mClock.refreshTime();
+ }
+
+ @Override
+ public void setDarkAmount(float darkAmount) {
+ mView.setDarkAmount(darkAmount);
+ }
+
+ @Override
+ public void onTimeZoneChanged(TimeZone timeZone) {}
+
+ @Override
+ public boolean shouldShowStatusArea() {
+ return true;
+ }
+
+ @Override
+ public boolean shouldShowInBigContainer() {
+ return true;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/SamsungClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/SamsungClockController.java
new file mode 100644
index 0000000..8a09397
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/clock/SamsungClockController.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.keyguard.clock;
+
+import android.app.WallpaperManager;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.graphics.Paint.Style;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextClock;
+
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.systemui.R;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.plugins.ClockPlugin;
+
+import java.util.TimeZone;
+
+import static com.android.systemui.statusbar.phone
+ .KeyguardClockPositionAlgorithm.CLOCK_USE_DEFAULT_Y;
+
+/**
+ * Plugin for the default clock face used only to provide a preview.
+ */
+public class SamsungClockController implements ClockPlugin {
+
+ /**
+ * Resources used to get title and thumbnail.
+ */
+ private final Resources mResources;
+
+ /**
+ * LayoutInflater used to inflate custom clock views.
+ */
+ private final LayoutInflater mLayoutInflater;
+
+ /**
+ * Extracts accent color from wallpaper.
+ */
+ private final SysuiColorExtractor mColorExtractor;
+
+ /**
+ * Renders preview from clock view.
+ */
+ private final ViewPreviewer mRenderer = new ViewPreviewer();
+
+ /**
+ * Root view of clock.
+ */
+ private ClockLayout mView;
+
+ /**
+ * Text clock in preview view hierarchy.
+ */
+ private TextClock mClock;
+
+ /**
+ * Create a DefaultClockController instance.
+ *
+ * @param res Resources contains title and thumbnail.
+ * @param inflater Inflater used to inflate custom clock views.
+ * @param colorExtractor Extracts accent color from wallpaper.
+ */
+ public SamsungClockController(Resources res, LayoutInflater inflater,
+ SysuiColorExtractor colorExtractor) {
+ mResources = res;
+ mLayoutInflater = inflater;
+ mColorExtractor = colorExtractor;
+ }
+
+ private void createViews() {
+ mView = (ClockLayout) mLayoutInflater
+ .inflate(R.layout.digital_clock_custom, null);
+ mClock = mView.findViewById(R.id.clock);
+ mClock.setLineSpacing(0, 0.8f);
+ mClock.setFormat12Hour("hh\nmm");
+ mClock.setFormat24Hour("kk\nmm");
+ }
+
+ @Override
+ public void onDestroyView() {
+ mView = null;
+ mClock = null;
+ }
+
+ @Override
+ public String getName() {
+ return "samsung";
+ }
+
+ @Override
+ public String getTitle() {
+ return mResources.getString(R.string.clock_title_samsung);
+ }
+
+ @Override
+ public Bitmap getThumbnail() {
+ return BitmapFactory.decodeResource(mResources, R.drawable.samsung_thumbnail);
+ }
+
+ @Override
+ public Bitmap getPreview(int width, int height) {
+
+ View previewView = mLayoutInflater.inflate(R.layout.default_clock_preview, null);
+ TextClock previewTime = previewView.findViewById(R.id.time);
+ previewTime.setLineSpacing(0, 0.8f);
+ previewTime.setFormat12Hour("hh\nmm");
+ previewTime.setFormat24Hour("kk\nmm");
+ TextClock previewDate = previewView.findViewById(R.id.date);
+
+ // Initialize state of plugin before generating preview.
+ previewTime.setTextColor(Color.WHITE);
+ previewDate.setTextColor(Color.WHITE);
+ ColorExtractor.GradientColors colors = mColorExtractor.getColors(
+ WallpaperManager.FLAG_LOCK);
+ setColorPalette(colors.supportsDarkText(), colors.getColorPalette());
+ onTimeTick();
+
+ return mRenderer.createPreview(previewView, width, height);
+ }
+
+ @Override
+ public View getView() {
+ if (mView == null) {
+ createViews();
+ }
+ return mView;
+ }
+
+ @Override
+ public View getBigClockView() {
+ return null;
+ }
+
+ @Override
+ public int getPreferredY(int totalHeight) {
+ return CLOCK_USE_DEFAULT_Y;
+ }
+
+ @Override
+ public void setStyle(Style style) {}
+
+ @Override
+ public void setTextColor(int color) {
+ mClock.setTextColor(color);
+ }
+
+ @Override
+ public void setColorPalette(boolean supportsDarkText, int[] colorPalette) {}
+
+ @Override
+ public void onTimeTick() {
+ mView.onTimeChanged();
+ mClock.refreshTime();
+ }
+
+ @Override
+ public void setDarkAmount(float darkAmount) {
+ mView.setDarkAmount(darkAmount);
+ }
+
+ @Override
+ public void onTimeZoneChanged(TimeZone timeZone) {}
+
+ @Override
+ public boolean shouldShowStatusArea() {
+ return true;
+ }
+
+ @Override
+ public boolean shouldShowInBigContainer() {
+ return true;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/SfunyClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/SfunyClockController.java
new file mode 100644
index 0000000..f769c85
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/clock/SfunyClockController.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.keyguard.clock;
+
+import android.app.WallpaperManager;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.graphics.Paint.Style;
+import android.text.Html;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextClock;
+
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.systemui.R;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.plugins.ClockPlugin;
+
+import java.util.TimeZone;
+
+/**
+ * Plugin for the default clock face used only to provide a preview.
+ */
+public class SfunyClockController implements ClockPlugin {
+
+ /**
+ * Resources used to get title and thumbnail.
+ */
+ private final Resources mResources;
+
+ /**
+ * LayoutInflater used to inflate custom clock views.
+ */
+ private final LayoutInflater mLayoutInflater;
+
+ /**
+ * Extracts accent color from wallpaper.
+ */
+ private final SysuiColorExtractor mColorExtractor;
+
+ /**
+ * Renders preview from clock view.
+ */
+ private final ViewPreviewer mRenderer = new ViewPreviewer();
+
+ /**
+ * Root view of clock.
+ */
+ private ClockLayout mBigClockView;
+
+ /**
+ * Text clock for both hour and minute
+ */
+ private TextClock mHourClock;
+ private TextClock mMinuteClock;
+
+ /**
+ * Controller for transition into dark state.
+ */
+ private CrossFadeDarkController mDarkController;
+
+ /**
+ * Create a DefaultClockController instance.
+ *
+ * @param res Resources contains title and thumbnail.
+ * @param inflater Inflater used to inflate custom clock views.
+ * @param colorExtractor Extracts accent color from wallpaper.
+ */
+ public SfunyClockController(Resources res, LayoutInflater inflater,
+ SysuiColorExtractor colorExtractor) {
+ mResources = res;
+ mLayoutInflater = inflater;
+ mColorExtractor = colorExtractor;
+ }
+
+ private void createViews() {
+ mBigClockView = (ClockLayout) mLayoutInflater
+ .inflate(R.layout.digital_clock_sfuny, null);
+ mHourClock = mBigClockView.findViewById(R.id.clockHour);
+ mMinuteClock = mBigClockView.findViewById(R.id.clockMinute);
+ }
+
+ @Override
+ public void onDestroyView() {
+ mBigClockView = null;
+ mHourClock = null;
+ mMinuteClock = null;
+ }
+
+ @Override
+ public String getName() {
+ return "sfuny";
+ }
+
+ @Override
+ public String getTitle() {
+ return "SFUNY";
+ }
+
+ @Override
+ public Bitmap getThumbnail() {
+ return BitmapFactory.decodeResource(mResources, R.drawable.sfuny);
+ }
+
+ @Override
+ public Bitmap getPreview(int width, int height) {
+
+ View previewView = mLayoutInflater.inflate(R.layout.digital_sfuny_preview, null);
+ TextClock previewHourTime = previewView.findViewById(R.id.clockHour);
+ TextClock previewMinuteTime = previewView.findViewById(R.id.clockMinute);
+ TextClock previewDate = previewView.findViewById(R.id.date);
+
+ // Initialize state of plugin before generating preview.
+ previewHourTime.setTextColor(Color.WHITE);
+ previewMinuteTime.setTextColor(Color.WHITE);
+ previewDate.setTextColor(Color.WHITE);
+ ColorExtractor.GradientColors colors = mColorExtractor.getColors(
+ WallpaperManager.FLAG_LOCK);
+ setColorPalette(colors.supportsDarkText(), colors.getColorPalette());
+ onTimeTick();
+
+ return mRenderer.createPreview(previewView, width, height);
+ }
+
+ @Override
+ public View getView() {
+ return null;
+ }
+
+ @Override
+ public View getBigClockView() {
+ if (mBigClockView == null) {
+ createViews();
+ }
+ return mBigClockView;
+ }
+
+ @Override
+ public int getPreferredY(int totalHeight) {
+ return totalHeight / 2;
+ }
+
+ @Override
+ public void setStyle(Style style) {}
+
+ @Override
+ public void setTextColor(int color) {
+ mHourClock.setTextColor(color);
+ mMinuteClock.setTextColor(color);
+ }
+
+ @Override
+ public void setColorPalette(boolean supportsDarkText, int[] colorPalette) {}
+
+ @Override
+ public void onTimeTick() {
+ }
+
+ @Override
+ public void setDarkAmount(float darkAmount) {
+ if (mDarkController != null) {
+ mBigClockView.setDarkAmount(darkAmount);
+ }
+ }
+
+ @Override
+ public void onTimeZoneChanged(TimeZone timeZone) {}
+
+ @Override
+ public boolean shouldShowStatusArea() {
+ return true;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/SneekyClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/SneekyClockController.java
new file mode 100644
index 0000000..c84def4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/clock/SneekyClockController.java
@@ -0,0 +1,181 @@
+/*
+* Copyright (C) 2014-2020 The BlissRoms 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.keyguard.clock;
+
+import android.app.WallpaperManager;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.graphics.Paint.Style;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextClock;
+
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.systemui.R;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.plugins.ClockPlugin;
+
+import java.util.TimeZone;
+
+/**
+ * Controller for Stretch clock that can appear on lock screen and AOD.
+ */
+public class SneekyClockController implements ClockPlugin {
+
+ /**
+ * Resources used to get title and thumbnail.
+ */
+ private final Resources mResources;
+
+ /**
+ * LayoutInflater used to inflate custom clock views.
+ */
+ private final LayoutInflater mLayoutInflater;
+
+ /**
+ * Extracts accent color from wallpaper.
+ */
+ private final SysuiColorExtractor mColorExtractor;
+
+ /**
+ * Renders preview from clock view.
+ */
+ private final ViewPreviewer mRenderer = new ViewPreviewer();
+
+ /**
+ * Custom clock shown on AOD screen and behind stack scroller on lock.
+ */
+ private ClockLayout mBigClockView;
+ private ImageClock mSneekyClock;
+
+ /**
+ * Helper to extract colors from wallpaper palette for clock face.
+ */
+ private final ClockPalette mPalette = new ClockPalette();
+
+ /**
+ * Create a BubbleClockController instance.
+ *
+ * @param res Resources contains title and thumbnail.
+ * @param inflater Inflater used to inflate custom clock views.
+ * @param colorExtractor Extracts accent color from wallpaper.
+ */
+ public SneekyClockController(Resources res, LayoutInflater inflater,
+ SysuiColorExtractor colorExtractor) {
+ mResources = res;
+ mLayoutInflater = inflater;
+ mColorExtractor = colorExtractor;
+ }
+
+ private void createViews() {
+ mBigClockView = (ClockLayout) mLayoutInflater.inflate(R.layout.sneeky_clock, null);
+ mSneekyClock = mBigClockView.findViewById(R.id.analog_clock);
+ }
+
+ @Override
+ public void onDestroyView() {
+ mBigClockView = null;
+ mSneekyClock = null;
+ }
+
+ @Override
+ public String getName() {
+ return "sneeky";
+ }
+
+ @Override
+ public String getTitle() {
+ return mResources.getString(R.string.clock_title_sneeky);
+ }
+
+ @Override
+ public Bitmap getThumbnail() {
+ return BitmapFactory.decodeResource(mResources, R.drawable.sneeky_thumbnail);
+ }
+
+ @Override
+ public Bitmap getPreview(int width, int height) {
+
+ // Use the big clock view for the preview
+ View view = getBigClockView();
+
+ // Initialize state of plugin before generating preview.
+ setDarkAmount(1f);
+ setTextColor(Color.WHITE);
+ ColorExtractor.GradientColors colors = mColorExtractor.getColors(
+ WallpaperManager.FLAG_LOCK);
+ setColorPalette(colors.supportsDarkText(), colors.getColorPalette());
+ onTimeTick();
+
+ return mRenderer.createPreview(view, width, height);
+ }
+
+ @Override
+ public View getView() {
+ return null;
+ }
+
+ @Override
+ public View getBigClockView() {
+ if (mBigClockView == null) {
+ createViews();
+ }
+ return mBigClockView;
+ }
+
+ @Override
+ public int getPreferredY(int totalHeight) {
+ return totalHeight / 2;
+ }
+
+ @Override
+ public void setTextColor(int color) {
+ updateColor();
+ }
+
+ @Override
+ public void setColorPalette(boolean supportsDarkText, int[] colorPalette) {
+ mPalette.setColorPalette(supportsDarkText, colorPalette);
+ updateColor();
+ }
+
+ private void updateColor() {
+ final int primary = mPalette.getPrimaryColor();
+ final int secondary = mPalette.getSecondaryColor();
+ //mSneekyClock.setClockColors(primary, secondary);
+ }
+
+ @Override
+ public void onTimeTick() {
+ mSneekyClock.onTimeChanged();
+ mBigClockView.onTimeChanged();
+ }
+
+ @Override
+ public void setDarkAmount(float darkAmount) {
+ mPalette.setDarkAmount(darkAmount);
+ mBigClockView.setDarkAmount(darkAmount);
+ }
+
+ @Override
+ public void onTimeZoneChanged(TimeZone timeZone) {
+ mSneekyClock.onTimeZoneChanged(timeZone);
+ }
+
+ @Override
+ public boolean shouldShowStatusArea() {
+ return true;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/SpectrumClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/SpectrumClockController.java
new file mode 100644
index 0000000..346d2fb
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/clock/SpectrumClockController.java
@@ -0,0 +1,181 @@
+/*
+* Copyright (C) 2014-2020 The BlissRoms 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.keyguard.clock;
+
+import android.app.WallpaperManager;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.graphics.Paint.Style;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextClock;
+
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.systemui.R;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.plugins.ClockPlugin;
+
+import java.util.TimeZone;
+
+/**
+ * Controller for Stretch clock that can appear on lock screen and AOD.
+ */
+public class SpectrumClockController implements ClockPlugin {
+
+ /**
+ * Resources used to get title and thumbnail.
+ */
+ private final Resources mResources;
+
+ /**
+ * LayoutInflater used to inflate custom clock views.
+ */
+ private final LayoutInflater mLayoutInflater;
+
+ /**
+ * Extracts accent color from wallpaper.
+ */
+ private final SysuiColorExtractor mColorExtractor;
+
+ /**
+ * Renders preview from clock view.
+ */
+ private final ViewPreviewer mRenderer = new ViewPreviewer();
+
+ /**
+ * Custom clock shown on AOD screen and behind stack scroller on lock.
+ */
+ private ClockLayout mBigClockView;
+ private ImageClock mSpectrumClock;
+
+ /**
+ * Helper to extract colors from wallpaper palette for clock face.
+ */
+ private final ClockPalette mPalette = new ClockPalette();
+
+ /**
+ * Create a BubbleClockController instance.
+ *
+ * @param res Resources contains title and thumbnail.
+ * @param inflater Inflater used to inflate custom clock views.
+ * @param colorExtractor Extracts accent color from wallpaper.
+ */
+ public SpectrumClockController(Resources res, LayoutInflater inflater,
+ SysuiColorExtractor colorExtractor) {
+ mResources = res;
+ mLayoutInflater = inflater;
+ mColorExtractor = colorExtractor;
+ }
+
+ private void createViews() {
+ mBigClockView = (ClockLayout) mLayoutInflater.inflate(R.layout.spectrum_clock, null);
+ mSpectrumClock = mBigClockView.findViewById(R.id.analog_clock);
+ }
+
+ @Override
+ public void onDestroyView() {
+ mBigClockView = null;
+ mSpectrumClock = null;
+ }
+
+ @Override
+ public String getName() {
+ return "spectrum";
+ }
+
+ @Override
+ public String getTitle() {
+ return mResources.getString(R.string.clock_title_spectrum);
+ }
+
+ @Override
+ public Bitmap getThumbnail() {
+ return BitmapFactory.decodeResource(mResources, R.drawable.spectrum_thumbnail);
+ }
+
+ @Override
+ public Bitmap getPreview(int width, int height) {
+
+ // Use the big clock view for the preview
+ View view = getBigClockView();
+
+ // Initialize state of plugin before generating preview.
+ setDarkAmount(1f);
+ setTextColor(Color.WHITE);
+ ColorExtractor.GradientColors colors = mColorExtractor.getColors(
+ WallpaperManager.FLAG_LOCK);
+ setColorPalette(colors.supportsDarkText(), colors.getColorPalette());
+ onTimeTick();
+
+ return mRenderer.createPreview(view, width, height);
+ }
+
+ @Override
+ public View getView() {
+ return null;
+ }
+
+ @Override
+ public View getBigClockView() {
+ if (mBigClockView == null) {
+ createViews();
+ }
+ return mBigClockView;
+ }
+
+ @Override
+ public int getPreferredY(int totalHeight) {
+ return totalHeight / 2;
+ }
+
+ @Override
+ public void setTextColor(int color) {
+ updateColor();
+ }
+
+ @Override
+ public void setColorPalette(boolean supportsDarkText, int[] colorPalette) {
+ mPalette.setColorPalette(supportsDarkText, colorPalette);
+ updateColor();
+ }
+
+ private void updateColor() {
+ final int primary = mPalette.getPrimaryColor();
+ final int secondary = mPalette.getSecondaryColor();
+ //mSpectrumClock.setClockColors(primary, secondary);
+ }
+
+ @Override
+ public void onTimeTick() {
+ mSpectrumClock.onTimeChanged();
+ mBigClockView.onTimeChanged();
+ }
+
+ @Override
+ public void setDarkAmount(float darkAmount) {
+ mPalette.setDarkAmount(darkAmount);
+ mBigClockView.setDarkAmount(darkAmount);
+ }
+
+ @Override
+ public void onTimeZoneChanged(TimeZone timeZone) {
+ mSpectrumClock.onTimeZoneChanged(timeZone);
+ }
+
+ @Override
+ public boolean shouldShowStatusArea() {
+ return true;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/SpideyClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/SpideyClockController.java
new file mode 100644
index 0000000..e1cd2c4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/clock/SpideyClockController.java
@@ -0,0 +1,181 @@
+/*
+* Copyright (C) 2014-2020 The BlissRoms 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.keyguard.clock;
+
+import android.app.WallpaperManager;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.graphics.Paint.Style;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextClock;
+
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.systemui.R;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.plugins.ClockPlugin;
+
+import java.util.TimeZone;
+
+/**
+ * Controller for Stretch clock that can appear on lock screen and AOD.
+ */
+public class SpideyClockController implements ClockPlugin {
+
+ /**
+ * Resources used to get title and thumbnail.
+ */
+ private final Resources mResources;
+
+ /**
+ * LayoutInflater used to inflate custom clock views.
+ */
+ private final LayoutInflater mLayoutInflater;
+
+ /**
+ * Extracts accent color from wallpaper.
+ */
+ private final SysuiColorExtractor mColorExtractor;
+
+ /**
+ * Renders preview from clock view.
+ */
+ private final ViewPreviewer mRenderer = new ViewPreviewer();
+
+ /**
+ * Custom clock shown on AOD screen and behind stack scroller on lock.
+ */
+ private ClockLayout mBigClockView;
+ private ImageClock mSpideyClock;
+
+ /**
+ * Helper to extract colors from wallpaper palette for clock face.
+ */
+ private final ClockPalette mPalette = new ClockPalette();
+
+ /**
+ * Create a BubbleClockController instance.
+ *
+ * @param res Resources contains title and thumbnail.
+ * @param inflater Inflater used to inflate custom clock views.
+ * @param colorExtractor Extracts accent color from wallpaper.
+ */
+ public SpideyClockController(Resources res, LayoutInflater inflater,
+ SysuiColorExtractor colorExtractor) {
+ mResources = res;
+ mLayoutInflater = inflater;
+ mColorExtractor = colorExtractor;
+ }
+
+ private void createViews() {
+ mBigClockView = (ClockLayout) mLayoutInflater.inflate(R.layout.spidey_clock, null);
+ mSpideyClock = mBigClockView.findViewById(R.id.analog_clock);
+ }
+
+ @Override
+ public void onDestroyView() {
+ mBigClockView = null;
+ mSpideyClock = null;
+ }
+
+ @Override
+ public String getName() {
+ return "spidey";
+ }
+
+ @Override
+ public String getTitle() {
+ return mResources.getString(R.string.clock_title_spidey);
+ }
+
+ @Override
+ public Bitmap getThumbnail() {
+ return BitmapFactory.decodeResource(mResources, R.drawable.spidey_thumbnail);
+ }
+
+ @Override
+ public Bitmap getPreview(int width, int height) {
+
+ // Use the big clock view for the preview
+ View view = getBigClockView();
+
+ // Initialize state of plugin before generating preview.
+ setDarkAmount(1f);
+ setTextColor(Color.WHITE);
+ ColorExtractor.GradientColors colors = mColorExtractor.getColors(
+ WallpaperManager.FLAG_LOCK);
+ setColorPalette(colors.supportsDarkText(), colors.getColorPalette());
+ onTimeTick();
+
+ return mRenderer.createPreview(view, width, height);
+ }
+
+ @Override
+ public View getView() {
+ return null;
+ }
+
+ @Override
+ public View getBigClockView() {
+ if (mBigClockView == null) {
+ createViews();
+ }
+ return mBigClockView;
+ }
+
+ @Override
+ public int getPreferredY(int totalHeight) {
+ return totalHeight / 2;
+ }
+
+ @Override
+ public void setTextColor(int color) {
+ updateColor();
+ }
+
+ @Override
+ public void setColorPalette(boolean supportsDarkText, int[] colorPalette) {
+ mPalette.setColorPalette(supportsDarkText, colorPalette);
+ updateColor();
+ }
+
+ private void updateColor() {
+ final int primary = mPalette.getPrimaryColor();
+ final int secondary = mPalette.getSecondaryColor();
+ //mSpideyClock.setClockColors(primary, secondary);
+ }
+
+ @Override
+ public void onTimeTick() {
+ mSpideyClock.onTimeChanged();
+ mBigClockView.onTimeChanged();
+ }
+
+ @Override
+ public void setDarkAmount(float darkAmount) {
+ mPalette.setDarkAmount(darkAmount);
+ mBigClockView.setDarkAmount(darkAmount);
+ }
+
+ @Override
+ public void onTimeZoneChanged(TimeZone timeZone) {
+ mSpideyClock.onTimeZoneChanged(timeZone);
+ }
+
+ @Override
+ public boolean shouldShowStatusArea() {
+ return true;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/TypeClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/TypeClockController.java
new file mode 100644
index 0000000..95bdbe0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/clock/TypeClockController.java
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.keyguard.clock;
+
+import static com.android.systemui.statusbar.phone.KeyguardClockPositionAlgorithm.CLOCK_USE_DEFAULT_Y;
+
+import android.app.WallpaperManager;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.graphics.Paint.Style;
+import android.util.MathUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import com.android.internal.colorextraction.ColorExtractor;
+import com.android.systemui.R;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.plugins.ClockPlugin;
+
+import java.util.TimeZone;
+
+/**
+ * Plugin for a custom Typographic clock face that displays the time in words.
+ */
+public class TypeClockController implements ClockPlugin {
+
+ /**
+ * Resources used to get title and thumbnail.
+ */
+ private final Resources mResources;
+
+ /**
+ * LayoutInflater used to inflate custom clock views.
+ */
+ private final LayoutInflater mLayoutInflater;
+
+ /**
+ * Extracts accent color from wallpaper.
+ */
+ private final SysuiColorExtractor mColorExtractor;
+
+ /**
+ * Computes preferred position of clock.
+ */
+ private float mDarkAmount;
+ private final int mStatusBarHeight;
+ private final int mKeyguardLockPadding;
+ private final int mKeyguardLockHeight;
+ private final int mBurnInOffsetY;
+
+ /**
+ * Renders preview from clock view.
+ */
+ private final ViewPreviewer mRenderer = new ViewPreviewer();
+
+ /**
+ * Custom clock shown on AOD screen and behind stack scroller on lock.
+ */
+ private TypographicClock mTypeClock;
+ private ClockLayout mBigClockView;
+
+ /**
+ * Controller for transition into dark state.
+ */
+ private CrossFadeDarkController mDarkController;
+
+ /**
+ * Create a TypeClockController instance.
+ *
+ * @param res Resources contains title and thumbnail.
+ * @param inflater Inflater used to inflate custom clock views.
+ * @param colorExtractor Extracts accent color from wallpaper.
+ */
+ TypeClockController(Resources res, LayoutInflater inflater,
+ SysuiColorExtractor colorExtractor) {
+ mResources = res;
+ mLayoutInflater = inflater;
+ mColorExtractor = colorExtractor;
+ mStatusBarHeight = res.getDimensionPixelSize(R.dimen.status_bar_height);
+ mKeyguardLockPadding = res.getDimensionPixelSize(R.dimen.keyguard_lock_padding);
+ mKeyguardLockHeight = res.getDimensionPixelSize(R.dimen.keyguard_lock_height);
+ mBurnInOffsetY = res.getDimensionPixelSize(R.dimen.burn_in_prevention_offset_y);
+ }
+
+ private void createViews() {
+ mBigClockView = (ClockLayout) mLayoutInflater.inflate(R.layout.type_aod_clock, null);
+ mTypeClock = mBigClockView.findViewById(R.id.type_clock);
+ }
+
+ @Override
+ public void onDestroyView() {
+ mBigClockView = null;
+ mTypeClock = null;
+ mDarkController = null;
+ }
+
+ @Override
+ public String getName() {
+ return "type";
+ }
+
+ @Override
+ public String getTitle() {
+ return mResources.getString(R.string.clock_title_type);
+ }
+
+ @Override
+ public Bitmap getThumbnail() {
+ return BitmapFactory.decodeResource(mResources, R.drawable.type_thumbnail);
+ }
+
+ @Override
+ public Bitmap getPreview(int width, int height) {
+
+ // Use the big clock view for the preview
+ View view = getBigClockView();
+
+ // Initialize state of plugin before generating preview.
+ setDarkAmount(1f);
+ setTextColor(Color.WHITE);
+ ColorExtractor.GradientColors colors = mColorExtractor.getColors(
+ WallpaperManager.FLAG_LOCK);
+ setColorPalette(colors.supportsDarkText(), colors.getColorPalette());
+ onTimeTick();
+
+ return mRenderer.createPreview(view, width, height);
+ }
+
+ @Override
+ public View getView() {
+ if (mBigClockView == null) {
+ createViews();
+ }
+ return mBigClockView;
+ }
+
+ @Override
+ public View getBigClockView() {
+ if (mBigClockView == null) {
+ createViews();
+ }
+ return mBigClockView ;
+ }
+
+ @Override
+ public int getPreferredY(int totalHeight) {
+ // On AOD, clock needs to appear below the status bar with enough room for pixel shifting
+ int aodY = mStatusBarHeight + mKeyguardLockHeight + 2 * mKeyguardLockPadding
+ + mBurnInOffsetY + mTypeClock.getHeight() + (mTypeClock.getHeight() / 2);
+ // On lock screen, clock needs to appear below the lock icon
+ int lockY = mStatusBarHeight + mKeyguardLockHeight + 2 * mKeyguardLockPadding + (mTypeClock.getHeight() / 2);
+ return (int) MathUtils.lerp(lockY, aodY, mDarkAmount);
+ }
+
+ @Override
+ public void setTextColor(int color) {
+ mTypeClock.setTextColor(color);
+ }
+
+ @Override
+ public void setColorPalette(boolean supportsDarkText, int[] colorPalette) {
+ if (colorPalette == null || colorPalette.length == 0) {
+ return;
+ }
+ final int color = colorPalette[Math.max(0, colorPalette.length - 5)];
+ mTypeClock.setClockColor(color);
+ }
+
+ @Override
+ public void onTimeTick() {
+ mTypeClock.onTimeChanged();
+ }
+
+ @Override
+ public void setDarkAmount(float darkAmount) {
+ mDarkAmount = darkAmount;
+ if (mDarkController != null) {
+ mDarkController.setDarkAmount(darkAmount);
+ }
+ }
+
+ @Override
+ public void onTimeZoneChanged(TimeZone timeZone) {
+ mTypeClock.onTimeZoneChanged(timeZone);
+ }
+
+ @Override
+ public boolean shouldShowStatusArea() {
+ return true;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/TypographicClock.java b/packages/SystemUI/src/com/android/keyguard/clock/TypographicClock.java
new file mode 100644
index 0000000..452dfb1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/clock/TypographicClock.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.keyguard.clock;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.text.Annotation;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.text.SpannedString;
+import android.text.TextUtils;
+import android.text.format.DateFormat;
+import android.text.style.ForegroundColorSpan;
+import android.util.AttributeSet;
+import android.widget.TextView;
+
+import com.android.systemui.R;
+
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.TimeZone;
+
+/**
+ * Clock that presents the time in words.
+ */
+public class TypographicClock extends TextView {
+
+ private static final String ANNOTATION_COLOR = "color";
+
+ private final Resources mResources;
+ private String[] mHours;
+ private final String[] mMinutes;
+ private int mAccentColor;
+ private int hour;
+ private final Calendar mTime = Calendar.getInstance(TimeZone.getDefault());
+ private String mDescFormat;
+ private TimeZone mTimeZone;
+
+ private boolean h24;
+
+ public TypographicClock(Context context) {
+ this(context, null);
+ }
+
+ public TypographicClock(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public TypographicClock(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ mDescFormat = ((SimpleDateFormat) DateFormat.getTimeFormat(context)).toLocalizedPattern();
+ mResources = context.getResources();
+ h24 = DateFormat.is24HourFormat(getContext());
+ if (!h24) mHours = mResources.getStringArray(R.array.type_clock_hours_12);
+ else mHours = mResources.getStringArray(R.array.type_clock_hours_24);
+ mMinutes = mResources.getStringArray(R.array.type_clock_minutes);
+ mAccentColor = mResources.getColor(R.color.typeClockAccentColor, null);
+ }
+
+ /**
+ * Call when the time changes to update the text of the time.
+ */
+ public void onTimeChanged() {
+ h24 = DateFormat.is24HourFormat(getContext());
+ mTime.setTimeInMillis(System.currentTimeMillis());
+ setContentDescription(DateFormat.format(mDescFormat, mTime));
+ if (!h24) {
+ mHours = mResources.getStringArray(R.array.type_clock_hours_12);
+ hour = mTime.get(Calendar.HOUR) % 12;
+ } else {
+ mHours = mResources.getStringArray(R.array.type_clock_hours_24);
+ hour = mTime.get(Calendar.HOUR_OF_DAY);
+ }
+ final int minute = mTime.get(Calendar.MINUTE) % 60;
+
+ SpannedString typeTemplate = (SpannedString) mResources.getQuantityText(
+ R.plurals.type_clock_header, hour);
+ // Find the "color" annotation and set the foreground color to the accent color.
+ Annotation[] annotations = typeTemplate.getSpans(0, typeTemplate.length(),
+ Annotation.class);
+ SpannableString spanType = new SpannableString(typeTemplate);
+ for (int i = 0; i < annotations.length; i++) {
+ Annotation annotation = annotations[i];
+ String key = annotation.getValue();
+ if (ANNOTATION_COLOR.equals(key)) {
+ spanType.setSpan(new ForegroundColorSpan(mAccentColor),
+ spanType.getSpanStart(annotation), spanType.getSpanEnd(annotation),
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ }
+ }
+
+ setText(TextUtils.expandTemplate(spanType, mHours[hour], mMinutes[minute]));
+ }
+
+ /**
+ * Call when the time zone has changed to update clock time.
+ *
+ * @param timeZone The updated time zone that will be used.
+ */
+ public void onTimeZoneChanged(TimeZone timeZone) {
+ mTimeZone = timeZone;
+ mTime.setTimeZone(timeZone);
+ }
+
+ /**
+ * Sets the accent color used on the clock face.
+ */
+ public void setClockColor(int color) {
+ mAccentColor = color;
+ onTimeChanged();
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ mTime.setTimeZone(mTimeZone != null ? mTimeZone : TimeZone.getDefault());
+ onTimeChanged();
+ }
+
+ /**
+ * Overriding hasOverlappingRendering as false to improve performance of crossfading.
+ */
+ @Override
+ public boolean hasOverlappingRendering() {
+ return false;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index a46ab3a..123703e 100644
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -17,7 +17,6 @@
import static android.app.StatusBarManager.DISABLE2_SYSTEM_ICONS;
import static android.app.StatusBarManager.DISABLE_NONE;
-import static android.provider.Settings.System.SHOW_BATTERY_PERCENT;
import static com.android.systemui.DejankUtils.whitelistIpcs;
import static com.android.systemui.util.SysuiLifecycle.viewAttachLifecycle;
@@ -28,6 +27,7 @@
import android.animation.ObjectAnimator;
import android.annotation.IntDef;
import android.app.ActivityManager;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
@@ -35,6 +35,7 @@
import android.graphics.Rect;
import android.net.Uri;
import android.os.Handler;
+import android.os.UserHandle;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.ArraySet;
@@ -51,6 +52,8 @@
import androidx.annotation.StyleRes;
import com.android.settingslib.Utils;
+import com.android.settingslib.graph.CircleBatteryDrawable;
+import com.android.settingslib.graph.FullCircleBatteryDrawable;
import com.android.settingslib.graph.ThemedBatteryDrawable;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.plugins.DarkIconDispatcher;
@@ -62,18 +65,16 @@
import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
-import com.android.systemui.tuner.TunerService;
-import com.android.systemui.tuner.TunerService.Tunable;
import com.android.systemui.util.Utils.DisableStateTracker;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.text.NumberFormat;
+import java.util.ArrayList;
public class BatteryMeterView extends LinearLayout implements
- BatteryStateChangeCallback, Tunable, DarkReceiver, ConfigurationListener {
-
+ BatteryStateChangeCallback, DarkReceiver, ConfigurationListener {
@Retention(SOURCE)
@IntDef({MODE_DEFAULT, MODE_ON, MODE_OFF, MODE_ESTIMATE})
@@ -83,7 +84,20 @@
public static final int MODE_OFF = 2;
public static final int MODE_ESTIMATE = 3;
- private final ThemedBatteryDrawable mDrawable;
+ private static final int BATTERY_STYLE_PORTRAIT = 0;
+ private static final int BATTERY_STYLE_CIRCLE = 1;
+ private static final int BATTERY_STYLE_DOTTED_CIRCLE = 2;
+ private static final int BATTERY_STYLE_FULL_CIRCLE = 3;
+ private static final int BATTERY_STYLE_TEXT = 4; /*hidden icon*/
+ private static final int BATTERY_STYLE_HIDDEN = 5;
+
+ private static final int BATTERY_PERCENT_HIDDEN = 0;
+ private static final int BATTERY_PERCENT_SHOW_INSIDE = 1;
+ private static final int BATTERY_PERCENT_SHOW_OUTSIDE = 2;
+
+ private final CircleBatteryDrawable mCircleDrawable;
+ private final FullCircleBatteryDrawable mFullCircleDrawable;
+ private final ThemedBatteryDrawable mThemedDrawable;
private final String mSlotBattery;
private final ImageView mBatteryIconView;
private final CurrentUserTracker mUserTracker;
@@ -95,16 +109,18 @@
private int mTextColor;
private int mLevel;
private int mShowPercentMode = MODE_DEFAULT;
- private boolean mForceShowPercent;
- private boolean mShowPercentAvailable;
- // Some places may need to show the battery conditionally, and not obey the tuner
- private boolean mIgnoreTunerUpdates;
- private boolean mIsSubscribedForTunerUpdates;
+
private boolean mCharging;
+ public int mBatteryStyle = BATTERY_STYLE_PORTRAIT;
+ public int mShowBatteryPercent;
private DualToneHandler mDualToneHandler;
private int mUser;
+ private boolean mIsQsHeader;
+
+ private final ArrayList<BatteryMeterViewCallbacks> mCallbacks = new ArrayList<>();
+
/**
* Whether we should use colors that adapt based on wallpaper/the scrim behind quick settings.
*/
@@ -130,13 +146,12 @@
final int frameColor = atts.getColor(R.styleable.BatteryMeterView_frameColor,
context.getColor(R.color.meter_background_color));
mPercentageStyleId = atts.getResourceId(R.styleable.BatteryMeterView_textAppearance, 0);
- mDrawable = new ThemedBatteryDrawable(context, frameColor);
+ mThemedDrawable = new ThemedBatteryDrawable(context, frameColor);
+ mCircleDrawable = new CircleBatteryDrawable(context, frameColor);
+ mFullCircleDrawable = new FullCircleBatteryDrawable(context, frameColor);
atts.recycle();
mSettingObserver = new SettingObserver(new Handler(context.getMainLooper()));
- mShowPercentAvailable = context.getResources().getBoolean(
- com.android.internal.R.bool.config_battery_percentage_setting_available);
-
addOnAttachStateChangeListener(
new DisableStateTracker(DISABLE_NONE, DISABLE2_SYSTEM_ICONS,
@@ -147,7 +162,7 @@
mSlotBattery = context.getString(
com.android.internal.R.string.status_bar_battery);
mBatteryIconView = new ImageView(context);
- mBatteryIconView.setImageDrawable(mDrawable);
+ mBatteryIconView.setImageDrawable(mThemedDrawable);
final MarginLayoutParams mlp = new MarginLayoutParams(
getResources().getDimensionPixelSize(R.dimen.status_bar_battery_icon_width),
getResources().getDimensionPixelSize(R.dimen.status_bar_battery_icon_height));
@@ -165,15 +180,13 @@
public void onUserSwitched(int newUserId) {
mUser = newUserId;
getContext().getContentResolver().unregisterContentObserver(mSettingObserver);
- getContext().getContentResolver().registerContentObserver(
- Settings.System.getUriFor(SHOW_BATTERY_PERCENT), false, mSettingObserver,
- newUserId);
updateShowPercent();
}
};
setClipChildren(false);
setClipToPadding(false);
+ mSettingObserver.observe();
Dependency.get(ConfigurationController.class).observe(viewAttachLifecycle(this), this);
}
@@ -210,44 +223,6 @@
}
/**
- * Set {@code true} to turn off BatteryMeterView's subscribing to the tuner for updates, and
- * thus avoid it controlling its own visibility
- *
- * @param ignore whether to ignore the tuner or not
- */
- public void setIgnoreTunerUpdates(boolean ignore) {
- mIgnoreTunerUpdates = ignore;
- updateTunerSubscription();
- }
-
- private void updateTunerSubscription() {
- if (mIgnoreTunerUpdates) {
- unsubscribeFromTunerUpdates();
- } else {
- subscribeForTunerUpdates();
- }
- }
-
- private void subscribeForTunerUpdates() {
- if (mIsSubscribedForTunerUpdates || mIgnoreTunerUpdates) {
- return;
- }
-
- Dependency.get(TunerService.class)
- .addTunable(this, StatusBarIconController.ICON_BLACKLIST);
- mIsSubscribedForTunerUpdates = true;
- }
-
- private void unsubscribeFromTunerUpdates() {
- if (!mIsSubscribedForTunerUpdates) {
- return;
- }
-
- Dependency.get(TunerService.class).removeTunable(this);
- mIsSubscribedForTunerUpdates = false;
- }
-
- /**
* Sets whether the battery meter view uses the wallpaperTextColor. If we're not using it, we'll
* revert back to dark-mode-based/tinted colors.
*
@@ -285,12 +260,36 @@
return false;
}
- @Override
- public void onTuningChanged(String key, String newValue) {
- if (StatusBarIconController.ICON_BLACKLIST.equals(key)) {
- ArraySet<String> icons = StatusBarIconController.getIconBlacklist(
- getContext(), newValue);
- setVisibility(icons.contains(mSlotBattery) ? View.GONE : View.VISIBLE);
+ private void updateSettings() {
+ updateSbBatteryStyle();
+ updateSbShowBatteryPercent();
+ }
+
+ private void updateSbBatteryStyle() {
+ mBatteryStyle = Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.STATUS_BAR_BATTERY_STYLE, BATTERY_STYLE_PORTRAIT);
+ updateBatteryStyle();
+ updateVisibility();
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ mCallbacks.get(i).onHiddenBattery(mBatteryStyle == BATTERY_STYLE_HIDDEN);
+ }
+ }
+
+ private void updateSbShowBatteryPercent() {
+ //updateSbBatteryStyle already called
+ switch (mBatteryStyle) {
+ case BATTERY_STYLE_TEXT:
+ mShowBatteryPercent = BATTERY_PERCENT_SHOW_OUTSIDE;
+ updatePercentView();
+ return;
+ case BATTERY_STYLE_HIDDEN:
+ mShowBatteryPercent = BATTERY_PERCENT_HIDDEN;
+ updatePercentView();
+ return;
+ default:
+ mShowBatteryPercent = Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.STATUS_BAR_SHOW_BATTERY_PERCENT, BATTERY_PERCENT_HIDDEN);
+ updatePercentView();
}
}
@@ -301,13 +300,12 @@
mBatteryController.addCallback(this);
mUser = ActivityManager.getCurrentUser();
getContext().getContentResolver().registerContentObserver(
- Settings.System.getUriFor(SHOW_BATTERY_PERCENT), false, mSettingObserver, mUser);
- getContext().getContentResolver().registerContentObserver(
Settings.Global.getUriFor(Settings.Global.BATTERY_ESTIMATES_LAST_UPDATE_TIME),
false, mSettingObserver);
updateShowPercent();
- subscribeForTunerUpdates();
+ updateSettings();
mUserTracker.startTracking();
+ mSettingObserver.observe();
}
@Override
@@ -316,21 +314,33 @@
mUserTracker.stopTracking();
mBatteryController.removeCallback(this);
getContext().getContentResolver().unregisterContentObserver(mSettingObserver);
- unsubscribeFromTunerUpdates();
}
@Override
public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
- mDrawable.setCharging(pluggedIn);
- mDrawable.setBatteryLevel(level);
- mCharging = pluggedIn;
- mLevel = level;
- updatePercentText();
+ if (mLevel != level) {
+ mLevel = level;
+ mThemedDrawable.setBatteryLevel(mLevel);
+ mCircleDrawable.setBatteryLevel(mLevel);
+ mFullCircleDrawable.setBatteryLevel(mLevel);
+ }
+ if (mCharging != pluggedIn) {
+ mCharging = pluggedIn;
+ mThemedDrawable.setCharging(mCharging);
+ mCircleDrawable.setCharging(mCharging);
+ mFullCircleDrawable.setCharging(mCharging);
+ updateShowPercent();
+ } else {
+ updatePercentText();
+ }
}
@Override
public void onPowerSaveChanged(boolean isPowerSave) {
- mDrawable.setPowerSaveEnabled(isPowerSave);
+ mThemedDrawable.setPowerSaveEnabled(isPowerSave);
+ mCircleDrawable.setPowerSaveEnabled(isPowerSave);
+ mFullCircleDrawable.setPowerSaveEnabled(isPowerSave);
+ updateShowPercent();
}
private TextView loadPercentView() {
@@ -342,10 +352,6 @@
* Updates percent view by removing old one and reinflating if necessary
*/
public void updatePercentView() {
- if (mBatteryPercentView != null) {
- removeView(mBatteryPercentView);
- mBatteryPercentView = null;
- }
updateShowPercent();
}
@@ -358,7 +364,9 @@
if (mShowPercentMode == MODE_ESTIMATE && !mCharging) {
mBatteryController.getEstimatedTimeRemainingString((String estimate) -> {
if (estimate != null) {
- mBatteryPercentView.setText(estimate);
+ if (mBatteryPercentView != null) {
+ batteryPercentViewSetText(estimate);
+ }
setContentDescription(getContext().getString(
R.string.accessibility_battery_level_with_estimate,
mLevel, estimate));
@@ -377,45 +385,98 @@
}
private void setPercentTextAtCurrentLevel() {
- mBatteryPercentView.setText(
+ if (mBatteryPercentView != null) {
+ // Use the high voltage symbol ⚡ (u26A1 unicode) but prevent the system
+ // to load its emoji colored variant with the uFE0E flag
+ String bolt = "\u26A1\uFE0E";
+ CharSequence mChargeIndicator = mCharging && (mBatteryStyle == BATTERY_STYLE_TEXT)
+ ? (bolt + " ") : "";
+ batteryPercentViewSetText(mChargeIndicator +
NumberFormat.getPercentInstance().format(mLevel / 100f));
- setContentDescription(
- getContext().getString(mCharging ? R.string.accessibility_battery_level_charging
- : R.string.accessibility_battery_level, mLevel));
+ setContentDescription(
+ getContext().getString(mCharging ? R.string.accessibility_battery_level_charging
+ : R.string.accessibility_battery_level, mLevel));
+ }
+ }
+
+ private void removeBatteryPercentView() {
+ if (mBatteryPercentView != null) {
+ removeView(mBatteryPercentView);
+ mBatteryPercentView = null;
+ }
}
private void updateShowPercent() {
final boolean showing = mBatteryPercentView != null;
- // TODO(b/140051051)
- final boolean systemSetting = 0 != whitelistIpcs(() -> Settings.System
- .getIntForUser(getContext().getContentResolver(),
- SHOW_BATTERY_PERCENT, 0, mUser));
-
- if ((mShowPercentAvailable && systemSetting && mShowPercentMode != MODE_OFF)
- || mShowPercentMode == MODE_ON || mShowPercentMode == MODE_ESTIMATE) {
+ final boolean drawPercentInside = mShowPercentMode == MODE_DEFAULT &&
+ mShowBatteryPercent == BATTERY_PERCENT_SHOW_INSIDE;
+ final boolean drawPercentOnly = mShowPercentMode == MODE_ESTIMATE ||
+ mShowPercentMode == MODE_ON || mShowBatteryPercent == BATTERY_PERCENT_SHOW_OUTSIDE;
+ if (!(!mIsQsHeader && mBatteryStyle == BATTERY_STYLE_HIDDEN)
+ && drawPercentOnly && (!drawPercentInside || mCharging)) {
+ mThemedDrawable.setShowPercent(false);
+ mCircleDrawable.setShowPercent(false);
+ mFullCircleDrawable.setShowPercent(false);
if (!showing) {
mBatteryPercentView = loadPercentView();
if (mPercentageStyleId != 0) { // Only set if specified as attribute
mBatteryPercentView.setTextAppearance(mPercentageStyleId);
}
if (mTextColor != 0) mBatteryPercentView.setTextColor(mTextColor);
- updatePercentText();
addView(mBatteryPercentView,
new ViewGroup.LayoutParams(
LayoutParams.WRAP_CONTENT,
LayoutParams.MATCH_PARENT));
}
- } else {
- if (showing) {
- removeView(mBatteryPercentView);
- mBatteryPercentView = null;
+ if (mBatteryStyle == BATTERY_STYLE_TEXT) {
+ mBatteryPercentView.setPaddingRelative(0, 0, 0, 0);
+ } else {
+ Resources res = getContext().getResources();
+ mBatteryPercentView.setPaddingRelative(
+ res.getDimensionPixelSize(R.dimen.battery_level_padding_start), 0, 0, 0);
}
+ } else {
+ removeBatteryPercentView();
+ mThemedDrawable.setShowPercent(drawPercentInside);
+ mCircleDrawable.setShowPercent(drawPercentInside);
+ mFullCircleDrawable.setShowPercent(drawPercentInside);
+ }
+ updatePercentText();
+ }
+
+ public void setIsQsHeader(boolean isQs) {
+ mIsQsHeader = isQs;
+ }
+
+ public void updateVisibility() {
+ if (mBatteryStyle == BATTERY_STYLE_TEXT || mBatteryStyle == BATTERY_STYLE_HIDDEN) {
+ mBatteryIconView.setVisibility(View.GONE);
+ mBatteryIconView.setImageDrawable(null);
+ //setVisibility(View.GONE);
+ } else {
+ mBatteryIconView.setVisibility(View.VISIBLE);
+ //setVisibility(View.VISIBLE);
+ scaleBatteryMeterViews();
+ }
+ }
+
+ private void batteryPercentViewSetText(CharSequence text) {
+ CharSequence currentText = mBatteryPercentView.getText();
+ if (!currentText.toString().equals(text.toString())) {
+ mBatteryPercentView.setText(text);
}
}
@Override
public void onDensityOrFontScaleChanged() {
scaleBatteryMeterViews();
+ updateSettings();
+ }
+
+ @Override
+ public void onOverlayChanged() {
+ updateShowPercent();
+ updateSettings();
}
/**
@@ -428,8 +489,14 @@
res.getValue(R.dimen.status_bar_icon_scale_factor, typedValue, true);
float iconScaleFactor = typedValue.getFloat();
- int batteryHeight = res.getDimensionPixelSize(R.dimen.status_bar_battery_icon_height);
- int batteryWidth = res.getDimensionPixelSize(R.dimen.status_bar_battery_icon_width);
+ int batteryHeight = mBatteryStyle == BATTERY_STYLE_CIRCLE || mBatteryStyle == BATTERY_STYLE_DOTTED_CIRCLE
+ || mBatteryStyle == BATTERY_STYLE_FULL_CIRCLE ?
+ res.getDimensionPixelSize(R.dimen.status_bar_battery_icon_circle_width) :
+ res.getDimensionPixelSize(R.dimen.status_bar_battery_icon_height);
+ int batteryWidth = mBatteryStyle == BATTERY_STYLE_CIRCLE || mBatteryStyle == BATTERY_STYLE_DOTTED_CIRCLE
+ || mBatteryStyle == BATTERY_STYLE_FULL_CIRCLE ?
+ res.getDimensionPixelSize(R.dimen.status_bar_battery_icon_circle_width) :
+ res.getDimensionPixelSize(R.dimen.status_bar_battery_icon_width);
int marginBottom = res.getDimensionPixelSize(R.dimen.battery_margin_bottom);
LinearLayout.LayoutParams scaledLayoutParams = new LinearLayout.LayoutParams(
@@ -439,6 +506,24 @@
mBatteryIconView.setLayoutParams(scaledLayoutParams);
}
+ public void updateBatteryStyle() {
+ switch (mBatteryStyle) {
+ case BATTERY_STYLE_TEXT:
+ case BATTERY_STYLE_HIDDEN:
+ break;
+ case BATTERY_STYLE_PORTRAIT:
+ mBatteryIconView.setImageDrawable(mThemedDrawable);
+ break;
+ case BATTERY_STYLE_FULL_CIRCLE:
+ mBatteryIconView.setImageDrawable(mFullCircleDrawable);
+ break;
+ default:
+ mCircleDrawable.setMeterStyle(mBatteryStyle);
+ mBatteryIconView.setImageDrawable(mCircleDrawable);
+ break;
+ }
+ }
+
@Override
public void onDarkChanged(Rect area, float darkIntensity, int tint) {
float intensity = DarkIconDispatcher.isInArea(area, this) ? darkIntensity : 0;
@@ -453,7 +538,9 @@
}
private void updateColors(int foregroundColor, int backgroundColor, int singleToneColor) {
- mDrawable.setColors(foregroundColor, backgroundColor, singleToneColor);
+ mThemedDrawable.setColors(foregroundColor, backgroundColor, singleToneColor);
+ mCircleDrawable.setColors(foregroundColor, backgroundColor, singleToneColor);
+ mFullCircleDrawable.setColors(foregroundColor, backgroundColor, singleToneColor);
mTextColor = singleToneColor;
if (mBatteryPercentView != null) {
mBatteryPercentView.setTextColor(singleToneColor);
@@ -461,14 +548,13 @@
}
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- String powerSave = mDrawable == null ? null : mDrawable.getPowerSaveEnabled() + "";
+ String powerSave = mThemedDrawable == null ? null : mThemedDrawable.getPowerSaveEnabled() + "";
CharSequence percent = mBatteryPercentView == null ? null : mBatteryPercentView.getText();
pw.println(" BatteryMeterView:");
- pw.println(" mDrawable.getPowerSave: " + powerSave);
+ pw.println(" mThemedDrawable.getPowerSave: " + powerSave);
pw.println(" mBatteryPercentView.getText(): " + percent);
pw.println(" mTextColor: #" + Integer.toHexString(mTextColor));
pw.println(" mLevel: " + mLevel);
- pw.println(" mForceShowPercent: " + mForceShowPercent);
}
private final class SettingObserver extends ContentObserver {
@@ -476,15 +562,38 @@
super(handler);
}
+ void observe() {
+ ContentResolver resolver = getContext().getContentResolver();
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.STATUS_BAR_BATTERY_STYLE),
+ false, this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.STATUS_BAR_SHOW_BATTERY_PERCENT),
+ false, this, UserHandle.USER_ALL);
+ }
+
@Override
public void onChange(boolean selfChange, Uri uri) {
super.onChange(selfChange, uri);
updateShowPercent();
- if (TextUtils.equals(uri.getLastPathSegment(),
+ updateSettings();
+ /*if (TextUtils.equals(uri.getLastPathSegment(),
Settings.Global.BATTERY_ESTIMATES_LAST_UPDATE_TIME)) {
// update the text for sure if the estimate in the cache was updated
updatePercentText();
- }
+ }*/ //updatePercentText gets called always by updateShowPercent
}
}
+
+ public interface BatteryMeterViewCallbacks {
+ default void onHiddenBattery(boolean hidden) {}
+ }
+
+ public void addCallback(BatteryMeterViewCallbacks callback) {
+ mCallbacks.add(callback);
+ }
+
+ public void removeCallback(BatteryMeterViewCallbacks callbacks) {
+ mCallbacks.remove(callbacks);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/BootReceiver.java b/packages/SystemUI/src/com/android/systemui/BootReceiver.java
new file mode 100644
index 0000000..3e570d9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/BootReceiver.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2020 BlissRoms 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;
+
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.database.ContentObserver;
+import android.os.Handler;
+import android.provider.Settings;
+import android.util.Log;
+
+/**
+ * Performs a number of miscellaneous, non-system-critical actions
+ * after the system has finished booting.
+ */
+public class BootReceiver extends BroadcastReceiver {
+ private static final String TAG = "SystemUIBootReceiver";
+ private Handler mHandler = new Handler();
+ private SettingsObserver mSettingsObserver;
+ private Context mContext;
+
+ private class SettingsObserver extends ContentObserver {
+ SettingsObserver(Handler handler) {
+ super(handler);
+ }
+
+ void observe() {
+ mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor(
+ Settings.Global.SHOW_CPU_OVERLAY),
+ false, this);
+ update();
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ update();
+ }
+
+ public void update() {
+ Intent cpuinfo = new Intent(mContext, com.android.systemui.CPUInfoService.class);
+ if (Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.SHOW_CPU_OVERLAY, 0) != 0) {
+ mContext.startService(cpuinfo);
+ } else {
+ mContext.stopService(cpuinfo);
+ }
+ }
+ }
+
+ @Override
+ public void onReceive(final Context context, Intent intent) {
+ try {
+ mContext = context;
+ if (mSettingsObserver == null) {
+ mSettingsObserver = new SettingsObserver(mHandler);
+ mSettingsObserver.observe();
+ }
+
+ // Start the cpu info overlay, if activated
+ if (Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.SHOW_CPU_OVERLAY, 0) != 0) {
+ Intent cpuinfo = new Intent(mContext, com.android.systemui.CPUInfoService.class);
+ mContext.startService(cpuinfo);
+ }
+
+ } catch (Exception e) {
+ Log.e(TAG, "Can't start load average service", e);
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/CPUInfoService.java b/packages/SystemUI/src/com/android/systemui/CPUInfoService.java
new file mode 100644
index 0000000..7034d0b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/CPUInfoService.java
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 2020-2021 BlissRoms 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;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.view.Gravity;
+import android.view.View;
+import android.view.WindowManager;
+import android.util.Log;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+
+import java.lang.StringBuffer;
+
+public class CPUInfoService extends Service {
+ private View mView;
+ private Thread mCurCPUThread;
+ private final String TAG = "CPUInfoService";
+ private int mNumCpus = 1;
+ private String[] mCurrFreq=null;
+ private String[] mCurrGov=null;
+
+ private static final String NUM_OF_CPUS_PATH = "/sys/devices/system/cpu/present";
+
+ private class CPUView extends View {
+ private Paint mOnlinePaint;
+ private Paint mOfflinePaint;
+ private float mAscent;
+ private int mFH;
+ private int mMaxWidth;
+
+ private int mNeededWidth;
+ private int mNeededHeight;
+
+ private boolean mDataAvail;
+ private String mCPUTemp;
+
+ private Handler mCurCPUHandler = new Handler() {
+ public void handleMessage(Message msg) {
+ if(msg.obj==null){
+ return;
+ }
+ if(msg.what==1){
+ String msgData = (String) msg.obj;
+ try {
+ String[] parts=msgData.split(";");
+ mCPUTemp=parts[0];
+
+ String[] cpuParts=parts[1].split("\\|");
+ for(int i=0; i<cpuParts.length; i++){
+ String cpuInfo=cpuParts[i];
+ String cpuInfoParts[]=cpuInfo.split(":");
+ if(cpuInfoParts.length==2){
+ mCurrFreq[i]=cpuInfoParts[0];
+ mCurrGov[i]=cpuInfoParts[1];
+ } else {
+ mCurrFreq[i]="0";
+ mCurrGov[i]="";
+ }
+ }
+ mDataAvail = true;
+ updateDisplay();
+ } catch(ArrayIndexOutOfBoundsException e) {
+ Log.e(TAG, "illegal data " + msgData);
+ }
+ }
+ }
+ };
+
+ CPUView(Context c) {
+ super(c);
+ float density = c.getResources().getDisplayMetrics().density;
+ int paddingPx = Math.round(5 * density);
+ setPadding(paddingPx, paddingPx, paddingPx, paddingPx);
+ setBackgroundColor(Color.argb(0x60, 0, 0, 0));
+
+ final int textSize = Math.round(12 * density);
+
+ mOnlinePaint = new Paint();
+ mOnlinePaint.setAntiAlias(true);
+ mOnlinePaint.setTextSize(textSize);
+ mOnlinePaint.setColor(Color.WHITE);
+ mOnlinePaint.setShadowLayer(5.0f, 0.0f, 0.0f, Color.BLACK);
+
+ mOfflinePaint = new Paint();
+ mOfflinePaint.setAntiAlias(true);
+ mOfflinePaint.setTextSize(textSize);
+ mOfflinePaint.setColor(Color.RED);
+
+ mAscent = mOnlinePaint.ascent();
+ float descent = mOnlinePaint.descent();
+ mFH = (int)(descent - mAscent + .5f);
+
+ final String maxWidthStr="cpuX interactive 0000000";
+ mMaxWidth = (int)mOnlinePaint.measureText(maxWidthStr);
+
+ updateDisplay();
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ mCurCPUHandler.removeMessages(1);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ setMeasuredDimension(resolveSize(mNeededWidth, widthMeasureSpec),
+ resolveSize(mNeededHeight, heightMeasureSpec));
+ }
+
+ private String getCPUInfoString(int i) {
+ String freq=mCurrFreq[i];
+ String gov=mCurrGov[i];
+ return "cpu"+i+": "+gov+": "+freq;
+ }
+
+ @Override
+ public void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+ if (!mDataAvail) {
+ return;
+ }
+
+ final int W = mNeededWidth;
+ final int RIGHT = getWidth()-1;
+
+ int x = RIGHT - mPaddingRight;
+ int top = mPaddingTop + 2;
+ int bottom = mPaddingTop + mFH - 2;
+
+ int y = mPaddingTop - (int)mAscent;
+
+ canvas.drawText("temp: "+mCPUTemp, RIGHT-mPaddingRight-mMaxWidth,
+ y-1, mOnlinePaint);
+ y += mFH;
+
+ for(int i=0; i<mCurrFreq.length; i++){
+ String s=getCPUInfoString(i);
+ String freq=mCurrFreq[i];
+ if(!freq.equals("0")){
+ canvas.drawText(s, RIGHT-mPaddingRight-mMaxWidth,
+ y-1, mOnlinePaint);
+ } else {
+ canvas.drawText(s, RIGHT-mPaddingRight-mMaxWidth,
+ y-1, mOfflinePaint);
+ }
+ y += mFH;
+ }
+ }
+
+ void updateDisplay() {
+ if (!mDataAvail) {
+ return;
+ }
+ final int NW = mNumCpus + 1;
+
+ int neededWidth = mPaddingLeft + mPaddingRight + mMaxWidth;
+ int neededHeight = mPaddingTop + mPaddingBottom + mFH * NW;
+ if (neededWidth != mNeededWidth || neededHeight != mNeededHeight) {
+ mNeededWidth = neededWidth;
+ mNeededHeight = neededHeight;
+ requestLayout();
+ } else {
+ invalidate();
+ }
+ }
+
+ private String toMHz(String mhzString) {
+ return new StringBuilder().append(Integer.valueOf(mhzString) / 1000).append(" MHz").toString();
+ }
+
+ public Handler getHandler(){
+ return mCurCPUHandler;
+ }
+ }
+
+ protected class CurCPUThread extends Thread {
+ private boolean mInterrupt = false;
+ private Handler mHandler;
+
+ private static final String CURRENT_CPU = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq";
+ private static final String CPU_ROOT = "/sys/devices/system/cpu/cpu";
+ private static final String CPU_CUR_TAIL = "/cpufreq/scaling_cur_freq";
+ private static final String CPU_GOV_TAIL = "/cpufreq/scaling_governor";
+ private static final String CPU_TEMP = "/sys/class/thermal/thermal_zone0/temp";
+
+ public CurCPUThread(Handler handler, int numCpus){
+ mHandler=handler;
+ mNumCpus = numCpus;
+ }
+
+ public void interrupt() {
+ mInterrupt = true;
+ }
+
+ @Override
+ public void run() {
+ try {
+ while (!mInterrupt) {
+ sleep(500);
+ StringBuffer sb=new StringBuffer();
+
+ String cpuTemp = CPUInfoService.readOneLine(CPU_TEMP);
+ sb.append(cpuTemp == null ? "0" : cpuTemp);
+ sb.append(";");
+
+ for(int i=0; i<mNumCpus; i++){
+ final String freqFile=CPU_ROOT+i+CPU_CUR_TAIL;
+ String currFreq = CPUInfoService.readOneLine(freqFile);
+ final String govFile=CPU_ROOT+i+CPU_GOV_TAIL;
+ String currGov = CPUInfoService.readOneLine(govFile);
+
+ if(currFreq==null){
+ currFreq="0";
+ currGov="";
+ }
+
+ sb.append(currFreq+":"+currGov+"|");
+ }
+ sb.deleteCharAt(sb.length()-1);
+ mHandler.sendMessage(mHandler.obtainMessage(1, sb.toString()));
+ }
+ } catch (InterruptedException e) {
+ return;
+ }
+ }
+ };
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ mNumCpus = getNumOfCpus();
+ mCurrFreq = new String[mNumCpus];
+ mCurrGov = new String[mNumCpus];
+
+ mView = new CPUView(this);
+ WindowManager.LayoutParams params = new WindowManager.LayoutParams(
+ WindowManager.LayoutParams.WRAP_CONTENT,
+ WindowManager.LayoutParams.WRAP_CONTENT,
+ WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY,
+ WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|
+ WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
+ PixelFormat.TRANSLUCENT);
+ params.gravity = Gravity.RIGHT | Gravity.TOP;
+ params.setTitle("CPU Info");
+
+ mCurCPUThread = new CurCPUThread(mView.getHandler(), mNumCpus);
+ mCurCPUThread.start();
+
+ Log.d(TAG, "started CurCPUThread");
+
+ WindowManager wm = (WindowManager)getSystemService(WINDOW_SERVICE);
+ wm.addView(mView, params);
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ if (mCurCPUThread.isAlive()) {
+ mCurCPUThread.interrupt();
+ try {
+ mCurCPUThread.join();
+ } catch (InterruptedException e) {
+ }
+ }
+ Log.d(TAG, "stopped CurCPUThread");
+ ((WindowManager)getSystemService(WINDOW_SERVICE)).removeView(mView);
+ mView = null;
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ private static String readOneLine(String fname) {
+ BufferedReader br;
+ String line = null;
+ try {
+ br = new BufferedReader(new FileReader(fname), 512);
+ try {
+ line = br.readLine();
+ } finally {
+ br.close();
+ }
+ } catch (Exception e) {
+ return null;
+ }
+ return line;
+ }
+
+ private static int getNumOfCpus() {
+ int numOfCpu = 1;
+ String numOfCpus = readOneLine(NUM_OF_CPUS_PATH);
+ String[] cpuCount = numOfCpus.split("-");
+ if (cpuCount.length > 1) {
+ try {
+ int cpuStart = Integer.parseInt(cpuCount[0]);
+ int cpuEnd = Integer.parseInt(cpuCount[1]);
+
+ numOfCpu = cpuEnd - cpuStart + 1;
+
+ if (numOfCpu < 0)
+ numOfCpu = 1;
+ } catch (NumberFormatException ex) {
+ numOfCpu = 1;
+ }
+ }
+ return numOfCpu;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIService.java b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
index 708002d..003f085 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIService.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
@@ -73,7 +73,7 @@
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/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
index 6d179f2..93a4f2c 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
@@ -396,10 +396,6 @@
intent.setComponent(assistComponent);
intent.putExtras(args);
- if (structureEnabled && AssistUtils.isDisclosureEnabled(mContext)) {
- showDisclosure();
- }
-
try {
final ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext,
R.anim.search_launch_enter, R.anim.search_launch_exit);
@@ -490,9 +486,7 @@
return getAssistInfoForUser(KeyguardUpdateMonitor.getCurrentUser());
}
- public void showDisclosure() {
- mAssistDisclosure.postShow();
- }
+ public void showDisclosure() {}
public void onLockscreenShown() {
AsyncTask.execute(new Runnable() {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/FODCircleView.java b/packages/SystemUI/src/com/android/systemui/biometrics/FODCircleView.java
new file mode 100644
index 0000000..25c3c66
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/FODCircleView.java
@@ -0,0 +1,536 @@
+/**
+ * Copyright (C) 2019-2020 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.biometrics;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.Point;
+import android.hardware.biometrics.BiometricSourceType;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.provider.Settings;
+import android.view.Display;
+import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.Surface;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.ImageView;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
+import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.KeyguardUpdateMonitorCallback;
+import com.android.systemui.Dependency;
+import com.android.systemui.R;
+
+import vendor.lineage.biometrics.fingerprint.inscreen.V1_0.IFingerprintInscreen;
+import vendor.lineage.biometrics.fingerprint.inscreen.V1_0.IFingerprintInscreenCallback;
+
+import java.util.NoSuchElementException;
+import java.util.Timer;
+import java.util.TimerTask;
+
+public class FODCircleView extends ImageView {
+ private static final int FADE_ANIM_DURATION = 250;
+
+ private final int mPositionX;
+ private final int mPositionY;
+ private final int mSize;
+ private final int mDreamingMaxOffset;
+ private final int mNavigationBarSize;
+ private final boolean mShouldBoostBrightness;
+ private final Paint mPaintFingerprintBackground = new Paint();
+ private final Paint mPaintFingerprint = new Paint();
+ private final WindowManager.LayoutParams mParams = new WindowManager.LayoutParams();
+ private final WindowManager.LayoutParams mPressedParams = new WindowManager.LayoutParams();
+ private final WindowManager mWindowManager;
+
+ private IFingerprintInscreen mFingerprintInscreenDaemon;
+
+ private int mDreamingOffsetX;
+ private int mDreamingOffsetY;
+
+ private boolean mFading;
+ private boolean mIsBouncer;
+ private boolean mIsBiometricRunning;
+ private boolean mIsCircleShowing;
+ private boolean mIsDreaming;
+ private boolean mIsKeyguard;
+
+ private Handler mHandler;
+
+ private final ImageView mPressedView;
+
+ private LockPatternUtils mLockPatternUtils;
+
+ private Timer mBurnInProtectionTimer;
+
+ private IFingerprintInscreenCallback mFingerprintInscreenCallback =
+ new IFingerprintInscreenCallback.Stub() {
+ @Override
+ public void onFingerDown() {
+ mHandler.post(() -> showCircle());
+ }
+
+ @Override
+ public void onFingerUp() {
+ mHandler.post(() -> hideCircle());
+ }
+ };
+
+ private KeyguardUpdateMonitor mUpdateMonitor;
+
+ private KeyguardUpdateMonitorCallback mMonitorCallback = new KeyguardUpdateMonitorCallback() {
+ @Override
+ public void onBiometricAuthenticated(int userId, BiometricSourceType biometricSourceType,
+ boolean isStrongBiometric) {
+ // We assume that if biometricSourceType matches Fingerprint it will be
+ // handled here, so we hide only when other biometric types authenticate
+ if (biometricSourceType != BiometricSourceType.FINGERPRINT) {
+ hide();
+ }
+ }
+
+ @Override
+ public void onBiometricRunningStateChanged(boolean running,
+ BiometricSourceType biometricSourceType) {
+ if (biometricSourceType == BiometricSourceType.FINGERPRINT) {
+ mIsBiometricRunning = running;
+ }
+ }
+
+ @Override
+ public void onDreamingStateChanged(boolean dreaming) {
+ mIsDreaming = dreaming;
+ updateAlpha();
+
+ if (mIsKeyguard && mUpdateMonitor.isFingerprintDetectionRunning()) {
+ show();
+ updateAlpha();
+ } else {
+ hide();
+ }
+
+ if (dreaming) {
+ mBurnInProtectionTimer = new Timer();
+ mBurnInProtectionTimer.schedule(new BurnInProtectionTask(), 0, 60 * 1000);
+ } else if (mBurnInProtectionTimer != null) {
+ mBurnInProtectionTimer.cancel();
+ updatePosition();
+ }
+ }
+
+ @Override
+ public void onKeyguardVisibilityChanged(boolean showing) {
+ mIsKeyguard = showing;
+ if (!showing) {
+ hide();
+ } else {
+ updateAlpha();
+ }
+ }
+
+ @Override
+ public void onKeyguardBouncerChanged(boolean isBouncer) {
+ mIsBouncer = isBouncer;
+ if (mUpdateMonitor.isFingerprintDetectionRunning()) {
+ if (isPinOrPattern(mUpdateMonitor.getCurrentUser()) || !isBouncer) {
+ show();
+ } else {
+ hide();
+ }
+ } else {
+ hide();
+ }
+ }
+
+ @Override
+ public void onStartedGoingToSleep(int why) {
+ hide();
+ }
+
+ @Override
+ public void onStartedWakingUp() {
+ if (mUpdateMonitor.isFingerprintDetectionRunning()) {
+ show();
+ }
+ }
+
+ @Override
+ public void onScreenTurnedOn() {
+ if (mUpdateMonitor.isFingerprintDetectionRunning()) {
+ show();
+ }
+ }
+ };
+
+ public FODCircleView(Context context) {
+ super(context);
+
+ setScaleType(ScaleType.CENTER);
+
+ IFingerprintInscreen daemon = getFingerprintInScreenDaemon();
+ if (daemon == null) {
+ throw new RuntimeException("Unable to get IFingerprintInscreen");
+ }
+
+ try {
+ mShouldBoostBrightness = daemon.shouldBoostBrightness();
+ mPositionX = daemon.getPositionX();
+ mPositionY = daemon.getPositionY();
+ mSize = daemon.getSize();
+ } catch (RemoteException e) {
+ throw new RuntimeException("Failed to retrieve FOD circle position or size");
+ }
+
+ Resources res = context.getResources();
+
+ mPaintFingerprint.setColor(res.getColor(R.color.config_fodColor));
+ mPaintFingerprint.setAntiAlias(true);
+
+ mPaintFingerprintBackground.setColor(res.getColor(R.color.config_fodColorBackground));
+ mPaintFingerprintBackground.setAntiAlias(true);
+
+ mWindowManager = context.getSystemService(WindowManager.class);
+
+ mNavigationBarSize = res.getDimensionPixelSize(R.dimen.navigation_bar_size);
+
+ mDreamingMaxOffset = (int) (mSize * 0.1f);
+
+ mHandler = new Handler(Looper.getMainLooper());
+
+ mParams.height = mSize;
+ mParams.width = mSize;
+ mParams.format = PixelFormat.TRANSLUCENT;
+
+ mParams.packageName = "android";
+ mParams.type = WindowManager.LayoutParams.TYPE_DISPLAY_OVERLAY;
+ mParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
+ WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
+ mParams.gravity = Gravity.TOP | Gravity.LEFT;
+
+ mPressedParams.copyFrom(mParams);
+ mPressedParams.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
+
+ mParams.setTitle("Fingerprint on display");
+ mPressedParams.setTitle("Fingerprint on display.touched");
+
+ mPressedView = new ImageView(context) {
+ @Override
+ protected void onDraw(Canvas canvas) {
+ if (mIsCircleShowing) {
+ canvas.drawCircle(mSize / 2, mSize / 2, mSize / 2.0f, mPaintFingerprint);
+ }
+ super.onDraw(canvas);
+ }
+ };
+ mPressedView.setImageResource(R.drawable.fod_icon_pressed);
+
+ mWindowManager.addView(this, mParams);
+
+ updatePosition();
+ hide();
+
+ mLockPatternUtils = new LockPatternUtils(mContext);
+
+ mUpdateMonitor = Dependency.get(KeyguardUpdateMonitor.class);
+ mUpdateMonitor.registerCallback(mMonitorCallback);
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ if (!mIsCircleShowing) {
+ canvas.drawCircle(mSize / 2, mSize / 2, mSize / 2.0f, mPaintFingerprintBackground);
+ }
+ super.onDraw(canvas);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ float x = event.getAxisValue(MotionEvent.AXIS_X);
+ float y = event.getAxisValue(MotionEvent.AXIS_Y);
+
+ boolean newIsInside = (x > 0 && x < mSize) && (y > 0 && y < mSize);
+
+ if (event.getAction() == MotionEvent.ACTION_DOWN && newIsInside) {
+ showCircle();
+ return true;
+ } else if (event.getAction() == MotionEvent.ACTION_UP) {
+ hideCircle();
+ return true;
+ } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
+ return true;
+ }
+
+ return false;
+ }
+
+ @Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ updatePosition();
+ }
+
+ public IFingerprintInscreen getFingerprintInScreenDaemon() {
+ if (mFingerprintInscreenDaemon == null) {
+ try {
+ mFingerprintInscreenDaemon = IFingerprintInscreen.getService();
+ if (mFingerprintInscreenDaemon != null) {
+ mFingerprintInscreenDaemon.setCallback(mFingerprintInscreenCallback);
+ mFingerprintInscreenDaemon.asBinder().linkToDeath((cookie) -> {
+ mFingerprintInscreenDaemon = null;
+ }, 0);
+ }
+ } catch (NoSuchElementException | RemoteException e) {
+ // do nothing
+ }
+ }
+ return mFingerprintInscreenDaemon;
+ }
+
+ public void dispatchPress() {
+ if (mFading) return;
+ IFingerprintInscreen daemon = getFingerprintInScreenDaemon();
+ try {
+ daemon.onPress();
+ } catch (RemoteException e) {
+ // do nothing
+ }
+ }
+
+ public void dispatchRelease() {
+ IFingerprintInscreen daemon = getFingerprintInScreenDaemon();
+ try {
+ daemon.onRelease();
+ } catch (RemoteException e) {
+ // do nothing
+ }
+ }
+
+ public void dispatchShow() {
+ IFingerprintInscreen daemon = getFingerprintInScreenDaemon();
+ try {
+ daemon.onShowFODView();
+ } catch (RemoteException e) {
+ // do nothing
+ }
+ }
+
+ public void dispatchHide() {
+ IFingerprintInscreen daemon = getFingerprintInScreenDaemon();
+ try {
+ daemon.onHideFODView();
+ } catch (RemoteException e) {
+ // do nothing
+ }
+ }
+
+ public void showCircle() {
+ if (mFading) return;
+ mIsCircleShowing = true;
+
+ setKeepScreenOn(true);
+
+ setDim(true);
+ dispatchPress();
+
+ setImageDrawable(null);
+ invalidate();
+ }
+
+ public void hideCircle() {
+ mIsCircleShowing = false;
+
+ setImageResource(R.drawable.fod_icon_default);
+ invalidate();
+
+ dispatchRelease();
+ setDim(false);
+
+ setKeepScreenOn(false);
+ }
+
+ public void show() {
+ if (!mUpdateMonitor.isScreenOn()) {
+ // Keyguard is shown just after screen turning off
+ return;
+ }
+
+ if (mIsBouncer && !isPinOrPattern(mUpdateMonitor.getCurrentUser())) {
+ // Ignore show calls when Keyguard password screen is being shown
+ return;
+ }
+
+ if (mIsKeyguard && mUpdateMonitor.getUserCanSkipBouncer(mUpdateMonitor.getCurrentUser())) {
+ // Ignore show calls if user can skip bouncer
+ return;
+ }
+
+ if (mIsKeyguard && !mIsBiometricRunning) {
+ return;
+ }
+
+ updatePosition();
+
+ setVisibility(View.VISIBLE);
+ animate().withStartAction(() -> mFading = true)
+ .alpha(mIsDreaming ? 0.5f : 1.0f)
+ .setDuration(FADE_ANIM_DURATION)
+ .withEndAction(() -> mFading = false)
+ .start();
+ dispatchShow();
+ }
+
+ public void hide() {
+ animate().withStartAction(() -> mFading = true)
+ .alpha(0)
+ .setDuration(FADE_ANIM_DURATION)
+ .withEndAction(() -> {
+ setVisibility(View.GONE);
+ mFading = false;
+ })
+ .start();
+ hideCircle();
+ dispatchHide();
+ }
+
+ private void updateAlpha() {
+ setAlpha(mIsDreaming ? 0.5f : 1.0f);
+ }
+
+ private void updatePosition() {
+ Display defaultDisplay = mWindowManager.getDefaultDisplay();
+
+ Point size = new Point();
+ defaultDisplay.getRealSize(size);
+
+ int rotation = defaultDisplay.getRotation();
+ int x, y;
+ switch (rotation) {
+ case Surface.ROTATION_0:
+ x = mPositionX;
+ y = mPositionY;
+ break;
+ case Surface.ROTATION_90:
+ x = mPositionY;
+ y = mPositionX;
+ break;
+ case Surface.ROTATION_180:
+ x = mPositionX;
+ y = size.y - mPositionY - mSize;
+ break;
+ case Surface.ROTATION_270:
+ x = size.x - mPositionY - mSize - mNavigationBarSize;
+ y = mPositionX;
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown rotation: " + rotation);
+ }
+
+ mPressedParams.x = mParams.x = x;
+ mPressedParams.y = mParams.y = y;
+
+ if (mIsDreaming) {
+ mParams.x += mDreamingOffsetX;
+ mParams.y += mDreamingOffsetY;
+ }
+
+ mWindowManager.updateViewLayout(this, mParams);
+
+ if (mPressedView.getParent() != null) {
+ mWindowManager.updateViewLayout(mPressedView, mPressedParams);
+ }
+ }
+
+ private void setDim(boolean dim) {
+ if (dim) {
+ int curBrightness = Settings.System.getInt(getContext().getContentResolver(),
+ Settings.System.SCREEN_BRIGHTNESS, 100);
+ int dimAmount = 0;
+
+ IFingerprintInscreen daemon = getFingerprintInScreenDaemon();
+ try {
+ dimAmount = daemon.getDimAmount(curBrightness);
+ } catch (RemoteException e) {
+ // do nothing
+ }
+
+ if (mShouldBoostBrightness) {
+ mPressedParams.screenBrightness = 1.0f;
+ }
+
+ mPressedParams.dimAmount = dimAmount / 255.0f;
+ if (mPressedView.getParent() == null) {
+ mWindowManager.addView(mPressedView, mPressedParams);
+ } else {
+ mWindowManager.updateViewLayout(mPressedView, mPressedParams);
+ }
+ } else {
+ if (mShouldBoostBrightness) {
+ mPressedParams.screenBrightness = 0.0f;
+ }
+ mPressedParams.dimAmount = 0.0f;
+ if (mPressedView.getParent() != null) {
+ mWindowManager.removeView(mPressedView);
+ }
+ }
+ }
+
+ private boolean isPinOrPattern(int userId) {
+ int passwordQuality = mLockPatternUtils.getActivePasswordQuality(userId);
+ switch (passwordQuality) {
+ // PIN
+ case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
+ case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
+ // Pattern
+ case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
+ return true;
+ }
+
+ return false;
+ }
+
+ private class BurnInProtectionTask extends TimerTask {
+ @Override
+ public void run() {
+ long now = System.currentTimeMillis() / 1000 / 60;
+
+ mDreamingOffsetX = (int) (now % (mDreamingMaxOffset * 4));
+ if (mDreamingOffsetX > mDreamingMaxOffset * 2) {
+ mDreamingOffsetX = mDreamingMaxOffset * 4 - mDreamingOffsetX;
+ }
+
+ // Let y to be not synchronized with x, so that we get maximum movement
+ mDreamingOffsetY = (int) ((now + mDreamingMaxOffset / 3) % (mDreamingMaxOffset * 2));
+ if (mDreamingOffsetY > mDreamingMaxOffset * 2) {
+ mDreamingOffsetY = mDreamingMaxOffset * 4 - mDreamingOffsetY;
+ }
+
+ mDreamingOffsetX -= mDreamingMaxOffset;
+ mDreamingOffsetY -= mDreamingMaxOffset;
+
+ mHandler.post(() -> updatePosition());
+ }
+ };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/FODCircleViewImpl.java b/packages/SystemUI/src/com/android/systemui/biometrics/FODCircleViewImpl.java
new file mode 100644
index 0000000..127e47a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/FODCircleViewImpl.java
@@ -0,0 +1,72 @@
+/**
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.biometrics;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.util.Slog;
+import android.view.View;
+
+import com.android.systemui.SystemUI;
+import com.android.systemui.statusbar.CommandQueue;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+@Singleton
+public class FODCircleViewImpl extends SystemUI implements CommandQueue.Callbacks {
+ private static final String TAG = "FODCircleViewImpl";
+
+ private FODCircleView mFodCircleView;
+ private final CommandQueue mCommandQueue;
+
+ @Inject
+ public FODCircleViewImpl(Context context, CommandQueue commandQueue) {
+ super(context);
+ mCommandQueue = commandQueue;
+ }
+
+ @Override
+ public void start() {
+ PackageManager packageManager = mContext.getPackageManager();
+ if (!packageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT) ||
+ !mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_needCustomFODView)) {
+ return;
+ }
+ mCommandQueue.addCallback(this);
+ try {
+ mFodCircleView = new FODCircleView(mContext);
+ } catch (RuntimeException e) {
+ Slog.e(TAG, "Failed to initialize FODCircleView", e);
+ }
+ }
+
+ @Override
+ public void showInDisplayFingerprintView() {
+ if (mFodCircleView != null) {
+ mFodCircleView.show();
+ }
+ }
+
+ @Override
+ public void hideInDisplayFingerprintView() {
+ if (mFodCircleView != null) {
+ mFodCircleView.hide();
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/bliss/batterybar/BatteryBar.java b/packages/SystemUI/src/com/android/systemui/bliss/batterybar/BatteryBar.java
new file mode 100644
index 0000000..fc25511
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/bliss/batterybar/BatteryBar.java
@@ -0,0 +1,348 @@
+/*
+ * Copyright (C) 2010 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.bliss.batterybar;
+
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.database.ContentObserver;
+import android.graphics.Color;
+import android.graphics.drawable.Animatable;
+import android.os.BatteryManager;
+import android.os.Handler;
+import android.provider.Settings;
+import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.View;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.Animation;
+import android.view.animation.TranslateAnimation;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+
+public class BatteryBar extends RelativeLayout implements Animatable {
+
+ private static final String TAG = BatteryBar.class.getSimpleName();
+
+ // Total animation duration
+ private static final int ANIM_DURATION = 1000; // 5 seconds
+
+ // When to use the low battery color
+ private static final int BATTERY_LOW_VALUE = 15;
+
+ private boolean mAttached = false;
+ private int mBatteryLevel = 0;
+ private int mChargingLevel = -1;
+ private boolean mBatteryCharging = false;
+ private boolean shouldAnimateCharging = true;
+ private boolean isAnimating = false;
+
+ private int mColor = 0xFFFFFFFF;
+ private int mChargingColor = 0xFFFFFFFF;
+ private int mBatteryLowColor = 0xFFFFFFFF;
+ private boolean mUseChargingColor = true;
+ private boolean mBlendColors = false;
+ private boolean mBlendColorsReversed = false;
+
+ private Handler mHandler = new Handler();
+
+ LinearLayout mBatteryBarLayout;
+ View mBatteryBar;
+
+ LinearLayout mChargerLayout;
+ View mCharger;
+
+ public static final int STYLE_REGULAR = 0;
+ public static final int STYLE_SYMMETRIC = 1;
+
+ boolean vertical = false;
+
+ class SettingsObserver extends ContentObserver {
+
+ public SettingsObserver(Handler handler) {
+ super(handler);
+ }
+
+ void observer() {
+ ContentResolver resolver = mContext.getContentResolver();
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.STATUSBAR_BATTERY_BAR), false, this);
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.STATUSBAR_BATTERY_BAR_COLOR), false,
+ this);
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.STATUSBAR_BATTERY_BAR_CHARGING_COLOR),
+ false, this);
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(
+ Settings.System.STATUSBAR_BATTERY_BAR_BATTERY_LOW_COLOR), false, this);
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.STATUSBAR_BATTERY_BAR_ANIMATE),
+ false, this);
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(
+ Settings.System.STATUSBAR_BATTERY_BAR_ENABLE_CHARGING_COLOR), false,
+ this);
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.STATUSBAR_BATTERY_BAR_BLEND_COLORS),
+ false, this);
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(
+ Settings.System.STATUSBAR_BATTERY_BAR_BLEND_COLORS_REVERSE), false,
+ this);
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ updateSettings();
+ }
+ }
+
+ public BatteryBar(Context context) {
+ this(context, null);
+ }
+
+ public BatteryBar(Context context, boolean isCharging, int currentCharge) {
+ this(context, null);
+
+ mBatteryLevel = currentCharge;
+ mBatteryCharging = isCharging;
+ }
+
+ public BatteryBar(Context context, boolean isCharging, int currentCharge, boolean isVertical) {
+ this(context, null);
+
+ mBatteryLevel = currentCharge;
+ mBatteryCharging = isCharging;
+ vertical = isVertical;
+ }
+
+ public BatteryBar(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public BatteryBar(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ if (!mAttached) {
+ mAttached = true;
+
+ mBatteryBarLayout = new LinearLayout(mContext);
+ addView(mBatteryBarLayout, new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT,
+ LayoutParams.MATCH_PARENT));
+
+ mBatteryBar = new View(mContext);
+ mBatteryBarLayout.addView(mBatteryBar, new LinearLayout.LayoutParams(
+ LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
+
+ DisplayMetrics metrics = getContext().getResources().getDisplayMetrics();
+ float dp = 4f;
+ int pixels = (int) (metrics.density * dp + 0.5f);
+
+ // charger
+ mChargerLayout = new LinearLayout(mContext);
+
+ if (vertical)
+ addView(mChargerLayout, new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT,
+ pixels));
+ else
+ addView(mChargerLayout, new RelativeLayout.LayoutParams(pixels,
+ LayoutParams.MATCH_PARENT));
+
+ mCharger = new View(mContext);
+ mChargerLayout.setVisibility(View.GONE);
+ mChargerLayout.addView(mCharger, new LinearLayout.LayoutParams(
+ LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
+
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_BATTERY_CHANGED);
+ filter.addAction(Intent.ACTION_SCREEN_OFF);
+ filter.addAction(Intent.ACTION_SCREEN_ON);
+ getContext().registerReceiver(mIntentReceiver, filter, null, getHandler());
+
+ SettingsObserver observer = new SettingsObserver(mHandler);
+ observer.observer();
+ updateSettings();
+ }
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ if (mAttached) {
+ mAttached = false;
+ getContext().unregisterReceiver(mIntentReceiver);
+ }
+ }
+
+ private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+
+ if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
+ mBatteryLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
+ mBatteryCharging = intent.getIntExtra(BatteryManager.EXTRA_STATUS, 0) == BatteryManager.BATTERY_STATUS_CHARGING;
+ if (mBatteryCharging && mBatteryLevel < 100) {
+ start();
+ } else {
+ stop();
+ }
+ setProgress(mBatteryLevel);
+ } else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
+ stop();
+ } else if (Intent.ACTION_SCREEN_ON.equals(action)) {
+ if (mBatteryCharging && mBatteryLevel < 100) {
+ start();
+ }
+ }
+ }
+ };
+
+ private void updateSettings() {
+ ContentResolver resolver = getContext().getContentResolver();
+
+ mColor = Settings.System.getInt(resolver,
+ Settings.System.STATUSBAR_BATTERY_BAR_COLOR, 0xFFFFFFFF);
+ mChargingColor = Settings.System.getInt(resolver,
+ Settings.System.STATUSBAR_BATTERY_BAR_CHARGING_COLOR, 0xFFFFFFFF);
+ mBatteryLowColor = Settings.System.getInt(resolver,
+ Settings.System.STATUSBAR_BATTERY_BAR_BATTERY_LOW_COLOR, 0xFFFFFFFF);
+
+ shouldAnimateCharging = Settings.System.getInt(resolver,
+ Settings.System.STATUSBAR_BATTERY_BAR_ANIMATE, 0) == 1;
+
+ mUseChargingColor = Settings.System.getInt(resolver,
+ Settings.System.STATUSBAR_BATTERY_BAR_ENABLE_CHARGING_COLOR, 1) == 1;
+ mBlendColors = Settings.System.getInt(resolver,
+ Settings.System.STATUSBAR_BATTERY_BAR_BLEND_COLORS, 0) == 1;
+ mBlendColorsReversed = Settings.System.getInt(resolver,
+ Settings.System.STATUSBAR_BATTERY_BAR_BLEND_COLORS_REVERSE, 0) == 1;
+
+ if (mBatteryCharging && mBatteryLevel < 100 && shouldAnimateCharging) {
+ start();
+ } else {
+ stop();
+ }
+ setProgress(mBatteryLevel);
+ }
+
+ private void setProgress(int n) {
+ if (vertical) {
+ int w = (int) (((getHeight() / 100.0) * n) + 0.5);
+ RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mBatteryBarLayout
+ .getLayoutParams();
+ params.height = w;
+ mBatteryBarLayout.setLayoutParams(params);
+
+ } else {
+ int w = (int) (((getWidth() / 100.0) * n) + 0.5);
+ RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mBatteryBarLayout
+ .getLayoutParams();
+ params.width = w;
+ mBatteryBarLayout.setLayoutParams(params);
+ }
+
+ // Update color
+ int color = getColorForPercent(n);
+ mBatteryBar.setBackgroundColor(color);
+ mCharger.setBackgroundColor(color);
+
+ }
+
+ @Override
+ public void start() {
+ if (!shouldAnimateCharging)
+ return;
+
+ if (vertical) {
+ TranslateAnimation a = new TranslateAnimation(getX(), getX(), getHeight(),
+ mBatteryBarLayout.getHeight());
+ a.setInterpolator(new AccelerateInterpolator());
+ a.setDuration(ANIM_DURATION);
+ a.setRepeatCount(Animation.INFINITE);
+ mChargerLayout.startAnimation(a);
+ mChargerLayout.setVisibility(View.VISIBLE);
+ } else {
+ TranslateAnimation a = new TranslateAnimation(getWidth(), mBatteryBarLayout.getWidth(),
+ getTop(), getTop());
+ a.setInterpolator(new AccelerateInterpolator());
+ a.setDuration(ANIM_DURATION);
+ a.setRepeatCount(Animation.INFINITE);
+ mChargerLayout.startAnimation(a);
+ mChargerLayout.setVisibility(View.VISIBLE);
+ }
+ isAnimating = true;
+ }
+
+ @Override
+ public void stop() {
+ mChargerLayout.clearAnimation();
+ mChargerLayout.setVisibility(View.GONE);
+ isAnimating = false;
+ }
+
+ @Override
+ public boolean isRunning() {
+ return isAnimating;
+ }
+
+ private int getColorForPercent(int percentage) {
+ if (mBatteryCharging && mUseChargingColor) {
+ return mChargingColor;
+ } else if (mBlendColors) {
+ float[] newColor = new float[3];
+ float[] empty = new float[3];
+ float[] full = new float[3];
+ Color.colorToHSV(mColor, full);
+ int fullAlpha = Color.alpha(mColor);
+ Color.colorToHSV(mBatteryLowColor, empty);
+ int emptyAlpha = Color.alpha(mBatteryLowColor);
+ float blendFactor = percentage/100f;
+ if (mBlendColorsReversed) {
+ if (empty[0] < full[0]) {
+ empty[0] += 360f;
+ }
+ newColor[0] = empty[0] - (empty[0]-full[0])*blendFactor;
+ } else {
+ if (empty[0] > full[0]) {
+ full[0] += 360f;
+ }
+ newColor[0] = empty[0] + (full[0]-empty[0])*blendFactor;
+ }
+ if (newColor[0] > 360f) {
+ newColor[0] -= 360f;
+ } else if (newColor[0] < 0) {
+ newColor[0] += 360f;
+ }
+ newColor[1] = empty[1] + ((full[1]-empty[1])*blendFactor);
+ newColor[2] = empty[2] + ((full[2]-empty[2])*blendFactor);
+ int newAlpha = (int) (emptyAlpha + ((fullAlpha-emptyAlpha)*blendFactor));
+ return Color.HSVToColor(newAlpha, newColor);
+ } else {
+ return percentage > BATTERY_LOW_VALUE ? mColor : mBatteryLowColor;
+ }
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/bliss/batterybar/BatteryBarController.java b/packages/SystemUI/src/com/android/systemui/bliss/batterybar/BatteryBarController.java
new file mode 100644
index 0000000..65ff5f5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/bliss/batterybar/BatteryBarController.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2010 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.bliss.batterybar;
+
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Configuration;
+import android.database.ContentObserver;
+import android.os.BatteryManager;
+import android.os.Handler;
+import android.provider.Settings;
+import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+
+public class BatteryBarController extends LinearLayout {
+
+ private static final String TAG = "BatteryBarController";
+
+ BatteryBar mainBar;
+ BatteryBar alternateStyleBar;
+
+ public static final int STYLE_REGULAR = 0;
+ public static final int STYLE_SYMMETRIC = 1;
+ public static final int STYLE_REVERSE = 2;
+
+ int mStyle = STYLE_REGULAR;
+ int mLocation = 0;
+
+ protected final static int CURRENT_LOC = 1;
+ int mLocationToLookFor = 0;
+
+ private int mBatteryLevel = 0;
+ private boolean mBatteryCharging = false;
+
+ boolean isAttached = false;
+ boolean isVertical = false;
+
+ class SettingsObserver extends ContentObserver {
+
+ public SettingsObserver(Handler handler) {
+ super(handler);
+ }
+
+ void observer() {
+ ContentResolver resolver = mContext.getContentResolver();
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.STATUSBAR_BATTERY_BAR), false, this);
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.STATUSBAR_BATTERY_BAR_STYLE), false,
+ this);
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.STATUSBAR_BATTERY_BAR_THICKNESS),
+ false, this);
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ updateSettings();
+ }
+ }
+
+ public BatteryBarController(Context context, AttributeSet attrs) {
+ super(context, attrs);
+
+ if (attrs != null) {
+ String ns = "http://schemas.android.com/apk/res/com.android.systemui";
+ mLocationToLookFor = attrs.getAttributeIntValue(ns, "viewLocation", 0);
+ }
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ if (!isAttached) {
+ isVertical = (getLayoutParams().height == LayoutParams.MATCH_PARENT);
+
+ isAttached = true;
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_BATTERY_CHANGED);
+ getContext().registerReceiver(mIntentReceiver, filter);
+
+ SettingsObserver observer = new SettingsObserver(new Handler());
+ observer.observer();
+ updateSettings();
+ }
+ }
+
+ private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+
+ if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
+ mBatteryLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
+ mBatteryCharging = intent.getIntExtra(BatteryManager.EXTRA_STATUS, 0) == BatteryManager.BATTERY_STATUS_CHARGING;
+ Prefs.setLastBatteryLevel(context, mBatteryLevel);
+ }
+ }
+ };
+
+ @Override
+ protected void onDetachedFromWindow() {
+ if (isAttached) {
+ isAttached = false;
+ removeBars();
+ }
+ super.onDetachedFromWindow();
+ }
+
+ @Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ if (isAttached) {
+ getHandler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ updateSettings();
+ }
+ }, 500);
+
+ }
+ }
+
+ public void addBars() {
+ // set heights
+ DisplayMetrics metrics = getContext().getResources().getDisplayMetrics();
+ float dp = (float) Settings.System.getInt(getContext().getContentResolver(),
+ Settings.System.STATUSBAR_BATTERY_BAR_THICKNESS, 1);
+ int pixels = (int) ((metrics.density * dp) + 0.5);
+
+ ViewGroup.LayoutParams params = (ViewGroup.LayoutParams) getLayoutParams();
+
+ if (isVertical)
+ params.width = pixels;
+ else
+ params.height = pixels;
+ setLayoutParams(params);
+
+ if (isVertical)
+ params.width = pixels;
+ else
+ params.height = pixels;
+ setLayoutParams(params);
+ mBatteryLevel = Prefs.getLastBatteryLevel(getContext());
+ if (mStyle == STYLE_REGULAR) {
+ addView(new BatteryBar(mContext, mBatteryCharging, mBatteryLevel, isVertical),
+ new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,
+ LayoutParams.MATCH_PARENT, 1));
+ } else if (mStyle == STYLE_SYMMETRIC) {
+ BatteryBar bar1 = new BatteryBar(mContext, mBatteryCharging, mBatteryLevel, isVertical);
+ BatteryBar bar2 = new BatteryBar(mContext, mBatteryCharging, mBatteryLevel, isVertical);
+
+ if (isVertical) {
+ bar2.setRotation(180);
+ addView(bar2, (new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,
+ LayoutParams.MATCH_PARENT, 1)));
+ addView(bar1, (new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,
+ LayoutParams.MATCH_PARENT, 1)));
+ } else {
+ bar1.setRotation(180);
+ addView(bar1, (new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,
+ LayoutParams.MATCH_PARENT, 1)));
+ addView(bar2, (new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,
+ LayoutParams.MATCH_PARENT, 1)));
+ }
+ } else if (mStyle == STYLE_REVERSE) {
+ BatteryBar bar = new BatteryBar(mContext, mBatteryCharging, mBatteryLevel, isVertical);
+ bar.setRotation(180);
+ addView(bar, new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,
+ LayoutParams.MATCH_PARENT, 1));
+
+ }
+ }
+
+ public void removeBars() {
+ removeAllViews();
+ }
+
+ public void updateSettings() {
+ mStyle = Settings.System.getInt(getContext().getContentResolver(),
+ Settings.System.STATUSBAR_BATTERY_BAR_STYLE, 0);
+ mLocation = Settings.System.getInt(getContext().getContentResolver(),
+ Settings.System.STATUSBAR_BATTERY_BAR, 0);
+
+ if (mLocation > 0 && isLocationValid(mLocation)) {
+ removeBars();
+ addBars();
+ setVisibility(View.VISIBLE);
+ } else {
+ removeBars();
+ setVisibility(View.GONE);
+ }
+ }
+
+ protected boolean isLocationValid(int location) {
+ return mLocationToLookFor == location;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/bliss/batterybar/Prefs.java b/packages/SystemUI/src/com/android/systemui/bliss/batterybar/Prefs.java
new file mode 100644
index 0000000..7301b4e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/bliss/batterybar/Prefs.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2010 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.bliss.batterybar;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+
+public class Prefs {
+ private static final String SHARED_PREFS_NAME = "status_bar";
+
+ public static final String LAST_BATTERY_LEVEL = "last_battery_level";
+
+ public static SharedPreferences read(Context context) {
+ return context.getSharedPreferences(Prefs.SHARED_PREFS_NAME, Context.MODE_PRIVATE);
+ }
+
+ public static SharedPreferences.Editor edit(Context context) {
+ return context.getSharedPreferences(Prefs.SHARED_PREFS_NAME, Context.MODE_PRIVATE).edit();
+ }
+
+ public static void setLastBatteryLevel(Context context, int level) {
+ edit(context).putInt(LAST_BATTERY_LEVEL, level).commit();
+ }
+
+ public static int getLastBatteryLevel(Context context) {
+ return read(context).getInt(LAST_BATTERY_LEVEL, 50);
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/bliss/carrierlabel/CarrierLabel.java b/packages/SystemUI/src/com/android/systemui/bliss/carrierlabel/CarrierLabel.java
new file mode 100644
index 0000000..0c61120
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/bliss/carrierlabel/CarrierLabel.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2014-2015 The MoKee OpenSource 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.bliss.carrierlabel;
+
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.database.ContentObserver;
+import android.graphics.Rect;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+import android.widget.TextView;
+
+import com.android.internal.util.bliss.BlissUtils;
+import com.android.internal.telephony.TelephonyIntents;
+
+import com.android.systemui.Dependency;
+import com.android.systemui.bliss.carrierlabel.SpnOverride;
+import com.android.systemui.plugins.DarkIconDispatcher;
+import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
+
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.TimeZone;
+
+import com.android.systemui.R;
+
+public class CarrierLabel extends TextView implements DarkReceiver {
+
+ private Context mContext;
+ private boolean mAttached;
+ private static boolean isCN;
+
+ public CarrierLabel(Context context) {
+ this(context, null);
+ }
+
+ public CarrierLabel(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public CarrierLabel(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ mContext = context;
+ updateNetworkName(true, null, false, null);
+ /* Force carrier label to the lockscreen. This helps us avoid
+ the carrier label on the statusbar if for whatever reason
+ the user changes notch overlays */
+ if (BlissUtils.hasNotch(mContext)) {
+ Settings.System.putInt(mContext.getContentResolver(),
+ Settings.System.STATUS_BAR_SHOW_CARRIER, 1);
+ }
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ Dependency.get(DarkIconDispatcher.class).addDarkReceiver(this);
+ if (!mAttached) {
+ mAttached = true;
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED);
+ filter.addAction(Intent.ACTION_CUSTOM_CARRIER_LABEL_CHANGED);
+ mContext.registerReceiver(mIntentReceiver, filter, null, getHandler());
+ }
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ Dependency.get(DarkIconDispatcher.class).removeDarkReceiver(this);
+ if (mAttached) {
+ mContext.unregisterReceiver(mIntentReceiver);
+ mAttached = false;
+ }
+ }
+
+ @Override
+ public void onDarkChanged(Rect area, float darkIntensity, int tint) {
+ setTextColor(DarkIconDispatcher.getTint(area, this, tint));
+ }
+
+ private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED.equals(action)
+ || Intent.ACTION_CUSTOM_CARRIER_LABEL_CHANGED.equals(action)) {
+ updateNetworkName(intent.getBooleanExtra(TelephonyManager.EXTRA_SHOW_SPN, true),
+ intent.getStringExtra(TelephonyManager.EXTRA_SPN),
+ intent.getBooleanExtra(TelephonyManager.EXTRA_SHOW_PLMN, false),
+ intent.getStringExtra(TelephonyManager.EXTRA_PLMN));
+ isCN = BlissUtils.isChineseLanguage();
+ }
+ }
+ };
+
+ void updateNetworkName(boolean showSpn, String spn, boolean showPlmn, String plmn) {
+ final String str;
+ final boolean plmnValid = showPlmn && !TextUtils.isEmpty(plmn);
+ final boolean spnValid = showSpn && !TextUtils.isEmpty(spn);
+ if (spnValid) {
+ str = spn;
+ } else if (plmnValid) {
+ str = plmn;
+ } else {
+ str = "";
+ }
+ String customCarrierLabel = Settings.System.getStringForUser(mContext.getContentResolver(),
+ Settings.System.CUSTOM_CARRIER_LABEL, UserHandle.USER_CURRENT);
+ if (!TextUtils.isEmpty(customCarrierLabel)) {
+ setText(customCarrierLabel);
+ } else {
+ setText(TextUtils.isEmpty(str) ? getOperatorName() : str);
+ }
+ }
+
+ private String getOperatorName() {
+ String operatorName = getContext().getString(R.string.quick_settings_wifi_no_network);
+ TelephonyManager telephonyManager = (TelephonyManager) getContext().getSystemService(
+ Context.TELEPHONY_SERVICE);
+ if (isCN) {
+ String operator = telephonyManager.getNetworkOperator();
+ if (TextUtils.isEmpty(operator)) {
+ operator = telephonyManager.getSimOperator();
+ }
+ SpnOverride mSpnOverride = new SpnOverride();
+ operatorName = mSpnOverride.getSpn(operator);
+ } else {
+ operatorName = telephonyManager.getNetworkOperatorName();
+ }
+ if (TextUtils.isEmpty(operatorName)) {
+ operatorName = telephonyManager.getSimOperatorName();
+ }
+ return operatorName;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/bliss/carrierlabel/SpnOverride.java b/packages/SystemUI/src/com/android/systemui/bliss/carrierlabel/SpnOverride.java
new file mode 100644
index 0000000..843e26c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/bliss/carrierlabel/SpnOverride.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2014 The MoKee OpenSource 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.bliss.carrierlabel;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.HashMap;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.os.Environment;
+import android.telephony.Rlog;
+import android.util.Xml;
+
+import com.android.internal.util.XmlUtils;
+
+public class SpnOverride {
+ private HashMap<String, String> mCarrierSpnMap;
+
+
+ static final String LOG_TAG = "SpnOverride";
+ static final String PARTNER_SPN_OVERRIDE_PATH ="etc/spn-conf.xml";
+
+ public SpnOverride () {
+ mCarrierSpnMap = new HashMap<String, String>();
+ loadSpnOverrides();
+ }
+
+ public boolean containsCarrier(String carrier) {
+ return mCarrierSpnMap.containsKey(carrier);
+ }
+
+ public String getSpn(String carrier) {
+ return mCarrierSpnMap.get(carrier);
+ }
+
+ private void loadSpnOverrides() {
+ FileReader spnReader;
+
+ final File spnFile = new File(Environment.getRootDirectory(),
+ PARTNER_SPN_OVERRIDE_PATH);
+
+ try {
+ spnReader = new FileReader(spnFile);
+ } catch (FileNotFoundException e) {
+ Rlog.w(LOG_TAG, "Can not open " +
+ Environment.getRootDirectory() + "/" + PARTNER_SPN_OVERRIDE_PATH);
+ return;
+ }
+
+ try {
+ XmlPullParser parser = Xml.newPullParser();
+ parser.setInput(spnReader);
+
+ XmlUtils.beginDocument(parser, "spnOverrides");
+
+ while (true) {
+ XmlUtils.nextElement(parser);
+
+ String name = parser.getName();
+ if (!"spnOverride".equals(name)) {
+ break;
+ }
+
+ String numeric = parser.getAttributeValue(null, "numeric");
+ String data = parser.getAttributeValue(null, "spn");
+
+ mCarrierSpnMap.put(numeric, data);
+ }
+ spnReader.close();
+ } catch (XmlPullParserException e) {
+ Rlog.w(LOG_TAG, "Exception in spn-conf parser " + e);
+ } catch (IOException e) {
+ Rlog.w(LOG_TAG, "Exception in spn-conf parser " + e);
+ }
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
index f35322b..4ba814d 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
@@ -20,6 +20,7 @@
import android.content.Context;
import android.hardware.SensorManager;
+import android.content.res.Resources;
import android.net.Uri;
import android.provider.DeviceConfig;
import android.view.MotionEvent;
@@ -29,6 +30,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.Dumpable;
+import com.android.systemui.R;
import com.android.systemui.classifier.brightline.BrightLineFalsingManager;
import com.android.systemui.classifier.brightline.FalsingDataProvider;
import com.android.systemui.dagger.qualifiers.Main;
@@ -129,8 +131,10 @@
* Chooses the FalsingManager implementation.
*/
private void setupFalsingManager(Context context) {
+ Resources res = context.getResources();
boolean brightlineEnabled = mDeviceConfig.getBoolean(
- DeviceConfig.NAMESPACE_SYSTEMUI, BRIGHTLINE_FALSING_MANAGER_ENABLED, true);
+ DeviceConfig.NAMESPACE_SYSTEMUI, BRIGHTLINE_FALSING_MANAGER_ENABLED,
+ res.getBoolean(R.bool.config_lockscreenAntiFalsingClassifierEnabled));
if (brightlineEnabled == mBrightlineEnabled && mInternalFalsingManager != null) {
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
index 413a522..a0a2e6f 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
@@ -24,6 +24,7 @@
import com.android.systemui.accessibility.SystemActions;
import com.android.systemui.accessibility.WindowMagnification;
import com.android.systemui.biometrics.AuthController;
+import com.android.systemui.biometrics.FODCircleViewImpl;
import com.android.systemui.bubbles.dagger.BubbleModule;
import com.android.systemui.globalactions.GlobalActionsComponent;
import com.android.systemui.keyguard.KeyguardViewMediator;
@@ -66,6 +67,12 @@
@ClassKey(Divider.class)
public abstract SystemUI bindDivider(Divider sysui);
+ /** Inject into FODCircleViewImpl. */
+ @Binds
+ @IntoMap
+ @ClassKey(FODCircleViewImpl.class)
+ public abstract SystemUI FODCircleViewImpl(FODCircleViewImpl sysui);
+
/** Inject into GarbageMonitor.Service. */
@Binds
@IntoMap
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
index 9c25b35..f8a172f 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
@@ -48,7 +48,7 @@
* @param x Touch X, or -1 if sensor doesn't support touch location.
* @param y Touch Y, or -1 if sensor doesn't support touch location.
*/
- void onSlpiTap(float x, float y);
+ void onSlpiTap(float x, float y, int pulseReason);
/**
* Artificially dim down the the display by changing scrim opacities.
@@ -98,12 +98,24 @@
*/
default void onPowerSaveChanged(boolean active) {}
+ default void wakeUpFromDoubleTap(int pulseReason) {}
+
+ default void skipTrack() {}
+
/** Called when the doze suppression state changes. */
default void onDozeSuppressedChanged(boolean suppressed) {}
+
+ default void toggleFlashlightProximityCheck() {}
+
+ default void triggerActionProximityCheck(String action) {}
}
interface PulseCallback {
void onPulseStarted();
void onPulseFinished();
}
+
+ void performToggleFlashlight();
+
+ void performTriggeredAction(String action);
}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
index a311a45..68b63e7 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
@@ -339,6 +339,8 @@
case PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN: return "wakelockscreen";
case REASON_SENSOR_WAKE_UP: return "wakeup";
case REASON_SENSOR_TAP: return "tap";
+ case REASON_TOGGLE_FLASHLIGHT: return "flashlight";
+ case REASON_TRIGGER_ACTION: return "triggeraction";
default: throw new IllegalArgumentException("invalid reason: " + pulseReason);
}
}
@@ -347,7 +349,7 @@
@IntDef({PULSE_REASON_NONE, PULSE_REASON_INTENT, PULSE_REASON_NOTIFICATION,
PULSE_REASON_SENSOR_SIGMOTION, REASON_SENSOR_PICKUP, REASON_SENSOR_DOUBLE_TAP,
PULSE_REASON_SENSOR_LONG_PRESS, PULSE_REASON_DOCKING, REASON_SENSOR_WAKE_UP,
- PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN, REASON_SENSOR_TAP})
+ PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN, REASON_SENSOR_TAP, REASON_TOGGLE_FLASHLIGHT, REASON_TRIGGER_ACTION})
public @interface Reason {}
public static final int PULSE_REASON_NONE = -1;
public static final int PULSE_REASON_INTENT = 0;
@@ -360,6 +362,8 @@
public static final int REASON_SENSOR_WAKE_UP = 7;
public static final int PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN = 8;
public static final int REASON_SENSOR_TAP = 9;
+ public static final int REASON_TOGGLE_FLASHLIGHT = 10;
+ public static final int REASON_TRIGGER_ACTION = 11;
- public static final int TOTAL_REASONS = 10;
+ public static final int TOTAL_REASONS = 12;
}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index cbf8f57..2f3b402 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -43,6 +43,7 @@
import com.android.systemui.dock.DockManager;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.util.Assert;
+import com.android.internal.util.bliss.LineageButtons;
import com.android.systemui.util.sensors.AsyncSensorManager;
import com.android.systemui.util.sensors.ProximitySensor;
import com.android.systemui.util.wakelock.WakeLock;
@@ -263,10 +264,17 @@
return;
}
if (isDoubleTap || isTap) {
- if (screenX != -1 && screenY != -1) {
- mDozeHost.onSlpiTap(screenX, screenY);
+ /* if in AoD try to trigger the double tap to skip Track otherwise just wake up gently.
+ Without this check, when screen is OFF and AoD disabled, we could trigger the skip track action
+ by mistake if tapping in the area where track infos are supposed to show up, even before
+ waking up to lockscreen or ambient*/
+ if (!mConfig.deviceHasSoli() && screenX != -1 && screenY != -1
+ && mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT)
+ /*|| mMachine.getState() == DozeMachine.State.DOZE_PULSING*/) {
+ mDozeHost.onSlpiTap(screenX, screenY, pulseReason);
+ } else {
+ gentleWakeUp(pulseReason);
}
- gentleWakeUp(pulseReason);
} else if (isPickup) {
gentleWakeUp(pulseReason);
} else {
@@ -285,6 +293,11 @@
}
private void gentleWakeUp(int reason) {
+ if (!mConfig.deviceHasSoli() && !mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT)
+ && mConfig.isAmbientGestureEnabled(UserHandle.USER_CURRENT)) {
+ requestPulse(reason, true /* alreadyPerformedProxCheck */, null /* onPulseSupressedListener */);
+ return;
+ }
// Log screen wake up reason (lift/pickup, tap, double-tap)
mMetricsLogger.write(new LogMaker(MetricsEvent.DOZING)
.setType(MetricsEvent.TYPE_UPDATE)
@@ -433,7 +446,12 @@
|| state == Display.STATE_OFF) {
mDozeSensors.setProxListening(mWantProx);
mDozeSensors.setListening(mWantSensors);
- mDozeSensors.setTouchscreenSensorsListening(mWantTouchScreenSensors);
+ if (mConfig.deviceHasWeirtdDtSensor() && mWantTouchScreenSensors) {
+ mDozeSensors.setTouchscreenSensorsListening(false);
+ mDozeSensors.setTouchscreenSensorsListening(true);
+ } else {
+ mDozeSensors.setTouchscreenSensorsListening(mWantTouchScreenSensors);
+ }
} else {
mDozeSensors.setProxListening(false);
mDozeSensors.setListening(mWantSensors);
@@ -448,6 +466,30 @@
}
}
+ private void tryToggleFlashlight() {
+ proximityCheckThenCall((result) -> {
+ if (result != null && result) {
+ // in pocket, abort pulse
+ return;
+ } else {
+ // not in pocket, toggle flashlight
+ mDozeHost.performToggleFlashlight();
+ }
+ }, false/*performedProxCheck*/, DozeLog.REASON_TOGGLE_FLASHLIGHT);
+ }
+
+ private void tryTriggerAction(String action) {
+ proximityCheckThenCall((result) -> {
+ if (result != null && result) {
+ // in pocket, abort pulse
+ return;
+ } else {
+ // not in pocket, trigger action
+ mDozeHost.performTriggeredAction(action);
+ }
+ }, false/*performedProxCheck*/, DozeLog.REASON_TRIGGER_ACTION);
+ }
+
private void requestPulse(final int reason, boolean performedProxCheck,
Runnable onPulseSuppressedListener) {
Assert.isMainThread();
@@ -598,5 +640,25 @@
}
mMachine.requestState(nextState);
}
+
+ @Override
+ public void toggleFlashlightProximityCheck() {
+ tryToggleFlashlight();
+ }
+
+ @Override
+ public void triggerActionProximityCheck(String action) {
+ tryTriggerAction(action);
+ }
+
+ @Override
+ public void wakeUpFromDoubleTap(int pulseReason) {
+ gentleWakeUp(pulseReason);
+ }
+
+ @Override
+ public void skipTrack() {
+ LineageButtons.getAttachedInstance(mContext).skipTrack();
+ }
};
}
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java
index b29c5b0..f7b53c1 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java
@@ -121,4 +121,12 @@
} catch (RemoteException e) {
}
}
+
+ @Override
+ public void advancedReboot(String mode) {
+ try {
+ mBarService.advancedReboot(mode);
+ } catch (RemoteException e) {
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index ff25439a..1f0f42b 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -27,6 +27,8 @@
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_GLOBAL_ACTIONS_SHOWING;
+import com.android.internal.graphics.ColorUtils;
+
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
@@ -60,6 +62,8 @@
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
+import android.os.PowerManager;
+import android.os.Process;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.os.UserHandle;
@@ -186,6 +190,10 @@
static final String GLOBAL_ACTION_KEY_EMERGENCY = "emergency";
static final String GLOBAL_ACTION_KEY_SCREENSHOT = "screenshot";
+ private static final int RESTART_RECOVERY_BUTTON = 1;
+ private static final int RESTART_BOOTLOADER_BUTTON = 2;
+ private static final int RESTART_UI_BUTTON = 3;
+
public static final String PREFS_CONTROLS_SEEDING_COMPLETED = "SeedingCompleted";
public static final String PREFS_CONTROLS_FILE = "controls_prefs";
private static final int SEEDING_MAX = 2;
@@ -575,7 +583,7 @@
@VisibleForTesting
protected String[] getDefaultActions() {
- return mResources.getStringArray(R.array.config_globalActionsList);
+ return mResources.getStringArray(R.array.custom_config_globalActionsList);
}
private void addIfShouldShowAction(List<Action> actions, Action action) {
@@ -602,6 +610,51 @@
ShutDownAction shutdownAction = new ShutDownAction();
RestartAction restartAction = new RestartAction();
+ AdvancedAction restartRecoveryAction = new AdvancedAction(
+ RESTART_RECOVERY_BUTTON,
+ com.android.systemui.R.drawable.ic_restart_recovery,
+ com.android.systemui.R.string.global_action_restart_recovery,
+ mWindowManagerFuncs, mHandler, mKeyguardStateController, mActivityStarter) {
+
+ public boolean showDuringKeyguard() {
+ return true;
+ }
+
+ public boolean showBeforeProvisioning() {
+ return true;
+ }
+ };
+
+ AdvancedAction restartBootloaderAction = new AdvancedAction(
+ RESTART_BOOTLOADER_BUTTON,
+ com.android.systemui.R.drawable.ic_restart_bootloader,
+ com.android.systemui.R.string.global_action_restart_bootloader,
+ mWindowManagerFuncs, mHandler, mKeyguardStateController, mActivityStarter) {
+
+ public boolean showDuringKeyguard() {
+ return true;
+ }
+
+ public boolean showBeforeProvisioning() {
+ return true;
+ }
+ };
+
+ AdvancedAction restartSystemUiAction = new AdvancedAction(
+ RESTART_UI_BUTTON,
+ com.android.systemui.R.drawable.ic_restart_ui,
+ com.android.systemui.R.string.global_action_restart_ui,
+ mWindowManagerFuncs, mHandler, mKeyguardStateController, mActivityStarter) {
+
+ public boolean showDuringKeyguard() {
+ return true;
+ }
+
+ public boolean showBeforeProvisioning() {
+ return true;
+ }
+ };
+
ArraySet<String> addedKeys = new ArraySet<String>();
List<Action> tempActions = new ArrayList<>();
CurrentUserProvider currentUser = new CurrentUserProvider();
@@ -646,6 +699,10 @@
addIfShouldShowAction(tempActions, getAssistAction());
} else if (GLOBAL_ACTION_KEY_RESTART.equals(actionKey)) {
addIfShouldShowAction(tempActions, restartAction);
+ // if Restart action is available, add advanced restart actions too
+ addIfShouldShowAction(tempActions, restartBootloaderAction);
+ addIfShouldShowAction(tempActions, restartRecoveryAction);
+ addIfShouldShowAction(tempActions, restartSystemUiAction);
} else if (GLOBAL_ACTION_KEY_SCREENSHOT.equals(actionKey)) {
addIfShouldShowAction(tempActions, new ScreenshotAction());
} else if (GLOBAL_ACTION_KEY_LOGOUT.equals(actionKey)) {
@@ -663,20 +720,33 @@
addedKeys.add(actionKey);
}
- // replace power and restart with a single power options action, if needed
- if (tempActions.contains(shutdownAction) && tempActions.contains(restartAction)
- && tempActions.size() > getMaxShownPowerItems()) {
- // transfer shutdown and restart to their own list of power actions
- int powerOptionsIndex = Math.min(tempActions.indexOf(restartAction),
- tempActions.indexOf(shutdownAction));
- tempActions.remove(shutdownAction);
+ if (tempActions.contains(restartAction)) {
+ // transfer restart and advanced restart to their own list of power actions
+ // and position it where Reset button was supposed to be
+ int powerOptionsIndex = tempActions.indexOf(restartAction);
tempActions.remove(restartAction);
- mPowerItems.add(shutdownAction);
+ tempActions.remove(restartBootloaderAction);
+ tempActions.remove(restartRecoveryAction);
+ tempActions.remove(restartSystemUiAction);
+ if (tempActions.contains(shutdownAction)) {
+ mPowerItems.add(shutdownAction); // will be removed later if needed
+ }
mPowerItems.add(restartAction);
+ mPowerItems.add(restartBootloaderAction);
+ mPowerItems.add(restartRecoveryAction);
+ mPowerItems.add(restartSystemUiAction);
- // add the PowerOptionsAction after Emergency, if present
+ // add the PowerOptionsAction after Emergency and Shutdown action, if present
tempActions.add(powerOptionsIndex, new PowerOptionsAction());
}
+ // Add also Power to power actions list, if needed
+ if (tempActions.contains(shutdownAction) && mPowerItems.size() > 1
+ /*tempActions.size gets in count already PowerOptionsAction if added*/
+ && tempActions.size() > getMaxShownPowerItems()) {
+ tempActions.remove(shutdownAction);
+ } else {
+ mPowerItems.remove(shutdownAction);
+ }
for (Action action : tempActions) {
addActionItem(action);
}
@@ -772,6 +842,18 @@
return mWalletPlugin.onPanelShown(this, !mKeyguardStateController.isUnlocked());
}
+ private boolean rebootAction(boolean safeMode) {
+ if (mKeyguardStateController.isMethodSecure() && mKeyguardStateController.isShowing()) {
+ mActivityStarter.postQSRunnableDismissingKeyguard(() -> {
+ mWindowManagerFuncs.reboot(safeMode);
+ });
+ return true;
+ } else {
+ mWindowManagerFuncs.reboot(safeMode);
+ return true;
+ }
+ }
+
/**
* Implements {@link GlobalActionsPanelPlugin.Callbacks#dismissGlobalActionsMenu()}, which is
* called when the quick access wallet requests dismissal.
@@ -794,8 +876,8 @@
@VisibleForTesting
protected final class PowerOptionsAction extends SinglePressAction {
private PowerOptionsAction() {
- super(com.android.systemui.R.drawable.ic_settings_power,
- R.string.global_action_power_options);
+ super(com.android.systemui.R.drawable.ic_restart_advanced,
+ com.android.systemui.R.string.global_action_restart_advanced);
}
@Override
@@ -826,7 +908,7 @@
@Override
public boolean onLongPress() {
if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_SAFE_BOOT)) {
- mWindowManagerFuncs.reboot(true);
+ rebootAction(true);
return true;
}
return false;
@@ -845,7 +927,13 @@
@Override
public void onPress() {
// shutdown by making sure radio and power are handled accordingly.
- mWindowManagerFuncs.shutdown();
+ if (mKeyguardStateController.isMethodSecure() && mKeyguardStateController.isShowing()) {
+ mActivityStarter.postQSRunnableDismissingKeyguard(() -> {
+ mWindowManagerFuncs.shutdown();
+ });
+ } else {
+ mWindowManagerFuncs.shutdown();
+ }
}
}
@@ -865,8 +953,8 @@
Context context, View convertView, ViewGroup parent, LayoutInflater inflater) {
View v = super.create(context, convertView, parent, inflater);
int textColor;
- v.setBackgroundTintList(ColorStateList.valueOf(v.getResources().getColor(
- com.android.systemui.R.color.global_actions_emergency_background)));
+ v.setBackgroundTintList(ColorStateList.valueOf(ColorUtils.setAlphaComponent(v.getResources().getColor(
+ com.android.systemui.R.color.global_actions_emergency_background), 60)));
textColor = v.getResources().getColor(
com.android.systemui.R.color.global_actions_emergency_text);
TextView messageView = v.findViewById(R.id.message);
@@ -938,7 +1026,7 @@
@Override
public boolean onLongPress() {
if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_SAFE_BOOT)) {
- mWindowManagerFuncs.reboot(true);
+ rebootAction(true);
return true;
}
return false;
@@ -956,7 +1044,7 @@
@Override
public void onPress() {
- mWindowManagerFuncs.reboot(false);
+ rebootAction(false);
}
}
@@ -1870,6 +1958,122 @@
}
}
+ /**
+ * A toggle action knows whether it is on or off, and displays an icon
+ * and status message accordingly.
+ */
+ private static abstract class AdvancedAction implements Action, LongPressAction {
+
+ protected int mActionType;
+ protected int mIconResid;
+ protected int mMessageResId;
+ protected Handler mRefresh;
+ protected GlobalActionsManager mWmFuncs;
+ private Context mContext;
+ private KeyguardStateController mKeyguardStateController;
+ private ActivityStarter mActivityStarter;
+
+ public AdvancedAction(
+ int actionType,
+ int iconResid,
+ int messageResid,
+ GlobalActionsManager funcs,
+ Handler handler,
+ KeyguardStateController ksc,
+ ActivityStarter as) {
+ mActionType = actionType;
+ mIconResid = iconResid;
+ mMessageResId = messageResid;
+ mRefresh = handler;
+ mWmFuncs = funcs;
+ mKeyguardStateController = ksc;
+ mActivityStarter = as;
+ }
+
+ @Override
+ public View create(
+ Context context, View convertView, ViewGroup parent, LayoutInflater inflater) {
+ mContext = context;
+ View v = inflater.inflate(com.android.systemui.R.layout.global_actions_item, parent,
+ false);
+
+ TextView messageView = (TextView) v.findViewById(R.id.message);
+ if (messageView != null) {
+ messageView.setText(mMessageResId);
+ }
+ ImageView icon = (ImageView) v.findViewById(R.id.icon);
+ if (icon != null) {
+ icon.setImageDrawable(mContext.getDrawable((mIconResid)));
+ }
+
+ return v;
+ }
+
+ @Override
+ public final void onPress() {
+ if (mKeyguardStateController.isMethodSecure() && mKeyguardStateController.isShowing()) {
+ mActivityStarter.postQSRunnableDismissingKeyguard(() -> {
+ triggerAction(mActionType, mRefresh, mWmFuncs, mContext);
+ });
+ } else {
+ triggerAction(mActionType, mRefresh, mWmFuncs, mContext);
+ }
+ }
+
+ @Override
+ public boolean onLongPress() {
+ return true;
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return true;
+ }
+
+ @Override
+ public CharSequence getLabelForAccessibility(Context context) {
+ return context.getString(mMessageResId);
+ }
+
+ @Override
+ public int getMessageResId() {
+ return mMessageResId;
+ }
+
+ @Override
+ public CharSequence getMessage() {
+ return null;
+ }
+
+ @Override
+ public Drawable getIcon(Context context) {
+ return context.getDrawable(mIconResid);
+ }
+ }
+
+ private static void triggerAction(int type, Handler h, GlobalActionsManager funcs, Context ctx) {
+ switch (type) {
+ case RESTART_RECOVERY_BUTTON:
+ h.sendEmptyMessage(MESSAGE_DISMISS);
+ funcs.advancedReboot(PowerManager.REBOOT_RECOVERY);
+ break;
+ case RESTART_BOOTLOADER_BUTTON:
+ h.sendEmptyMessage(MESSAGE_DISMISS);
+ funcs.advancedReboot(PowerManager.REBOOT_BOOTLOADER);
+ break;
+ case RESTART_UI_BUTTON:
+ /* no time and need to dismiss the dialog here, just kill systemui straight after telling to
+ policy/GlobalActions that we hid the dialog within the kill action itself so its onStatusBarConnectedChanged
+ won't show the LegacyGlobalActions after systemui restart
+ */
+ funcs.onGlobalActionsHidden();
+ restartSystemUI(ctx);
+ break;
+ default:
+ break;
+ }
+ }
+
private class AirplaneModeAction extends ToggleAction {
AirplaneModeAction() {
super(
@@ -2364,7 +2568,7 @@
initializeWalletView();
if (mBackgroundDrawable == null) {
mBackgroundDrawable = new ScrimDrawable();
- mScrimAlpha = 1.0f;
+ mScrimAlpha = 0.80f;
}
getWindow().setBackgroundDrawable(mBackgroundDrawable);
}
@@ -2401,7 +2605,6 @@
if (!(mBackgroundDrawable instanceof ScrimDrawable)) {
return;
}
- ((ScrimDrawable) mBackgroundDrawable).setColor(Color.BLACK, animate);
View decorView = getWindow().getDecorView();
if (colors.supportsDarkText()) {
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR |
@@ -2687,4 +2890,8 @@
mShowLockScreenCardsAndControls = Settings.Secure.getInt(mContentResolver,
Settings.Secure.POWER_MENU_LOCKED_SHOW_CONTENT, 0) != 0;
}
+
+ public static void restartSystemUI(Context ctx) {
+ Process.killProcess(Process.myPid());
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
index b55b29a8..41f79fb 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
@@ -167,9 +167,11 @@
if (reason != null && reason.startsWith(PowerManager.REBOOT_RECOVERY_UPDATE)) {
return R.string.reboot_to_update_reboot;
} else if (reason != null && reason.equals(PowerManager.REBOOT_RECOVERY)) {
- return R.string.reboot_to_reset_message;
+ return R.string.reboot_to_recovery_message;
+ } else if (reason != null && reason.equals(PowerManager.REBOOT_BOOTLOADER)) {
+ return R.string.reboot_to_bootloader_message;
} else if (isReboot) {
- return R.string.reboot_to_reset_message;
+ return R.string.reboot_message;
} else {
return R.string.shutdown_progress;
}
@@ -179,8 +181,6 @@
private String getReasonMessage(@Nullable String reason) {
if (reason != null && reason.startsWith(PowerManager.REBOOT_RECOVERY_UPDATE)) {
return mContext.getString(R.string.reboot_to_update_title);
- } else if (reason != null && reason.equals(PowerManager.REBOOT_RECOVERY)) {
- return mContext.getString(R.string.reboot_to_reset_title);
} else {
return null;
}
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPowerDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPowerDialog.java
index caa88a3..8db7360 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPowerDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsPowerDialog.java
@@ -53,7 +53,7 @@
window.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
window.setTitle(""); // prevent Talkback from speaking first item name twice
window.setBackgroundDrawable(res.getDrawable(
- com.android.systemui.R.drawable.control_background, context.getTheme()));
+ com.android.systemui.R.drawable.control_background_dialog, context.getTheme()));
window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
return dialog;
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
index 3a37c0f..ec86be3 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
@@ -34,6 +34,7 @@
import android.net.Uri;
import android.os.Handler;
import android.os.Trace;
+import android.os.UserHandle;
import android.provider.Settings;
import android.service.notification.ZenModeConfig;
import android.text.TextUtils;
@@ -140,6 +141,8 @@
protected boolean mDozing;
private int mStatusBarState;
private boolean mMediaIsVisible;
+ private boolean mPulseOnNewTracks;
+ private static final String PULSE_ACTION = "com.android.systemui.doze.pulse";
private SystemUIAppComponentFactory.ContextAvailableCallback mContextAvailableCallback;
/**
@@ -216,7 +219,7 @@
return slice;
}
- protected boolean needsMediaLocked() {
+ public boolean needsMediaLocked() {
boolean keepWhenAwake = mKeyguardBypassController != null
&& mKeyguardBypassController.getBypassEnabled() && mDozeParameters.getAlwaysOn();
// Show header if music is playing and the status bar is in the shade state. This way, an
@@ -454,7 +457,7 @@
public void onPrimaryMetadataOrStateChanged(MediaMetadata metadata,
@PlaybackState.State int state) {
synchronized (this) {
- boolean nextVisible = NotificationMediaManager.isPlayingState(state);
+ boolean nextVisible = NotificationMediaManager.isPlayingState(state) || mMediaManager.getNowPlayingTrack() != null;
mMediaHandler.removeCallbacksAndMessages(null);
if (mMediaIsVisible && !nextVisible && mStatusBarState != StatusBarState.SHADE) {
// We need to delay this event for a few millis when stopping to avoid jank in the
@@ -476,6 +479,11 @@
private void updateMediaStateLocked(MediaMetadata metadata, @PlaybackState.State int state) {
boolean nextVisible = NotificationMediaManager.isPlayingState(state);
+ // Get track info from Now Playing notification, if available, and only if there's no playing media notification
+ CharSequence npTitle = mMediaManager.getNowPlayingTrack();
+ boolean nowPlayingAvailable = !nextVisible && npTitle != null;
+
+ // Get track info from player media notification, if available
CharSequence title = null;
if (metadata != null) {
title = metadata.getText(MediaMetadata.METADATA_KEY_TITLE);
@@ -486,14 +494,33 @@
CharSequence artist = metadata == null ? null : metadata.getText(
MediaMetadata.METADATA_KEY_ARTIST);
+ // If Now playing is available, and there's no playing media notification, get Now Playing title
+ title = nowPlayingAvailable ? npTitle : title;
+
if (nextVisible == mMediaIsVisible && TextUtils.equals(title, mMediaTitle)
&& TextUtils.equals(artist, mMediaArtist)) {
return;
}
+ if (nowPlayingAvailable == mMediaIsVisible && TextUtils.equals(title, mMediaTitle)) {
+ return;
+ }
+
+ // Set new track info from playing media notification
mMediaTitle = title;
- mMediaArtist = artist;
- mMediaIsVisible = nextVisible;
+ mMediaArtist = nowPlayingAvailable ? null : artist;
+ mMediaIsVisible = nextVisible || nowPlayingAvailable;
+
notifyChange();
+ // if AoD is disabled, the device is not already dozing and we get a new track, trigger an ambient pulse event
+ if (mPulseOnNewTracks && mMediaIsVisible
+ && !mDozeParameters.getAlwaysOn() && mDozing) {
+ getContext().sendBroadcastAsUser(new Intent(PULSE_ACTION),
+ new UserHandle(UserHandle.USER_CURRENT));
+ }
+ }
+
+ public void setPulseOnNewTracks(boolean enabled) {
+ mPulseOnNewTracks = enabled;
}
protected void notifyChange() {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 75f4809..b0a6a64 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -380,6 +380,8 @@
private IKeyguardDrawnCallback mDrawnCallback;
private CharSequence mCustomMessage;
+ private boolean mHasFod;
+
private final DeviceConfig.OnPropertiesChangedListener mOnPropertiesChangedListener =
new DeviceConfig.OnPropertiesChangedListener() {
@Override
@@ -748,6 +750,8 @@
QuickStepContract.isGesturalMode(navigationModeController.addListener(mode -> {
mInGestureNavigationMode = QuickStepContract.isGesturalMode(mode);
}));
+ mHasFod = context.getResources().getBoolean(
+ com.android.internal.R.bool.config_needCustomFODView);
}
public void userActivity() {
@@ -878,7 +882,9 @@
// explicitly DO NOT want to call
// mKeyguardViewControllerLazy.get().setKeyguardGoingAwayState(false)
// here, since that will mess with the device lock state.
- mUpdateMonitor.dispatchKeyguardGoingAway(false);
+ if (!mHasFod) {
+ mUpdateMonitor.dispatchKeyguardGoingAway(false);
+ }
// Lock immediately based on setting if secure (user has a pin/pattern/password).
// This also "locks" the device when not secure to provide easy access to the
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogReceiver.kt b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogReceiver.kt
index 0ce0c02..e6b245f 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogReceiver.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogReceiver.kt
@@ -32,7 +32,10 @@
override fun onReceive(context: Context, intent: Intent) {
if (TextUtils.equals(MediaOutputSliceConstants.ACTION_LAUNCH_MEDIA_OUTPUT_DIALOG,
intent.action)) {
- mediaOutputDialogFactory.create(
+ var intentExtra = intent.getStringExtra(MediaOutputSliceConstants.EXTRA_PACKAGE_NAME)
+ if (intentExtra == null)
+ mediaOutputDialogFactory.create(MediaOutputSliceConstants.SYSTEMUI_PACKAGE_NAME, false)
+ else mediaOutputDialogFactory.create(
intent.getStringExtra(MediaOutputSliceConstants.EXTRA_PACKAGE_NAME), false)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/DoubleLineTileLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/DoubleLineTileLayout.kt
index dc157a8..a6796c1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/DoubleLineTileLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/DoubleLineTileLayout.kt
@@ -41,6 +41,7 @@
private var cellMarginHorizontal = 0
private var cellMarginVertical = 0
private var tilesToShow = 0
+ private var actualColumns = 6
init {
isFocusableInTouchMode = true
@@ -101,6 +102,12 @@
override fun getNumVisibleTiles() = tilesToShow
+ override fun getNumColumns() = actualColumns
+
+ override fun isShowTitles(): Boolean {
+ return false
+ }
+
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
updateResources()
@@ -111,6 +118,8 @@
updateResources()
}
+ override fun updateSettings() { }
+
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
mRecords.forEach {
@@ -132,7 +141,7 @@
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
val availableWidth = r - l - paddingLeft - paddingRight
val maxColumns = calculateMaxColumns(availableWidth)
- val actualColumns = Math.min(maxColumns, mRecords.size / NUM_LINES)
+ actualColumns = Math.min(maxColumns, mRecords.size / NUM_LINES)
if (actualColumns == 0) {
// No tileSize or horizontal margin
return
@@ -162,4 +171,4 @@
}
private fun getTopBottomRow() = smallTileSize + cellMarginVertical
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index 44803ae..5c2562e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -70,6 +70,7 @@
private int mLastExcessHeight;
private int mMinRows = 1;
private int mMaxColumns = TileLayout.NO_MAX_COLUMNS;
+ private int mNumColumns;
public PagedTileLayout(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -435,6 +436,16 @@
return mPages.get(0).mColumns;
}
+ @Override
+ public int getNumColumns() {
+ return getColumnCount();
+ }
+
+ @Override
+ public boolean isShowTitles() {
+ return mPages.get(0).isShowTitles();
+ }
+
/**
* Gets the number of pages in this paged tile layout
*/
@@ -591,4 +602,12 @@
public interface PageListener {
void onPageChanged(boolean isFirst);
}
+
+ @Override
+ public void updateSettings() {
+ for (int i = 0; i < mPages.size(); i++) {
+ mPages.get(i).updateSettings();
+ }
+ distributeTiles();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
index 9dcc924..15056a0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
@@ -94,6 +94,7 @@
Log.w(TAG, "QS Not using page layout");
}
panel.setPageListener(this);
+ updateSettings();
}
public void onRtlChanged() {
@@ -143,7 +144,7 @@
@Override
public void onViewAttachedToWindow(View v) {
Dependency.get(TunerService.class).addTunable(this, ALLOW_FANCY_ANIMATION,
- MOVE_FULL_ROWS, QuickQSPanel.NUM_QUICK_TILES);
+ MOVE_FULL_ROWS);
}
@Override
@@ -163,9 +164,6 @@
}
} else if (MOVE_FULL_ROWS.equals(key)) {
mFullRows = TunerService.parseIntegerSwitch(newValue, true);
- } else if (QuickQSPanel.NUM_QUICK_TILES.equals(key)) {
- mNumQuickTiles = QuickQSPanel.parseNumTiles(newValue);
- clearAnimationState();
}
updateAnimators();
}
@@ -473,4 +471,9 @@
setCurrentPosition();
}
};
+
+ public void updateSettings() {
+ mNumQuickTiles = mQuickQsPanel.getNumQuickTiles();
+ clearAnimationState();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
index eba4465..993d333 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
@@ -61,12 +61,9 @@
private QuickStatusBarHeader mHeader;
private float mQsExpansion;
private QSCustomizer mQSCustomizer;
- private View mDragHandle;
private View mQSPanelContainer;
private View mBackground;
- private View mBackgroundGradient;
- private View mStatusBarBackground;
private int mSideMargins;
private boolean mQsDisabled;
@@ -86,10 +83,7 @@
mQSDetail = findViewById(R.id.qs_detail);
mHeader = findViewById(R.id.header);
mQSCustomizer = findViewById(R.id.qs_customize);
- mDragHandle = findViewById(R.id.qs_drag_handle_view);
mBackground = findViewById(R.id.quick_settings_background);
- mStatusBarBackground = findViewById(R.id.quick_settings_status_bar_background);
- mBackgroundGradient = findViewById(R.id.quick_settings_gradient_view);
updateResources();
mHeader.getHeaderQsPanel().setMediaVisibilityChangedListener((visible) -> {
if (mHeader.getHeaderQsPanel().isShown()) {
@@ -123,7 +117,6 @@
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
- setBackgroundGradientVisibility(newConfig);
updateResources();
mSizePoint.set(0, 0); // Will be retrieved on next measure pass.
}
@@ -193,7 +186,6 @@
final boolean disabled = (state2 & DISABLE2_QUICK_SETTINGS) != 0;
if (disabled == mQsDisabled) return;
mQsDisabled = disabled;
- setBackgroundGradientVisibility(getResources().getConfiguration());
mBackground.setVisibility(mQsDisabled ? View.GONE : View.VISIBLE);
}
@@ -234,8 +226,6 @@
int height = calculateContainerHeight();
setBottom(getTop() + height);
mQSDetail.setBottom(getTop() + height);
- // Pin the drag handle to the bottom of the panel.
- mDragHandle.setTranslationY(height - mDragHandle.getHeight());
mBackground.setTop(mQSPanelContainer.getTop());
updateBackgroundBottom(height, animate);
}
@@ -261,27 +251,15 @@
+ mHeader.getHeight();
}
- private void setBackgroundGradientVisibility(Configuration newConfig) {
- if (newConfig.orientation == ORIENTATION_LANDSCAPE) {
- mBackgroundGradient.setVisibility(View.INVISIBLE);
- mStatusBarBackground.setVisibility(View.INVISIBLE);
- } else {
- mBackgroundGradient.setVisibility(mQsDisabled ? View.INVISIBLE : View.VISIBLE);
- mStatusBarBackground.setVisibility(View.VISIBLE);
- }
- }
-
public void setExpansion(float expansion) {
mQsExpansion = expansion;
- mDragHandle.setAlpha(1.0f - expansion);
updateExpansion();
}
private void updatePaddingsAndMargins() {
for (int i = 0; i < getChildCount(); i++) {
View view = getChildAt(i);
- if (view == mStatusBarBackground || view == mBackgroundGradient
- || view == mQSCustomizer) {
+ if (view == mQSCustomizer) {
// Some views are always full width
continue;
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
index 0a2533a..26d3e4b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
@@ -26,7 +26,7 @@
/**
* Sets the given {@link QSPanel} to be the one that will display the quick settings.
*/
- void setQSPanel(@Nullable QSPanel panel);
+ void setQSPanel(@Nullable QSPanel panel, @Nullable QuickQSPanel quickQSPanel);
/**
* Sets the given {@link QuickQSPanel} to be the one associated with quick settings.
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java
index 6e4ab9a..0014149 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java
@@ -37,6 +37,7 @@
import android.util.AttributeSet;
import android.view.View;
import android.view.View.OnClickListener;
+import android.view.View.OnLongClickListener;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
import android.widget.ImageView;
@@ -68,7 +69,7 @@
import javax.inject.Named;
public class QSFooterImpl extends FrameLayout implements QSFooter,
- OnClickListener, OnUserInfoChangedListener {
+ OnClickListener, OnLongClickListener, OnUserInfoChangedListener {
private static final String TAG = "QSFooterImpl";
@@ -80,6 +81,7 @@
private PageIndicator mPageIndicator;
private TextView mBuildText;
private boolean mShouldShowBuildText;
+ private View mRunningServicesButton;
private boolean mQsDisabled;
private QSPanel mQsPanel;
@@ -103,14 +105,14 @@
private OnClickListener mExpandClickListener;
- private final ContentObserver mDeveloperSettingsObserver = new ContentObserver(
+ /*private final ContentObserver mDeveloperSettingsObserver = new ContentObserver(
new Handler(mContext.getMainLooper())) {
@Override
public void onChange(boolean selfChange, Uri uri) {
super.onChange(selfChange, uri);
setBuildText();
}
- };
+ };*/
@Inject
public QSFooterImpl(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs,
@@ -143,6 +145,10 @@
mSettingsButton = findViewById(R.id.settings_button);
mSettingsContainer = findViewById(R.id.settings_button_container);
mSettingsButton.setOnClickListener(this);
+ mSettingsButton.setOnLongClickListener(this);
+
+ mRunningServicesButton = findViewById(R.id.running_services_button);
+ mRunningServicesButton.setOnClickListener(this);
mMultiUserSwitch = findViewById(R.id.multi_user_switch);
mMultiUserAvatar = mMultiUserSwitch.findViewById(R.id.multi_user_avatar);
@@ -154,6 +160,7 @@
// RenderThread is doing more harm than good when touching the header (to expand quick
// settings), so disable it for this view
((RippleDrawable) mSettingsButton.getBackground()).setForceSoftware(true);
+ ((RippleDrawable) mRunningServicesButton.getBackground()).setForceSoftware(true);
updateResources();
@@ -161,11 +168,11 @@
oldBottom) -> updateAnimator(right - left));
setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
updateEverything();
- setBuildText();
+ //setBuildText();
}
private void setBuildText() {
- if (mBuildText == null) return;
+ /* if (mBuildText == null) return;
if (DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)) {
mBuildText.setText(mContext.getString(
com.android.internal.R.string.bugreport_status,
@@ -178,7 +185,7 @@
} else {
mShouldShowBuildText = false;
mBuildText.setSelected(false);
- }
+ }*/
}
private void updateAnimator(int width) {
@@ -221,7 +228,7 @@
@Nullable
private TouchAnimator createFooterAnimator() {
return new TouchAnimator.Builder()
- .addFloat(mActionsContainer, "alpha", 0, 1)
+ .addFloat(mActionsContainer, "alpha", 0, 1) // contains mRunningServicesButton
.addFloat(mEditContainer, "alpha", 0, 1)
.addFloat(mPageIndicator, "alpha", 0, 1)
.setStartDelay(0.9f)
@@ -258,16 +265,16 @@
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
- mContext.getContentResolver().registerContentObserver(
+ /*mContext.getContentResolver().registerContentObserver(
Settings.Global.getUriFor(Settings.Global.DEVELOPMENT_SETTINGS_ENABLED), false,
- mDeveloperSettingsObserver, UserHandle.USER_ALL);
+ mDeveloperSettingsObserver, UserHandle.USER_ALL);*/
}
@Override
@VisibleForTesting
public void onDetachedFromWindow() {
setListening(false);
- mContext.getContentResolver().unregisterContentObserver(mDeveloperSettingsObserver);
+ //mContext.getContentResolver().unregisterContentObserver(mDeveloperSettingsObserver);
super.onDetachedFromWindow();
}
@@ -321,14 +328,15 @@
private void updateVisibilities() {
mSettingsContainer.setVisibility(mQsDisabled ? View.GONE : View.VISIBLE);
- mSettingsContainer.findViewById(R.id.tuner_icon).setVisibility(
- TunerService.isTunerEnabled(mContext) ? View.VISIBLE : View.INVISIBLE);
final boolean isDemo = UserManager.isDeviceInDemoMode(mContext);
mMultiUserSwitch.setVisibility(showUserSwitcher() ? View.VISIBLE : View.INVISIBLE);
mEditContainer.setVisibility(isDemo || !mExpanded ? View.INVISIBLE : View.VISIBLE);
+ mEdit.setVisibility(isEditEnabled() ? View.VISIBLE : View.GONE);
mSettingsButton.setVisibility(isDemo || !mExpanded ? View.INVISIBLE : View.VISIBLE);
mBuildText.setVisibility(mExpanded && mShouldShowBuildText ? View.VISIBLE : View.GONE);
+ mRunningServicesButton.setVisibility(!isDemo && mExpanded ? View.VISIBLE : View.INVISIBLE);
+ mRunningServicesButton.setVisibility(isRunningServicesEnabled() ? !isDemo && mExpanded ? View.VISIBLE : View.INVISIBLE : View.GONE);
}
private boolean showUserSwitcher() {
@@ -344,14 +352,25 @@
}
@Override
- public void setQSPanel(final QSPanel qsPanel) {
+ public void setQSPanel(final QSPanel qsPanel, final QuickQSPanel quickQSPanel) {
mQsPanel = qsPanel;
+ mQuickQsPanel = quickQSPanel;
if (mQsPanel != null) {
mMultiUserSwitch.setQsPanel(qsPanel);
mQsPanel.setFooterPageIndicator(mPageIndicator);
}
}
+ public boolean isRunningServicesEnabled() {
+ return Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.QS_RUNNING_SERVICES_TOGGLE, 0) == 1;
+ }
+
+ public boolean isEditEnabled() {
+ return Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.QS_EDIT_TOGGLE, 1) == 1;
+ }
+
@Override
public void setQQSPanel(@Nullable QuickQSPanel panel) {
mQuickQsPanel = panel;
@@ -374,27 +393,37 @@
MetricsLogger.action(mContext,
mExpanded ? MetricsProto.MetricsEvent.ACTION_QS_EXPANDED_SETTINGS_LAUNCH
: MetricsProto.MetricsEvent.ACTION_QS_COLLAPSED_SETTINGS_LAUNCH);
- if (mSettingsButton.isTunerClick()) {
- mActivityStarter.postQSRunnableDismissingKeyguard(() -> {
- if (TunerService.isTunerEnabled(mContext)) {
- TunerService.showResetRequest(mContext, () -> {
- // Relaunch settings so that the tuner disappears.
- startSettingsActivity();
- });
- } else {
- Toast.makeText(getContext(), R.string.tuner_toast,
- Toast.LENGTH_LONG).show();
- TunerService.setTunerEnabled(mContext, true);
- }
- startSettingsActivity();
-
- });
- } else {
- startSettingsActivity();
- }
+ startSettingsActivity();
+ } else if (v == mRunningServicesButton) {
+ MetricsLogger.action(mContext,
+ mExpanded ? MetricsProto.MetricsEvent.ACTION_QS_EXPANDED_SETTINGS_LAUNCH
+ : MetricsProto.MetricsEvent.ACTION_QS_COLLAPSED_SETTINGS_LAUNCH);
+ startRunningServicesActivity();
}
}
+ @Override
+ public boolean onLongClick(View v) {
+ if (v == mSettingsButton) {
+ startBlissifyActivity();
+ }
+ return false;
+ }
+
+ private void startRunningServicesActivity() {
+ Intent intent = new Intent();
+ intent.setClassName("com.android.settings",
+ "com.android.settings.Settings$DevRunningServicesActivity");
+ mActivityStarter.startActivity(intent, true /* dismissShade */);
+ }
+
+ private void startBlissifyActivity() {
+ Intent nIntent = new Intent(Intent.ACTION_MAIN);
+ nIntent.setClassName("com.android.settings",
+ "com.android.settings.Settings$BlissifySettingsActivity");
+ mActivityStarter.startActivity(nIntent, true /* dismissShade */);
+ }
+
private void startSettingsActivity() {
mActivityStarter.startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS),
true /* dismissShade */);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index f1bb899..0139fe2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -72,6 +72,7 @@
private QSCustomizer mQSCustomizer;
protected QSPanel mQSPanel;
protected NonInterceptingScrollView mQSPanelScrollView;
+ protected QuickQSPanel mQuickQSPanel;
private QSDetail mQSDetail;
private boolean mListening;
private QSContainerImpl mContainer;
@@ -136,6 +137,7 @@
mQSDetail = view.findViewById(R.id.qs_detail);
mHeader = view.findViewById(R.id.header);
mQSPanel.setHeaderContainer(view.findViewById(R.id.header_text_container));
+ mQuickQSPanel = mHeader.findViewById(R.id.quick_qs_panel);
mFooter = view.findViewById(R.id.qs_footer);
mContainer = view.findViewById(id.quick_settings_container);
@@ -145,7 +147,7 @@
mQSDetail.setQsPanel(mQSPanel, mHeader, (View) mFooter);
- mQSAnimator = new QSAnimator(this, mHeader.findViewById(R.id.quick_qs_panel), mQSPanel);
+ mQSAnimator = new QSAnimator(this, mQuickQSPanel, mQSPanel);
mQSCustomizer = view.findViewById(R.id.qs_customize);
@@ -226,6 +228,9 @@
mQSAnimator.onRtlChanged();
}
}
+ if (mQSAnimator != null) {
+ mQSAnimator.updateSettings();
+ }
}
private void setEditLocation(View view) {
@@ -251,7 +256,7 @@
public void setHost(QSTileHost qsh) {
mQSPanel.setHost(qsh, mQSCustomizer);
mHeader.setQSPanel(mQSPanel);
- mFooter.setQSPanel(mQSPanel);
+ mFooter.setQSPanel(mQSPanel, mQuickQSPanel);
mQSDetail.setHost(qsh);
if (mQSAnimator != null) {
@@ -551,6 +556,13 @@
// Let the panel know the position changed and it needs to update where notifications
// and whatnot are.
mPanelView.onQsHeightChanged();
+
+ // when we come back from customize update
+ if (!mQSCustomizer.isCustomizing()) {
+ mQSPanel.updateSettings();
+ mQuickQSPanel.updateSettings();
+ mQSAnimator.updateSettings();
+ }
}
/**
@@ -613,6 +625,10 @@
}
};
+ public QuickQSPanel getQuickQsPanel() {
+ return mQuickQSPanel;
+ }
+
@Override
public void onStateChanged(int newState) {
mState = newState;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index ae925d1..5481032 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -20,6 +20,10 @@
import static com.android.systemui.util.Utils.useQsMediaPlayer;
import android.annotation.NonNull;
+import android.animation.Animator;
+import android.animation.Animator.AnimatorListener;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Context;
@@ -30,11 +34,23 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
+import android.os.UserHandle;
+import android.provider.Settings;
import android.util.AttributeSet;
+import android.util.Log;
import android.view.Gravity;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.AccelerateDecelerateInterpolator;
+import android.view.animation.AnticipateInterpolator;
+import android.view.animation.AnticipateOvershootInterpolator;
+import android.view.animation.BounceInterpolator;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.LinearInterpolator;
+import android.view.animation.OvershootInterpolator;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.ImageView;
import android.widget.LinearLayout;
import com.android.internal.logging.MetricsLogger;
@@ -210,6 +226,7 @@
(PagedTileLayout) mRegularTileLayout);
}
mQSLogger.logAllTilesChangeListening(mListening, getDumpableTag(), mCachedSpecs);
+ updateSettings();
updateResources();
}
@@ -229,7 +246,9 @@
R.layout.quick_settings_brightness_dialog, this, false);
addView(mBrightnessView);
mBrightnessController = new BrightnessController(getContext(),
- findViewById(R.id.brightness_slider), mBroadcastDispatcher);
+ findViewById(R.id.brightness_slider),
+ findViewById(R.id.brightness_icon),
+ mBroadcastDispatcher);
}
protected QSTileLayout createRegularTileLayout() {
@@ -240,7 +259,6 @@
return mRegularTileLayout;
}
-
protected QSTileLayout createHorizontalTileLayout() {
return createRegularTileLayout();
}
@@ -883,6 +901,7 @@
if (mTileLayout != null) {
mTileLayout.addTile(r);
+ tileClickListener(r.tile, r.tileView);
}
return r;
@@ -1186,6 +1205,9 @@
int getOffsetTop(TileRecord tile);
boolean updateResources();
+ int getNumColumns();
+ void updateSettings();
+ boolean isShowTitles();
void setListening(boolean listening);
@@ -1213,4 +1235,78 @@
int getNumVisibleTiles();
}
+
+ private void setAnimationTile(QSTileView v) {
+ ObjectAnimator animTile = null;
+ int animStyle = Settings.System.getIntForUser(mContext.getContentResolver(),
+ Settings.System.ANIM_TILE_STYLE, 0, UserHandle.USER_CURRENT);
+ int animDuration = Settings.System.getIntForUser(mContext.getContentResolver(),
+ Settings.System.ANIM_TILE_DURATION, 2000, UserHandle.USER_CURRENT);
+ int interpolatorType = Settings.System.getIntForUser(mContext.getContentResolver(),
+ Settings.System.ANIM_TILE_INTERPOLATOR, 0, UserHandle.USER_CURRENT);
+ if (animStyle == 0) {
+ //No animation
+ }
+ if (animStyle == 1) {
+ animTile = ObjectAnimator.ofFloat(v, "rotationY", 0f, 360f);
+ }
+ if (animStyle == 2) {
+ animTile = ObjectAnimator.ofFloat(v, "rotation", 0f, 360f);
+ }
+ if (animTile != null) {
+ switch (interpolatorType) {
+ case 0:
+ animTile.setInterpolator(new LinearInterpolator());
+ break;
+ case 1:
+ animTile.setInterpolator(new AccelerateInterpolator());
+ break;
+ case 2:
+ animTile.setInterpolator(new DecelerateInterpolator());
+ break;
+ case 3:
+ animTile.setInterpolator(new AccelerateDecelerateInterpolator());
+ break;
+ case 4:
+ animTile.setInterpolator(new BounceInterpolator());
+ break;
+ case 5:
+ animTile.setInterpolator(new OvershootInterpolator());
+ break;
+ case 6:
+ animTile.setInterpolator(new AnticipateInterpolator());
+ break;
+ case 7:
+ animTile.setInterpolator(new AnticipateOvershootInterpolator());
+ break;
+ default:
+ break;
+ }
+ animTile.setDuration(animDuration);
+ animTile.start();
+ }
+ }
+
+ private void tileClickListener(QSTile t, QSTileView v) {
+ if (mTileLayout != null) {
+ v.setHideLabel(!mTileLayout.isShowTitles());
+ v.setOnClickListener(view -> {
+ t.click();
+ setAnimationTile(v);
+ });
+ }
+ }
+
+ public void updateSettings() {
+ if (mTileLayout != null) {
+ mTileLayout.updateSettings();
+ for (TileRecord r : mRecords) {
+ tileClickListener(r.tile, r.tileView);
+ }
+ }
+ }
+
+ public int getNumColumns() {
+ return mTileLayout.getNumColumns();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index affb7b9..bff67e2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -19,15 +19,17 @@
import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;
import android.content.Context;
+import android.content.ContentResolver;
import android.content.res.Configuration;
import android.graphics.Rect;
+import android.os.UserHandle;
+import android.provider.Settings;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.widget.LinearLayout;
import com.android.internal.logging.UiEventLogger;
-import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dump.DumpManager;
@@ -52,10 +54,10 @@
*/
public class QuickQSPanel extends QSPanel {
- public static final String NUM_QUICK_TILES = "sysui_qqs_count";
private static final String TAG = "QuickQSPanel";
// Start it at 6 so a non-zero value can be obtained statically.
private static int sDefaultMaxTiles = 6;
+ public static final int NUM_QUICK_TILES_DEFAULT = 6;
private boolean mDisabledByPolicy;
private int mMaxTiles;
@@ -75,6 +77,7 @@
super(context, attrs, dumpManager, broadcastDispatcher, qsLogger, mediaHost, uiEventLogger);
sDefaultMaxTiles = getResources().getInteger(R.integer.quick_qs_panel_max_columns);
applyBottomMargin((View) mRegularTileLayout);
+ updateSettings();
}
private void applyBottomMargin(View view) {
@@ -96,7 +99,7 @@
@Override
protected TileLayout createRegularTileLayout() {
- return new QuickQSPanel.HeaderTileLayout(mContext, mUiEventLogger);
+ return new QuickQSPanel.HeaderTileLayout(mContext, mUiEventLogger, this);
}
@Override
@@ -130,13 +133,11 @@
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
- Dependency.get(TunerService.class).addTunable(mNumTiles, NUM_QUICK_TILES);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
- Dependency.get(TunerService.class).removeTunable(mNumTiles);
}
@Override
@@ -146,6 +147,7 @@
public void setQSPanelAndHeader(QSPanel fullPanel, View header) {
mFullPanel = fullPanel;
+ updateSettings();
}
@Override
@@ -172,7 +174,7 @@
setTiles(mHost.getTiles());
}
- public void setMaxTiles(int maxTiles) {
+ private void setMaxTiles(int maxTiles) {
mMaxTiles = maxTiles;
if (mHost != null) {
setTiles(mHost.getTiles());
@@ -199,13 +201,6 @@
super.setTiles(quickTiles, true);
}
- private final Tunable mNumTiles = new Tunable() {
- @Override
- public void onTuningChanged(String key, String newValue) {
- setMaxTiles(parseNumTiles(newValue));
- }
- };
-
public int getNumQuickTiles() {
return mMaxTiles;
}
@@ -268,15 +263,41 @@
return QSEvent.QQS_TILE_VISIBLE;
}
+ public int getNumColumns() {
+ if (mFullPanel != null) {
+ return mFullPanel.getNumColumns();
+ }
+ return NUM_QUICK_TILES_DEFAULT;
+ }
+
+ public void updateSettings() {
+ int qsColumns = Settings.System.getIntForUser(
+ mContext.getContentResolver(), Settings.System.QS_QUICKBAR_COLUMNS,
+ NUM_QUICK_TILES_DEFAULT, UserHandle.USER_CURRENT);
+ if (qsColumns == -1) {
+ setMaxTiles(Math.max(NUM_QUICK_TILES_DEFAULT, getNumColumns()));
+ } else {
+ setMaxTiles(Math.max(NUM_QUICK_TILES_DEFAULT, qsColumns));
+ }
+ }
+
+ public void updateResources() {
+ if (mTileLayout != null) {
+ mTileLayout.updateResources();
+ }
+ }
+
private static class HeaderTileLayout extends TileLayout {
private final UiEventLogger mUiEventLogger;
private Rect mClippingBounds = new Rect();
+ private QuickQSPanel mPanel;
- public HeaderTileLayout(Context context, UiEventLogger uiEventLogger) {
+ public HeaderTileLayout(Context context, UiEventLogger uiEventLogger, QuickQSPanel panel) {
super(context);
mUiEventLogger = uiEventLogger;
+ mPanel = panel;
setClipChildren(false);
setClipToPadding(false);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,
@@ -327,6 +348,7 @@
public boolean updateResources() {
mCellWidth = mContext.getResources().getDimensionPixelSize(R.dimen.qs_quick_tile_size);
mCellHeight = mCellWidth;
+ updateSettings();
return false;
}
@@ -401,6 +423,26 @@
return getPaddingStart() + mCellMarginHorizontal;
}
return getPaddingStart() + column * (mCellWidth + mCellMarginHorizontal);
+ }
+
+ @Override
+ public int getNumColumns() {
+ if (mPanel != null) {
+ return mPanel.getNumQuickTiles();
+ }
+ return super.getNumColumns();
+ }
+
+ @Override
+ public void updateSettings() {
+ if (mPanel != null) {
+ mPanel.updateSettings();
+ }
+ }
+
+ @Override
+ public boolean isShowTitles() {
+ return false;
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index 58c723c..638739a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -16,6 +16,7 @@
import static android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
+import static android.provider.Settings.System.QS_SHOW_BATTERY_PERCENT;
import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;
@@ -30,9 +31,12 @@
import android.graphics.Color;
import android.graphics.Rect;
import android.media.AudioManager;
+import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
+import android.os.UserHandle;
import android.provider.AlarmClock;
+import android.provider.CalendarContract;
import android.provider.Settings;
import android.service.notification.ZenModeConfig;
import android.text.format.DateUtils;
@@ -269,16 +273,16 @@
mClockView = findViewById(R.id.clock);
mClockView.setOnClickListener(this);
+ mClockView.setQsHeader();
mDateView = findViewById(R.id.date);
mSpace = findViewById(R.id.space);
+ mDateView.setOnClickListener(this);
// Tint for the battery icons are handled in setupHost()
mBatteryRemainingIcon = findViewById(R.id.batteryRemainingIcon);
- // Don't need to worry about tuner settings for this icon
- mBatteryRemainingIcon.setIgnoreTunerUpdates(true);
- // QS will always show the estimate, and BatteryMeterView handles the case where
- // it's unavailable or charging
- mBatteryRemainingIcon.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE);
+ mBatteryRemainingIcon.setIsQsHeader(true);
+ mBatteryRemainingIcon.setPercentShowMode(getBatteryPercentMode());
+
mRingerModeTextView.setSelected(true);
mNextAlarmTextView.setSelected(true);
@@ -457,12 +461,25 @@
mPrivacyChipAlphaAnimator = new TouchAnimator.Builder()
.addFloat(mPrivacyChip, "alpha", 1, 0, 1)
.build();
+ }
+
+ private int getBatteryPercentMode() {
+ boolean showBatteryPercent = Settings.System
+ .getIntForUser(getContext().getContentResolver(),
+ QS_SHOW_BATTERY_PERCENT, 0, UserHandle.USER_CURRENT) == 1;
+ return showBatteryPercent ?
+ BatteryMeterView.MODE_ON : BatteryMeterView.MODE_ESTIMATE;
+ }
+
+ public void setBatteryPercentMode() {
+ mBatteryRemainingIcon.setPercentShowMode(getBatteryPercentMode());
}
public void setExpanded(boolean expanded) {
if (mExpanded == expanded) return;
mExpanded = expanded;
mHeaderQsPanel.setExpanded(expanded);
+ mDateView.setVisibility(mClockView.isClockDateEnabled() ? View.INVISIBLE : View.VISIBLE);
updateEverything();
}
@@ -639,7 +656,7 @@
@Override
public void onClick(View v) {
- if (v == mClockView) {
+ if (v == mClockView || v == mNextAlarmTextView) {
mActivityStarter.postStartActivityDismissingKeyguard(new Intent(
AlarmClock.ACTION_SHOW_ALARMS), 0);
} else if (v == mNextAlarmContainer && mNextAlarmContainer.isVisibleToUser()) {
@@ -665,6 +682,12 @@
} else if (v == mRingerContainer && mRingerContainer.isVisibleToUser()) {
mActivityStarter.postStartActivityDismissingKeyguard(new Intent(
Settings.ACTION_SOUND_SETTINGS), 0);
+ } else if (v == mDateView) {
+ Uri.Builder builder = CalendarContract.CONTENT_URI.buildUpon();
+ builder.appendPath("time");
+ builder.appendPath(Long.toString(System.currentTimeMillis()));
+ Intent todayIntent = new Intent(Intent.ACTION_VIEW, builder.build());
+ mActivityStarter.postStartActivityDismissingKeyguard(todayIntent, 0);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
index 694492a..1b39f78 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
@@ -3,7 +3,9 @@
import static com.android.systemui.util.Utils.useQsMediaPlayer;
import android.content.Context;
+import android.content.res.Configuration;
import android.content.res.Resources;
+import android.os.UserHandle;
import android.provider.Settings;
import android.util.AttributeSet;
import android.view.View;
@@ -29,6 +31,8 @@
protected int mCellMarginVertical;
protected int mSidePadding;
protected int mRows = 1;
+ protected int mDefaultColumns;
+ protected boolean mShowTitles = true;
protected final ArrayList<TileRecord> mRecords = new ArrayList<>();
private int mCellMarginTop;
@@ -111,23 +115,20 @@
public boolean updateResources() {
final Resources res = mContext.getResources();
- mResourceColumns = Math.max(1, res.getInteger(R.integer.quick_settings_num_columns));
mCellHeight = mContext.getResources().getDimensionPixelSize(R.dimen.qs_tile_height);
mCellMarginHorizontal = res.getDimensionPixelSize(R.dimen.qs_tile_margin_horizontal);
mCellMarginVertical= res.getDimensionPixelSize(R.dimen.qs_tile_margin_vertical);
mCellMarginTop = res.getDimensionPixelSize(R.dimen.qs_tile_margin_top);
mMaxAllowedRows = Math.max(1, getResources().getInteger(R.integer.quick_settings_max_rows));
if (mLessRows) mMaxAllowedRows = Math.max(mMinRows, mMaxAllowedRows - 1);
- if (updateColumns()) {
- requestLayout();
- return true;
- }
+ updateSettings();
return false;
}
private boolean updateColumns() {
+ updateSettings();
int oldColumns = mColumns;
- mColumns = Math.min(mResourceColumns, mMaxColumns);
+ mColumns = Math.min(mColumns, mMaxColumns);
return oldColumns != mColumns;
}
@@ -237,4 +238,39 @@
public int getNumVisibleTiles() {
return mRecords.size();
}
+
+ public int getNumColumns() {
+ return mColumns;
+ }
+
+ public void updateSettings() {
+ final Resources res = mContext.getResources();
+ mDefaultColumns = Math.max(1, res.getInteger(R.integer.quick_settings_num_columns));
+ boolean isPortrait = res.getConfiguration().orientation
+ == Configuration.ORIENTATION_PORTRAIT;
+ int columns = Settings.System.getIntForUser(
+ mContext.getContentResolver(), Settings.System.QS_LAYOUT_COLUMNS, mDefaultColumns,
+ UserHandle.USER_CURRENT);
+ int columnsLandscape = Settings.System.getIntForUser(
+ mContext.getContentResolver(), Settings.System.QS_LAYOUT_COLUMNS_LANDSCAPE, mDefaultColumns,
+ UserHandle.USER_CURRENT);
+ boolean showTitles = Settings.System.getIntForUser(
+ mContext.getContentResolver(), Settings.System.QS_TILE_TITLE_VISIBILITY, 1,
+ UserHandle.USER_CURRENT) == 1;
+ if (showTitles) {
+ mCellHeight = mContext.getResources().getDimensionPixelSize(R.dimen.qs_tile_height);
+ } else {
+ mCellHeight = mContext.getResources().getDimensionPixelSize(R.dimen.qs_tile_height_wo_label);
+ }
+ if (mColumns != (isPortrait ? columns : columnsLandscape) || mShowTitles != showTitles) {
+ mColumns = isPortrait ? columns : columnsLandscape;
+ mShowTitles = showTitles;
+ requestLayout();
+ }
+ }
+
+ @Override
+ public boolean isShowTitles() {
+ return mShowTitles;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
index e5ed88c..d11618b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
@@ -21,11 +21,19 @@
import android.content.Context;
import android.content.res.Configuration;
import android.os.Bundle;
+import android.content.res.Resources;
+import android.content.Intent;
+import android.os.UserHandle;
+import android.provider.Settings;
+import androidx.recyclerview.widget.DefaultItemAnimator;
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.Menu;
+import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.LinearLayout;
@@ -39,6 +47,7 @@
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.UiEventLoggerImpl;
+import com.android.settingslib.Utils;
import com.android.systemui.R;
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.plugins.qs.QS;
@@ -46,6 +55,7 @@
import com.android.systemui.qs.QSDetailClipper;
import com.android.systemui.qs.QSEditEvent;
import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.qs.QuickQSPanel;
import com.android.systemui.statusbar.phone.LightBarController;
import com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer;
import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -64,7 +74,6 @@
*/
public class QSCustomizer extends LinearLayout implements OnMenuItemClickListener {
- private static final int MENU_RESET = Menu.FIRST;
private static final String EXTRA_QS_CUSTOMIZING = "qs_customizing";
private static final String TAG = "QSCustomizer";
@@ -89,6 +98,12 @@
private boolean mIsShowingNavBackdrop;
private UiEventLogger mUiEventLogger = new UiEventLoggerImpl();
+ private GridLayoutManager mLayout;
+ private int mDefaultColumns;
+ private Menu mColumnsSubMenu;
+ private Menu mColumnsLandscapeSubMenu;
+ private Menu mQsColumnsSubMenu;
+
@Inject
public QSCustomizer(Context context, AttributeSet attrs,
LightBarController lightBarController,
@@ -112,25 +127,48 @@
}
});
mToolbar.setOnMenuItemClickListener(this);
- mToolbar.getMenu().add(Menu.NONE, MENU_RESET, 0,
- mContext.getString(com.android.internal.R.string.reset));
+ MenuInflater menuInflater = new MenuInflater(mContext);
+ menuInflater.inflate(R.menu.qs_customize_menu, mToolbar.getMenu());
+ MenuItem menuItem = mToolbar.getMenu().findItem(R.id.menu_item_columns);
+ if (menuItem != null) {
+ mColumnsSubMenu = menuItem.getSubMenu();
+ }
+ MenuItem menuItemLand = mToolbar.getMenu().findItem(R.id.menu_item_columns_landscape);
+ if (menuItemLand != null) {
+ mColumnsLandscapeSubMenu = menuItemLand.getSubMenu();
+ }
+ MenuItem menuItemQs = mToolbar.getMenu().findItem(R.id.menu_item_qs_columns);
+ if (menuItemQs != null) {
+ mQsColumnsSubMenu = menuItemQs.getSubMenu();
+ }
+ int qsTitlesValue = Settings.System.getIntForUser(mContext.getContentResolver(),
+ Settings.System.QS_TILE_TITLE_VISIBILITY, 1,
+ UserHandle.USER_CURRENT);
+ MenuItem qsTitlesMenuItem = mToolbar.getMenu().findItem(R.id.menu_item_titles);
+ qsTitlesMenuItem.setChecked(qsTitlesValue == 1);
+ int accentColor = Utils.getColorAccentDefaultColor(context);
+ mToolbar.setTitleTextColor(accentColor);
+ mToolbar.getNavigationIcon().setTint(accentColor);
+ mToolbar.getOverflowIcon().setTint(accentColor);
mToolbar.setTitle(R.string.qs_edit);
- mRecyclerView = findViewById(android.R.id.list);
+ mDefaultColumns = Math.max(1,
+ mContext.getResources().getInteger(R.integer.quick_settings_num_columns));
+ mRecyclerView = (RecyclerView) findViewById(android.R.id.list);
mTransparentView = findViewById(R.id.customizer_transparent_view);
mTileAdapter = new TileAdapter(getContext(), uiEventLogger);
mTileQueryHelper = tileQueryHelper;
mTileQueryHelper.setListener(mTileAdapter);
mRecyclerView.setAdapter(mTileAdapter);
mTileAdapter.getItemTouchHelper().attachToRecyclerView(mRecyclerView);
- GridLayoutManager layout = new GridLayoutManager(getContext(), 3) {
+ mLayout = new GridLayoutManager(getContext(), mDefaultColumns) {
@Override
public void onInitializeAccessibilityNodeInfoForItem(RecyclerView.Recycler recycler,
RecyclerView.State state, View host, AccessibilityNodeInfoCompat info) {
// Do not read row and column every time it changes.
}
};
- layout.setSpanSizeLookup(mTileAdapter.getSizeLookup());
- mRecyclerView.setLayoutManager(layout);
+ mLayout.setSpanSizeLookup(mTileAdapter.getSizeLookup());
+ mRecyclerView.setLayoutManager(mLayout);
mRecyclerView.addItemDecoration(mTileAdapter.getItemDecoration());
DefaultItemAnimator animator = new DefaultItemAnimator();
animator.setMoveDuration(TileAdapter.MOVE_DURATION);
@@ -139,6 +177,7 @@
mKeyguardStateController = keyguardStateController;
mScreenLifecycle = screenLifecycle;
updateNavBackDrop(getResources().getConfiguration());
+ updateSettings();
}
@Override
@@ -163,6 +202,7 @@
navBackdrop.setVisibility(mIsShowingNavBackdrop ? View.VISIBLE : View.GONE);
}
updateNavColors();
+ updateSettings();
}
private void updateNavColors() {
@@ -230,6 +270,15 @@
if (isShown) {
mUiEventLogger.log(QSEditEvent.QS_EDIT_CLOSED);
isShown = false;
+ if (mColumnsSubMenu != null) {
+ mColumnsSubMenu.close();
+ }
+ if (mColumnsLandscapeSubMenu != null) {
+ mColumnsLandscapeSubMenu.close();
+ }
+ if (mQsColumnsSubMenu != null) {
+ mQsColumnsSubMenu.close();
+ }
mToolbar.dismissPopupMenus();
mClipper.cancelAnimator();
// Make sure we're not opening (because we're closing). Nobody can think we are
@@ -264,17 +313,72 @@
@Override
public boolean onMenuItemClick(MenuItem item) {
- switch (item.getItemId()) {
- case MENU_RESET:
- mUiEventLogger.log(QSEditEvent.QS_EDIT_RESET);
- reset();
- break;
+ int id = item.getItemId();
+ if (id == R.id.menu_item_reset) {
+ mUiEventLogger.log(QSEditEvent.QS_EDIT_RESET);
+ reset();
+ } else if (id == R.id.menu_item_columns_three) {
+ Settings.System.putIntForUser(mContext.getContentResolver(),
+ Settings.System.QS_LAYOUT_COLUMNS, 3, UserHandle.USER_CURRENT);
+ } else if (id == R.id.menu_item_columns_four) {
+ Settings.System.putIntForUser(mContext.getContentResolver(),
+ Settings.System.QS_LAYOUT_COLUMNS, 4, UserHandle.USER_CURRENT);
+ } else if (id == R.id.menu_item_columns_five) {
+ Settings.System.putIntForUser(mContext.getContentResolver(),
+ Settings.System.QS_LAYOUT_COLUMNS, 5, UserHandle.USER_CURRENT);
+ } else if (id == R.id.menu_item_columns_six) {
+ Settings.System.putIntForUser(mContext.getContentResolver(),
+ Settings.System.QS_LAYOUT_COLUMNS, 6, UserHandle.USER_CURRENT);
+ } else if (id == R.id.menu_item_columns_seven) {
+ Settings.System.putIntForUser(mContext.getContentResolver(),
+ Settings.System.QS_LAYOUT_COLUMNS, 7, UserHandle.USER_CURRENT);
+ } else if (id == R.id.menu_item_columns_eight) {
+ Settings.System.putIntForUser(mContext.getContentResolver(),
+ Settings.System.QS_LAYOUT_COLUMNS, 8, UserHandle.USER_CURRENT);
+ } else if (id == R.id.menu_item_columns_landscape_four) {
+ Settings.System.putIntForUser(mContext.getContentResolver(),
+ Settings.System.QS_LAYOUT_COLUMNS_LANDSCAPE, 4, UserHandle.USER_CURRENT);
+ } else if (id == R.id.menu_item_columns_landscape_five) {
+ Settings.System.putIntForUser(mContext.getContentResolver(),
+ Settings.System.QS_LAYOUT_COLUMNS_LANDSCAPE, 5, UserHandle.USER_CURRENT);
+ } else if (id == R.id.menu_item_columns_landscape_six) {
+ Settings.System.putIntForUser(mContext.getContentResolver(),
+ Settings.System.QS_LAYOUT_COLUMNS_LANDSCAPE, 6, UserHandle.USER_CURRENT);
+ } else if (id == R.id.menu_item_columns_landscape_seven) {
+ Settings.System.putIntForUser(mContext.getContentResolver(),
+ Settings.System.QS_LAYOUT_COLUMNS_LANDSCAPE, 7, UserHandle.USER_CURRENT);
+ } else if (id == R.id.menu_item_columns_landscape_eight) {
+ Settings.System.putIntForUser(mContext.getContentResolver(),
+ Settings.System.QS_LAYOUT_COLUMNS_LANDSCAPE, 8, UserHandle.USER_CURRENT);
+ } else if (id == R.id.menu_item_qs_columns_six) {
+ Settings.System.putIntForUser(mContext.getContentResolver(),
+ Settings.System.QS_QUICKBAR_COLUMNS, 6, UserHandle.USER_CURRENT);
+ } else if (id == R.id.menu_item_qs_columns_seven) {
+ Settings.System.putIntForUser(mContext.getContentResolver(),
+ Settings.System.QS_QUICKBAR_COLUMNS, 7, UserHandle.USER_CURRENT);
+ } else if (id == R.id.menu_item_qs_columns_eight) {
+ Settings.System.putIntForUser(mContext.getContentResolver(),
+ Settings.System.QS_QUICKBAR_COLUMNS, 8, UserHandle.USER_CURRENT);
+ } else if (id == R.id.menu_item_qs_columns_auto) {
+ Settings.System.putIntForUser(mContext.getContentResolver(),
+ Settings.System.QS_QUICKBAR_COLUMNS, -1, UserHandle.USER_CURRENT);
+ } else if (id == R.id.menu_item_titles) {
+ item.setChecked(!item.isChecked());
+ Settings.System.putIntForUser(mContext.getContentResolver(),
+ Settings.System.QS_TILE_TITLE_VISIBILITY, item.isChecked() ? 1 : 0,
+ UserHandle.USER_CURRENT);
}
+ updateSettings();
return false;
}
private void reset() {
- mTileAdapter.resetTileSpecs(mHost, QSTileHost.getDefaultSpecs(mContext));
+ ArrayList<String> tiles = new ArrayList<>();
+ String defTiles = mContext.getString(R.string.quick_settings_tiles_default);
+ for (String tile : defTiles.split(",")) {
+ tiles.add(tile);
+ }
+ mTileAdapter.resetTileSpecs(mHost, tiles);
}
private void setTileSpecs() {
@@ -368,4 +472,54 @@
mNotifQsContainer.setCustomizerAnimating(false);
}
};
+
+ public void updateSettings() {
+ final Resources res = mContext.getResources();
+ boolean isPortrait = res.getConfiguration().orientation
+ == Configuration.ORIENTATION_PORTRAIT;
+ int columns = Settings.System.getIntForUser(
+ mContext.getContentResolver(), Settings.System.QS_LAYOUT_COLUMNS, mDefaultColumns,
+ UserHandle.USER_CURRENT);
+ int columnsLandscape = Settings.System.getIntForUser(
+ mContext.getContentResolver(), Settings.System.QS_LAYOUT_COLUMNS_LANDSCAPE, mDefaultColumns,
+ UserHandle.USER_CURRENT);
+ mTileAdapter.setColumnCount(isPortrait ? columns : columnsLandscape);
+ mLayout.setSpanCount(isPortrait ? columns : columnsLandscape);
+ updateColumnsMenu();
+ }
+ private void updateColumnsMenu() {
+ int columns = Settings.System.getIntForUser(
+ mContext.getContentResolver(), Settings.System.QS_LAYOUT_COLUMNS, mDefaultColumns,
+ UserHandle.USER_CURRENT);
+ MenuItem menuItemThree = mToolbar.getMenu().findItem(R.id.menu_item_columns_three);
+ menuItemThree.setChecked(columns == 3);
+ MenuItem menuItemFour = mToolbar.getMenu().findItem(R.id.menu_item_columns_four);
+ menuItemFour.setChecked(columns == 4);
+ MenuItem menuItemFive = mToolbar.getMenu().findItem(R.id.menu_item_columns_five);
+ menuItemFive.setChecked(columns == 5);
+ int columnsLandscape = Settings.System.getIntForUser(
+ mContext.getContentResolver(), Settings.System.QS_LAYOUT_COLUMNS_LANDSCAPE, mDefaultColumns,
+ UserHandle.USER_CURRENT);
+ menuItemFour = mToolbar.getMenu().findItem(R.id.menu_item_columns_landscape_four);
+ menuItemFour.setChecked(columnsLandscape == 4);
+ menuItemFive = mToolbar.getMenu().findItem(R.id.menu_item_columns_landscape_five);
+ menuItemFive.setChecked(columnsLandscape == 5);
+ MenuItem menuItemSix = mToolbar.getMenu().findItem(R.id.menu_item_columns_landscape_six);
+ menuItemSix.setChecked(columnsLandscape == 6);
+ MenuItem menuItemSeven = mToolbar.getMenu().findItem(R.id.menu_item_columns_landscape_seven);
+ menuItemSeven.setChecked(columnsLandscape == 7);
+ MenuItem menuItemEight = mToolbar.getMenu().findItem(R.id.menu_item_columns_landscape_eight);
+ menuItemEight.setChecked(columnsLandscape == 8);
+ int qsColumns = Settings.System.getIntForUser(
+ mContext.getContentResolver(), Settings.System.QS_QUICKBAR_COLUMNS,
+ QuickQSPanel.NUM_QUICK_TILES_DEFAULT, UserHandle.USER_CURRENT);
+ menuItemSix = mToolbar.getMenu().findItem(R.id.menu_item_qs_columns_six);
+ menuItemSix.setChecked(qsColumns == 6);
+ menuItemSeven = mToolbar.getMenu().findItem(R.id.menu_item_qs_columns_seven);
+ menuItemSeven.setChecked(qsColumns == 7);
+ menuItemEight = mToolbar.getMenu().findItem(R.id.menu_item_qs_columns_eight);
+ menuItemEight.setChecked(qsColumns == 8);
+ MenuItem menuItemAuto = mToolbar.getMenu().findItem(R.id.menu_item_qs_columns_auto);
+ menuItemAuto.setChecked(qsColumns == -1);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
index bffeb3e..aeb785e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
@@ -88,8 +88,9 @@
private int mAccessibilityAction = ACTION_NONE;
private int mAccessibilityFromIndex;
private QSTileHost mHost;
+ private boolean mHideLabel;
private final UiEventLogger mUiEventLogger;
- private final AccessibilityDelegateCompat mAccessibilityDelegate;
+ //private final AccessibilityDelegateCompat mAccessibilityDelegate;
private RecyclerView mRecyclerView;
public TileAdapter(Context context, UiEventLogger uiEventLogger) {
@@ -98,7 +99,7 @@
mItemTouchHelper = new ItemTouchHelper(mCallbacks);
mDecoration = new TileItemDecoration(context);
mMinNumTiles = context.getResources().getInteger(R.integer.quick_settings_min_num_tiles);
- mAccessibilityDelegate = new TileAdapterDelegate();
+ //mAccessibilityDelegate = new TileAdapterDelegate();
}
@Override
@@ -317,13 +318,28 @@
holder.mTileView.handleStateChanged(info.state);
holder.mTileView.setShowAppLabel(position > mEditIndex && !info.isSystem);
- holder.mTileView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
+ holder.mTileView.setHideLabel(mHideLabel);
+ /*holder.mTileView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
holder.mTileView.setClickable(true);
holder.mTileView.setOnClickListener(null);
holder.mTileView.setFocusable(true);
- holder.mTileView.setFocusableInTouchMode(true);
+ holder.mTileView.setFocusableInTouchMode(true);*/
- if (mAccessibilityAction != ACTION_NONE) {
+ holder.mTileView.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ int position = holder.getLayoutPosition();
+ if (position < mEditIndex) {
+ if (canRemoveTiles()) {
+ move(position, mEditIndex);
+ }
+ } else {
+ move(position, mEditIndex);
+ }
+ }
+ });
+
+ /*if (mAccessibilityAction != ACTION_NONE) {
holder.mTileView.setClickable(selectable);
holder.mTileView.setFocusable(selectable);
holder.mTileView.setFocusableInTouchMode(selectable);
@@ -345,7 +361,7 @@
}
if (position == mFocusIndex) {
focusOnHolder(holder);
- }
+ }*/
}
private void focusOnHolder(Holder holder) {
@@ -502,7 +518,7 @@
mTileView.setBackground(null);
mTileView.getIcon().disableAnimation();
mTileView.setTag(this);
- ViewCompat.setAccessibilityDelegate(mTileView, mAccessibilityDelegate);
+ //ViewCompat.setAccessibilityDelegate(mTileView, mAccessibilityDelegate);
}
}
@@ -581,13 +597,18 @@
}
}
- private final SpanSizeLookup mSizeLookup = new SpanSizeLookup() {
+ private class OmniSpanSizeLookup extends SpanSizeLookup {
+ private int mColumns = 3;
@Override
public int getSpanSize(int position) {
final int type = getItemViewType(position);
- return type == TYPE_EDIT || type == TYPE_DIVIDER || type == TYPE_HEADER ? 3 : 1;
+ return type == TYPE_EDIT || type == TYPE_DIVIDER || type == TYPE_HEADER ? mColumns : 1;
}
- };
+ public void setColumnCount(int columns) {
+ mColumns = columns;
+ }
+ }
+ private final OmniSpanSizeLookup mSizeLookup = new OmniSpanSizeLookup();
private class TileItemDecoration extends ItemDecoration {
private final Drawable mDrawable;
@@ -707,4 +728,15 @@
public void onSwiped(ViewHolder viewHolder, int direction) {
}
};
+
+ public void setColumnCount(int columns) {
+ mSizeLookup.setColumnCount(columns);
+ }
+
+ public void setHideLabel(boolean value) {
+ if (mHideLabel != value) {
+ mHideLabel = value;
+ notifyDataSetChanged();
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
index db77e08..84c204b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
@@ -89,9 +89,11 @@
}
private void addCurrentAndStockTiles(QSTileHost host) {
- String stock = mContext.getString(R.string.quick_settings_tiles_stock);
String current = Settings.Secure.getString(mContext.getContentResolver(),
Settings.Secure.QS_TILES);
+ String possible = mContext.getString(R.string.quick_settings_tiles_stock)
+ + "," + mContext.getString(R.string.quick_settings_tiles_extra)
+ + "," + current;
final ArrayList<String> possibleTiles = new ArrayList<>();
if (current != null) {
// The setting QS_TILES is not populated immediately upon Factory Reset
@@ -99,15 +101,15 @@
} else {
current = "";
}
- String[] stockSplit = stock.split(",");
+ String[] stockSplit = possible.split(",");
for (String spec : stockSplit) {
if (!current.contains(spec)) {
possibleTiles.add(spec);
}
}
- if (Build.IS_DEBUGGABLE && !current.contains(GarbageMonitor.MemoryTile.TILE_SPEC)) {
+ /*if (Build.IS_DEBUGGABLE && !current.contains(GarbageMonitor.MemoryTile.TILE_SPEC)) {
possibleTiles.add(GarbageMonitor.MemoryTile.TILE_SPEC);
- }
+ }*/
final ArrayList<QSTile> tilesToAdd = new ArrayList<>();
for (String spec : possibleTiles) {
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 c182a58..f77836c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
@@ -35,17 +35,24 @@
import com.android.systemui.qs.tiles.DataSaverTile;
import com.android.systemui.qs.tiles.DndTile;
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.LocationTile;
import com.android.systemui.qs.tiles.NfcTile;
import com.android.systemui.qs.tiles.NightDisplayTile;
import com.android.systemui.qs.tiles.RotationLockTile;
import com.android.systemui.qs.tiles.ScreenRecordTile;
+import com.android.systemui.qs.tiles.SyncTile;
import com.android.systemui.qs.tiles.UiModeNightTile;
+import com.android.systemui.qs.tiles.SoundTile;
+import com.android.systemui.qs.tiles.ScreenshotTile;
import com.android.systemui.qs.tiles.UserTile;
import com.android.systemui.qs.tiles.WifiTile;
import com.android.systemui.qs.tiles.WorkModeTile;
import com.android.systemui.util.leak.GarbageMonitor;
+import com.android.systemui.qs.tiles.CaffeineTile;
+import com.android.systemui.qs.tiles.AmbientDisplayTile;
+import com.android.systemui.qs.tiles.UsbTetherTile;
import javax.inject.Inject;
import javax.inject.Provider;
@@ -78,6 +85,13 @@
private final Provider<GarbageMonitor.MemoryTile> mMemoryTileProvider;
private final Provider<UiModeNightTile> mUiModeNightTileProvider;
private final Provider<ScreenRecordTile> mScreenRecordTileProvider;
+ private final Provider<CaffeineTile> mCaffeineTileProvider;
+ private final Provider<AmbientDisplayTile> mAmbientDisplayTileProvider;
+ private final Provider<UsbTetherTile> mUsbTetherTileProvider;
+ private final Provider<SyncTile> mSyncTileProvider;
+ private final Provider<SoundTile> mSoundTileProvider;
+ private final Provider<ScreenshotTile> mScreenshotTileProvider;
+ private final Provider<HeadsUpTile> mHeadsUpTileProvider;
private final Lazy<QSHost> mQsHostLazy;
@@ -102,7 +116,14 @@
Provider<NfcTile> nfcTileProvider,
Provider<GarbageMonitor.MemoryTile> memoryTileProvider,
Provider<UiModeNightTile> uiModeNightTileProvider,
- Provider<ScreenRecordTile> screenRecordTileProvider) {
+ Provider<ScreenRecordTile> screenRecordTileProvider,
+ Provider<CaffeineTile> caffeineTileProvider,
+ Provider<AmbientDisplayTile> ambientDisplayTileProvider,
+ Provider<UsbTetherTile> usbTetherTileProvider,
+ Provider<SyncTile> syncTileProvider,
+ Provider<SoundTile> soundTileProvider,
+ Provider<ScreenshotTile> screenshotTileProvider,
+ Provider<HeadsUpTile> headsUpTileProvider) {
mQsHostLazy = qsHostLazy;
mWifiTileProvider = wifiTileProvider;
mBluetoothTileProvider = bluetoothTileProvider;
@@ -124,6 +145,13 @@
mMemoryTileProvider = memoryTileProvider;
mUiModeNightTileProvider = uiModeNightTileProvider;
mScreenRecordTileProvider = screenRecordTileProvider;
+ mCaffeineTileProvider = caffeineTileProvider;
+ mAmbientDisplayTileProvider = ambientDisplayTileProvider;
+ mUsbTetherTileProvider = usbTetherTileProvider;
+ mSyncTileProvider = syncTileProvider;
+ mSoundTileProvider = soundTileProvider;
+ mScreenshotTileProvider = screenshotTileProvider;
+ mHeadsUpTileProvider = headsUpTileProvider;
}
public QSTile createTile(String tileSpec) {
@@ -175,6 +203,20 @@
return mUiModeNightTileProvider.get();
case "screenrecord":
return mScreenRecordTileProvider.get();
+ case "caffeine":
+ return mCaffeineTileProvider.get();
+ case "ambient_display":
+ return mAmbientDisplayTileProvider.get();
+ case "usb_tether":
+ return mUsbTetherTileProvider.get();
+ case "sync":
+ return mSyncTileProvider.get();
+ case "sound":
+ return mSoundTileProvider.get();
+ case "screenshot":
+ return mScreenshotTileProvider.get();
+ case "heads_up":
+ return mHeadsUpTileProvider.get();
}
// Custom tiles
@@ -184,11 +226,11 @@
}
// Debug tiles.
- if (Build.IS_DEBUGGABLE) {
+ /*if (Build.IS_DEBUGGABLE) {
if (tileSpec.equals(GarbageMonitor.MemoryTile.TILE_SPEC)) {
return mMemoryTileProvider.get();
}
- }
+ }*/
// Broken tiles.
Log.w(TAG, "No stock tile spec: " + tileSpec);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
index 795d062..b34a637 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
@@ -37,6 +37,9 @@
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
+import android.os.UserHandle;
+import android.os.Vibrator;
+import android.provider.Settings;
import android.service.quicksettings.Tile;
import android.text.format.DateUtils;
import android.util.ArraySet;
@@ -142,6 +145,8 @@
*/
abstract protected void handleUpdateState(TState state, Object arg);
+ protected Vibrator mVibrator;
+
/**
* Declare the category of this tile.
*
@@ -158,6 +163,7 @@
mTmpState = newTileState();
mQSLogger = host.getQSLogger();
mUiEventLogger = host.getUiEventLogger();
+ mVibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
}
protected final void resetStates() {
@@ -234,6 +240,18 @@
// safe to call from any thread
+ public boolean isVibrationEnabled() {
+ return (Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.QUICK_SETTINGS_TILES_VIBRATE, 0, UserHandle.USER_CURRENT) == 1);
+ }
+
+ public void vibrateTile(int duration) {
+ if (!isVibrationEnabled()) { return; }
+ if (mVibrator != null) {
+ if (mVibrator.hasVibrator()) { mVibrator.vibrate(duration); }
+ }
+ }
+
public void addCallback(Callback callback) {
mHandler.obtainMessage(H.ADD_CALLBACK, callback).sendToTarget();
}
@@ -254,6 +272,7 @@
getInstanceId());
mQSLogger.logTileClick(mTileSpec, mStatusBarStateController.getState(), mState.state);
mHandler.sendEmptyMessage(H.CLICK);
+ vibrateTile(45);
}
public void secondaryClick() {
@@ -280,6 +299,7 @@
mContext,
Prefs.Key.QS_LONG_PRESS_TOOLTIP_SHOWN_COUNT,
QuickStatusBarHeader.MAX_TOOLTIP_SHOWN_COUNT);
+ vibrateTile(45);
}
public LogMaker populate(LogMaker logMaker) {
@@ -357,8 +377,10 @@
* {@link QSTileImpl#getLongClickIntent}
*/
protected void handleLongClick() {
- Dependency.get(ActivityStarter.class).postStartActivityDismissingKeyguard(
- getLongClickIntent(), 0);
+ if (getLongClickIntent() != null) {
+ Dependency.get(ActivityStarter.class).postStartActivityDismissingKeyguard(
+ getLongClickIntent(), 0);
+ }
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java
index 8a360ee..84fd972 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java
@@ -151,4 +151,8 @@
mLabelContainer.setClickable(false);
mLabelContainer.setLongClickable(false);
}
+
+ public void setHideLabel(boolean value) {
+ mLabelContainer.setVisibility(value ? View.GONE : View.VISIBLE);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
index b24fdbf..ae4e16a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
@@ -35,6 +35,7 @@
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.qs.QSTile.BooleanState;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.qs.GlobalSetting;
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.tileimpl.QSTileImpl;
@@ -49,13 +50,15 @@
private final BroadcastDispatcher mBroadcastDispatcher;
private boolean mListening;
+ private KeyguardStateController mKeyguard;
@Inject
public AirplaneModeTile(QSHost host, ActivityStarter activityStarter,
- BroadcastDispatcher broadcastDispatcher) {
+ BroadcastDispatcher broadcastDispatcher, KeyguardStateController keyguardStateController) {
super(host);
mActivityStarter = activityStarter;
mBroadcastDispatcher = broadcastDispatcher;
+ mKeyguard = keyguardStateController;
mSetting = new GlobalSetting(mContext, mHandler, Global.AIRPLANE_MODE_ON) {
@Override
@@ -79,6 +82,13 @@
new Intent(TelephonyManager.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS), 0);
return;
}
+ if (mKeyguard.isMethodSecure() && mKeyguard.isShowing()) {
+ mActivityStarter.postQSRunnableDismissingKeyguard(() -> {
+ setEnabled(!mState.value);
+ });
+ return;
+ }
+ // no secure keyguard
setEnabled(!airplaneModeEnabled);
}
@@ -151,4 +161,11 @@
}
}
};
+
+ private final class Callback implements KeyguardStateController.Callback {
+ @Override
+ public void onKeyguardShowingChanged() {
+ refreshState();
+ }
+ };
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AmbientDisplayTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AmbientDisplayTile.java
new file mode 100644
index 0000000..084714c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AmbientDisplayTile.java
@@ -0,0 +1,133 @@
+/*
+ * 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.Build;
+import android.os.SystemProperties;
+import android.provider.Settings;
+import android.provider.Settings.Secure;
+import android.service.quicksettings.Tile;
+import android.text.TextUtils;
+
+import com.android.systemui.plugins.qs.QSTile.BooleanState;
+import com.android.systemui.qs.QSHost;
+import com.android.systemui.qs.tileimpl.QSTileImpl;
+import com.android.systemui.qs.SecureSetting;
+import com.android.systemui.R;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+
+import javax.inject.Inject;
+
+/** Quick settings tile: Ambient Display **/
+public class AmbientDisplayTile extends QSTileImpl<BooleanState> {
+
+ private final Icon mIcon = ResourceIcon.get(R.drawable.ic_qs_ambient_display);
+
+ private static final Intent DISPLAY_SETTINGS = new Intent("android.settings.DISPLAY_SETTINGS");
+
+ private final SecureSetting mSetting;
+
+ @Inject
+ public AmbientDisplayTile(QSHost host) {
+ super(host);
+
+ mSetting = new SecureSetting(mContext, mHandler, Secure.DOZE_ENABLED) {
+ @Override
+ protected void handleValueChanged(int value, boolean observedChange) {
+ handleRefreshState(value);
+ }
+ };
+ }
+
+ @Override
+ public boolean isAvailable() {
+ String name = Build.IS_DEBUGGABLE ? SystemProperties.get("debug.doze.component") : null;
+ if (TextUtils.isEmpty(name)) {
+ name = mContext.getString(com.android.internal.R.string.config_dozeComponent);
+ }
+ return !TextUtils.isEmpty(name);
+ }
+
+ @Override
+ public BooleanState newTileState() {
+ return new BooleanState();
+ }
+
+ @Override
+ protected void handleClick() {
+ setEnabled(!mState.value);
+ refreshState();
+ }
+
+ @Override
+ public Intent getLongClickIntent() {
+ return DISPLAY_SETTINGS;
+ }
+
+ private void setEnabled(boolean enabled) {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.DOZE_ENABLED,
+ enabled ? 1 : 0);
+ }
+
+ @Override
+ protected void handleUpdateState(BooleanState state, Object arg) {
+ final int value = arg instanceof Integer ? (Integer) arg : mSetting.getValue();
+ final boolean enable = value != 0;
+ state.value = enable;
+ state.label = mContext.getString(R.string.quick_settings_ambient_display_label);
+ state.icon = mIcon;
+ if (enable) {
+ state.contentDescription = mContext.getString(
+ R.string.accessibility_quick_settings_ambient_display_on);
+ state.state = Tile.STATE_ACTIVE;
+ } else {
+ state.contentDescription = mContext.getString(
+ R.string.accessibility_quick_settings_ambient_display_off);
+ state.state = Tile.STATE_INACTIVE;
+ }
+ }
+
+ @Override
+ public CharSequence getTileLabel() {
+ return mContext.getString(R.string.quick_settings_ambient_display_label);
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsEvent.BLISSIFY;
+ }
+
+ @Override
+ protected String composeChangeAnnouncement() {
+ if (mState.value) {
+ return mContext.getString(
+ R.string.accessibility_quick_settings_ambient_display_changed_on);
+ } else {
+ return mContext.getString(
+ R.string.accessibility_quick_settings_ambient_display_changed_off);
+ }
+ }
+
+ @Override
+ public void handleSetListening(boolean listening) {
+ // Do nothing
+ }
+}
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 0000000..fba8e88
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CaffeineTile.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2016 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.systemui.qs.tiles;
+
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.PowerManager;
+import android.provider.Settings;
+import android.service.quicksettings.Tile;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.systemui.qs.QSHost;
+import com.android.systemui.plugins.qs.QSTile.BooleanState;
+import com.android.systemui.qs.tileimpl.QSTileImpl;
+import com.android.systemui.R;
+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 final Receiver mReceiver = new Receiver();
+
+ @Inject
+ public CaffeineTile(QSHost host) {
+ super(host);
+ mWakeLock = ((PowerManager) mContext.getSystemService(Context.POWER_SERVICE)).newWakeLock(
+ PowerManager.FULL_WAKE_LOCK, "CaffeineTile");
+ mReceiver.init();
+ }
+
+ @Override
+ public BooleanState newTileState() {
+ return new BooleanState();
+ }
+
+ @Override
+ protected void handleDestroy() {
+ super.handleDestroy();
+ mReceiver.destroy();
+ if (mWakeLock.isHeld()) {
+ mWakeLock.release();
+ }
+ }
+
+ @Override
+ public CharSequence getTileLabel() {
+ return mContext.getString(R.string.quick_settings_caffeine_label);
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsEvent.BLISSIFY;
+ }
+
+ @Override
+ public void handleSetListening(boolean listening) {}
+
+ @Override
+ public void handleClick() {
+ // toggle
+ if (mWakeLock.isHeld()) {
+ mWakeLock.release();
+ } else {
+ mWakeLock.acquire();
+ }
+ refreshState();
+ }
+
+ @Override
+ public Intent getLongClickIntent() {
+ return new Intent().setComponent(new ComponentName(
+ "com.android.settings", "com.android.settings.Settings$DisplaySettingsActivity"));
+ }
+
+ @Override
+ protected void handleUpdateState(BooleanState state, Object arg) {
+ if (mWakeLock == null) {
+ return;
+ }
+ if (state.slash == null) {
+ state.slash = new SlashState();
+ }
+ state.icon = mIcon;
+ state.value = mWakeLock.isHeld();
+ state.label = mContext.getString(R.string.quick_settings_caffeine_label);
+ if (state.value) {
+ state.slash.isSlashed = false;
+ state.contentDescription = mContext.getString(
+ R.string.accessibility_quick_settings_caffeine_on);
+ state.state = Tile.STATE_ACTIVE;
+ } else {
+ state.slash.isSlashed = true;
+ 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)
+ if (mWakeLock.isHeld()) {
+ mWakeLock.release();
+ }
+ refreshState();
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index 59597ac..5894903 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -47,6 +47,7 @@
import com.android.systemui.qs.SignalTileView;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.statusbar.phone.SystemUIDialog;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.NetworkController.IconState;
import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
@@ -60,12 +61,14 @@
private final NetworkController mController;
private final DataUsageController mDataController;
private final CellularDetailAdapter mDetailAdapter;
+ private KeyguardStateController mKeyguard;
private final CellSignalCallback mSignalCallback = new CellSignalCallback();
private final ActivityStarter mActivityStarter;
@Inject
- public CellularTile(QSHost host, NetworkController networkController,
+ public CellularTile(QSHost host, KeyguardStateController keyguardStateController,
+ NetworkController networkController,
ActivityStarter activityStarter) {
super(host);
mController = networkController;
@@ -73,6 +76,7 @@
mDataController = mController.getMobileDataController();
mDetailAdapter = new CellularDetailAdapter();
mController.observe(getLifecycle(), mSignalCallback);
+ mKeyguard = keyguardStateController;
}
@Override
@@ -104,7 +108,11 @@
return;
}
if (mDataController.isMobileDataEnabled()) {
- maybeShowDisableDialog();
+ if (mKeyguard.isMethodSecure() && mKeyguard.isShowing()) {
+ mActivityStarter.postQSRunnableDismissingKeyguard(this::maybeShowDisableDialog);
+ } else {
+ maybeShowDisableDialog();
+ }
} else {
mDataController.setMobileDataEnabled(true);
}
@@ -343,4 +351,11 @@
fireToggleStateChanged(enabled);
}
}
+
+ private final class Callback implements KeyguardStateController.Callback {
+ @Override
+ public void onKeyguardShowingChanged() {
+ 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 0000000..fe053da
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HeadsUpTile.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2015 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.systemui.qs.tiles;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.provider.Settings;
+import android.provider.Settings.Global;
+import android.service.quicksettings.Tile;
+
+import com.android.systemui.qs.GlobalSetting;
+import com.android.systemui.qs.QSHost;
+import com.android.systemui.qs.tileimpl.QSTileImpl;
+import com.android.systemui.plugins.qs.QSTile.BooleanState;
+import com.android.systemui.R;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+
+import javax.inject.Inject;
+
+/** Quick settings tile: Heads up **/
+public class HeadsUpTile extends QSTileImpl<BooleanState> {
+
+ private final GlobalSetting mSetting;
+
+ private final Icon mIcon = ResourceIcon.get(R.drawable.ic_qs_heads_up);
+
+ @Inject
+ public HeadsUpTile(QSHost host) {
+ super(host);
+
+ mSetting = new GlobalSetting(mContext, mHandler, Global.HEADS_UP_NOTIFICATIONS_ENABLED) {
+ @Override
+ protected void handleValueChanged(int value) {
+ handleRefreshState(value);
+ }
+ };
+ }
+
+ @Override
+ public BooleanState newTileState() {
+ return new BooleanState();
+ }
+
+ @Override
+ public void handleClick() {
+ setEnabled(!mState.value);
+ refreshState();
+ }
+
+ @Override
+ public Intent getLongClickIntent() {
+ return new Intent().setComponent(new ComponentName(
+ "com.android.settings", "com.android.settings.Settings$HeadsUpSettingsActivity"));
+ }
+
+ @Override
+ public CharSequence getTileLabel() {
+ return mContext.getString(R.string.quick_settings_heads_up_label);
+ }
+
+ 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) {
+
+ if (state.slash == null) {
+ state.slash = new SlashState();
+ }
+ state.icon = mIcon;
+
+ 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);
+ if (headsUp) {
+ state.contentDescription = mContext.getString(
+ R.string.accessibility_quick_settings_heads_up_on);
+ state.slash.isSlashed = false;
+ state.state = Tile.STATE_ACTIVE;
+ } else {
+ state.contentDescription = mContext.getString(
+ R.string.accessibility_quick_settings_heads_up_off);
+ state.slash.isSlashed = true;
+ state.state = Tile.STATE_INACTIVE;
+ }
+ }
+
+ @Override
+ protected String composeChangeAnnouncement() {
+ if (mState.value) {
+ return mContext.getString(
+ R.string.accessibility_quick_settings_heads_up_changed_on);
+ } else {
+ return mContext.getString(
+ R.string.accessibility_quick_settings_heads_up_changed_off);
+ }
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsEvent.BLISSIFY;
+ }
+
+ @Override
+ public void handleSetListening(boolean listening) {
+ // Do nothing
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
index 02f364b..bd59d25 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
@@ -39,6 +39,11 @@
private final Icon mIcon = ResourceIcon.get(R.drawable.ic_location);
+ private static final int BATTERY_SAVING = Settings.Secure.LOCATION_MODE_BATTERY_SAVING;
+ private static final int SENSORS_ONLY = Settings.Secure.LOCATION_MODE_SENSORS_ONLY;
+ private static final int HIGH_ACCURACY = Settings.Secure.LOCATION_MODE_HIGH_ACCURACY;
+ private static final int OFF = Settings.Secure.LOCATION_MODE_OFF;
+
private final LocationController mController;
private final KeyguardStateController mKeyguard;
private final ActivityStarter mActivityStarter;
@@ -69,14 +74,29 @@
protected void handleClick() {
if (mKeyguard.isMethodSecure() && mKeyguard.isShowing()) {
mActivityStarter.postQSRunnableDismissingKeyguard(() -> {
- final boolean wasEnabled = mState.value;
mHost.openPanels();
- mController.setLocationEnabled(!wasEnabled);
+ switchMode();
});
return;
}
- final boolean wasEnabled = mState.value;
- mController.setLocationEnabled(!wasEnabled);
+ switchMode();
+ }
+
+ private void switchMode() {
+ int currentMode = mController.getCurrentMode();
+ if (currentMode == BATTERY_SAVING) {
+ //from battery saving to off
+ mController.setLocationEnabled(OFF);
+ } else if (currentMode == SENSORS_ONLY) {
+ //from sensor only to high precision
+ mController.setLocationEnabled(HIGH_ACCURACY);
+ } else if (currentMode == HIGH_ACCURACY) {
+ //from high precision to battery saving
+ mController.setLocationEnabled(BATTERY_SAVING);
+ } else {
+ //from off to sensor only
+ mController.setLocationEnabled(SENSORS_ONLY);
+ }
}
@Override
@@ -86,24 +106,49 @@
@Override
protected void handleUpdateState(BooleanState state, Object arg) {
- if (state.slash == null) {
- state.slash = new SlashState();
- }
final boolean locationEnabled = mController.isLocationEnabled();
-
// Work around for bug 15916487: don't show location tile on top of lock screen. After the
// bug is fixed, this should be reverted to only hiding it on secure lock screens:
// state.visible = !(mKeyguard.isMethodSecure() && mKeyguard.isShowing());
- state.value = locationEnabled;
checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_SHARE_LOCATION);
if (state.disabledByPolicy == false) {
checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_CONFIG_LOCATION);
}
- state.icon = mIcon;
- state.slash.isSlashed = !state.value;
- state.label = mContext.getString(R.string.quick_settings_location_label);
- state.contentDescription = state.label;
- state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
+ int currentMode = mController.getCurrentMode();
+ switch (currentMode) {
+ case BATTERY_SAVING:
+ state.value = true;
+ state.contentDescription = mContext.getString(R.string.accessibility_quick_settings_location_battery_saving);
+ state.label = mContext.getString(R.string.quick_settings_location_label);
+ state.secondaryLabel = mContext.getString(R.string.quick_settings_location_secondary_battery_saving);
+ state.icon = ResourceIcon.get(R.drawable.ic_qs_location_battery_saving);
+ state.state = Tile.STATE_ACTIVE;
+ break;
+ case SENSORS_ONLY:
+ state.value = true;
+ state.contentDescription = mContext.getString(R.string.accessibility_quick_settings_location_gps_only);
+ state.label = mContext.getString(R.string.quick_settings_location_label);
+ state.secondaryLabel = mContext.getString(R.string.quick_settings_location_secondary_gps_only);
+ state.icon = mIcon;
+ state.state = Tile.STATE_ACTIVE;
+ break;
+ case HIGH_ACCURACY:
+ state.value = true;
+ state.contentDescription = mContext.getString(R.string.accessibility_quick_settings_location_high_accuracy);
+ state.label = mContext.getString(R.string.quick_settings_location_label);
+ state.secondaryLabel = mContext.getString(R.string.quick_settings_location_secondary_high_accuracy);
+ state.icon = ResourceIcon.get(R.drawable.ic_qs_location_high_accuracy);
+ state.state = Tile.STATE_ACTIVE;
+ break;
+ case OFF:
+ state.value = false;
+ state.contentDescription = mContext.getString(R.string.accessibility_quick_settings_location_off);
+ state.label = mContext.getString(R.string.quick_settings_location_label);
+ state.secondaryLabel = mContext.getString(R.string.quick_settings_secondary_location_off);
+ state.icon = mIcon;
+ state.state = Tile.STATE_INACTIVE;
+ break;
+ }
state.expandedAccessibilityClassName = Switch.class.getName();
}
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 4bee075..407c950 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NfcTile.java
@@ -39,6 +39,8 @@
/** Quick settings tile: Enable/Disable NFC **/
public class NfcTile extends QSTileImpl<BooleanState> {
+ private final Icon mIcon = ResourceIcon.get(R.drawable.ic_qs_nfc);
+
private NfcAdapter mAdapter;
private BroadcastDispatcher mBroadcastDispatcher;
@@ -78,7 +80,7 @@
@Override
public Intent getLongClickIntent() {
- return new Intent(Settings.ACTION_NFC_SETTINGS);
+ return new Intent(Settings.Panel.ACTION_NFC);
}
@Override
@@ -109,8 +111,7 @@
state.state = getAdapter() == null
? Tile.STATE_UNAVAILABLE
: state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
- state.icon = ResourceIcon.get(
- state.value ? R.drawable.ic_qs_nfc_enabled : R.drawable.ic_qs_nfc_disabled);
+ state.icon = mIcon;
state.label = mContext.getString(R.string.quick_settings_nfc_label);
state.expandedAccessibilityClassName = Switch.class.getName();
state.contentDescription = state.label;
@@ -133,7 +134,7 @@
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/qs/tiles/ScreenshotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenshotTile.java
new file mode 100644
index 0000000..f48cac6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenshotTile.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2017 ABC rom
+ * 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.Context;
+import android.content.Intent;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.service.quicksettings.Tile;
+
+import com.android.internal.util.bliss.BlissUtils;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.systemui.qs.QSHost;
+import com.android.systemui.plugins.qs.QSTile.BooleanState;
+import com.android.systemui.qs.tileimpl.QSTileImpl;
+import com.android.systemui.R;
+
+import javax.inject.Inject;
+
+/** Quick settings tile: Screenshot **/
+public class ScreenshotTile extends QSTileImpl<BooleanState> {
+
+ private boolean mRegion = false;
+
+ @Inject
+ public ScreenshotTile(QSHost host) {
+ super(host);
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsEvent.BLISSIFY;
+ }
+
+ @Override
+ public BooleanState newTileState() {
+ return new BooleanState();
+ }
+
+ @Override
+ public void handleSetListening(boolean listening) {
+ }
+
+ @Override
+ public void handleClick() {
+ mRegion = !mRegion;
+ refreshState();
+ }
+
+ @Override
+ public void handleLongClick() {
+ mHost.collapsePanels();
+
+ //finish collapsing the panel
+ try {
+ Thread.sleep(1000); //1s
+ } catch (InterruptedException ie) {}
+ BlissUtils.takeScreenshot(mRegion ? false : true);
+ }
+
+ @Override
+ public Intent getLongClickIntent() {
+ return null;
+ }
+
+ @Override
+ public CharSequence getTileLabel() {
+ return mContext.getString(R.string.quick_settings_screenshot_label);
+ }
+
+ @Override
+ protected void handleUpdateState(BooleanState state, Object arg) {
+ if (mRegion) {
+ state.label = mContext.getString(R.string.quick_settings_region_screenshot_label);
+ state.icon = ResourceIcon.get(R.drawable.ic_qs_region_screenshot);
+ state.contentDescription = mContext.getString(
+ R.string.quick_settings_region_screenshot_label);
+ } else {
+ state.label = mContext.getString(R.string.quick_settings_screenshot_label);
+ state.icon = ResourceIcon.get(R.drawable.ic_qs_screenshot);
+ state.contentDescription = mContext.getString(
+ R.string.quick_settings_screenshot_label);
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/SoundTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/SoundTile.java
new file mode 100644
index 0000000..fc78dd9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/SoundTile.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2016 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.qs.tiles;
+
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.media.AudioManager;
+import android.provider.Settings.Global;
+import android.service.quicksettings.Tile;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.systemui.Dependency;
+import com.android.systemui.qs.QSHost;
+import com.android.systemui.plugins.qs.QSTile.BooleanState;
+import com.android.systemui.qs.tileimpl.QSTileImpl;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.policy.ZenModeController;
+
+import javax.inject.Inject;
+
+public class SoundTile extends QSTileImpl<BooleanState> {
+
+ private final ZenModeController mZenController;
+ private final AudioManager mAudioManager;
+
+ private boolean mListening = false;
+
+ private BroadcastReceiver mReceiver;
+ private IntentFilter mFilter;
+
+ @Inject
+ public SoundTile(QSHost host) {
+ super(host);
+ mZenController = Dependency.get(ZenModeController.class);
+ mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+ mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ refreshState();
+ }
+ };
+ }
+
+ @Override
+ public BooleanState newTileState() {
+ return new BooleanState();
+ }
+
+ @Override
+ public void handleSetListening(boolean listening) {
+ if (mAudioManager == null) {
+ return;
+ }
+ if (mListening == listening) return;
+ mListening = listening;
+ if (listening) {
+ final IntentFilter filter = new IntentFilter();
+ filter.addAction(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION);
+ mContext.registerReceiver(mReceiver, filter);
+ } else {
+ mContext.unregisterReceiver(mReceiver);
+ }
+ }
+
+ @Override
+ public void handleClick() {
+ updateState();
+ }
+
+ @Override
+ public void handleLongClick() {
+ mAudioManager.adjustVolume(AudioManager.ADJUST_SAME, AudioManager.FLAG_SHOW_UI);
+ }
+
+ @Override
+ public Intent getLongClickIntent() {
+ return null;
+ }
+
+ private void updateState() {
+ int oldState = mAudioManager.getRingerModeInternal();
+ int newState = oldState;
+ switch (oldState) {
+ case AudioManager.RINGER_MODE_NORMAL:
+ newState = AudioManager.RINGER_MODE_VIBRATE;
+ mAudioManager.setRingerModeInternal(newState);
+ break;
+ case AudioManager.RINGER_MODE_VIBRATE:
+ newState = AudioManager.RINGER_MODE_SILENT;
+ mZenController.setZen(Global.ZEN_MODE_ALARMS, null, TAG);
+ break;
+ case AudioManager.RINGER_MODE_SILENT:
+ newState = AudioManager.RINGER_MODE_NORMAL;
+ mZenController.setZen(Global.ZEN_MODE_OFF, null, TAG);
+ mAudioManager.setRingerModeInternal(newState);
+ break;
+ default:
+ break;
+ }
+ }
+
+ @Override
+ public CharSequence getTileLabel() {
+ return mContext.getString(R.string.quick_settings_sound_label);
+ }
+
+ @Override
+ protected void handleUpdateState(BooleanState state, Object arg) {
+ if (mAudioManager == null) {
+ return;
+ }
+ switch (mAudioManager.getRingerModeInternal()) {
+ case AudioManager.RINGER_MODE_NORMAL:
+ state.icon = ResourceIcon.get(R.drawable.ic_qs_ringer_audible);
+ state.label = mContext.getString(R.string.quick_settings_sound_ring);
+ state.contentDescription = mContext.getString(
+ R.string.quick_settings_sound_ring);
+ break;
+ case AudioManager.RINGER_MODE_VIBRATE:
+ state.icon = ResourceIcon.get(R.drawable.ic_qs_ringer_vibrate);
+ state.label = mContext.getString(R.string.quick_settings_sound_vibrate);
+ state.contentDescription = mContext.getString(
+ R.string.quick_settings_sound_vibrate);
+ break;
+ case AudioManager.RINGER_MODE_SILENT:
+ state.icon = ResourceIcon.get(R.drawable.ic_qs_ringer_silent);
+ state.label = mContext.getString(R.string.quick_settings_sound_dnd);
+ state.contentDescription = mContext.getString(
+ R.string.quick_settings_sound_dnd);
+ break;
+ default:
+ break;
+ }
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsEvent.BLISSIFY;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/SyncTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/SyncTile.java
new file mode 100644
index 0000000..e00e1b2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/SyncTile.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2015 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.systemui.qs.tiles;
+
+import android.content.ContentResolver;
+import android.content.Intent;
+import android.content.SyncStatusObserver;
+import android.service.quicksettings.Tile;
+
+import com.android.systemui.R;
+import com.android.systemui.qs.QSHost;
+import com.android.systemui.plugins.qs.QSTile.BooleanState;
+import com.android.systemui.qs.tileimpl.QSTileImpl;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+
+import javax.inject.Inject;
+
+/** Quick settings tile: Sync **/
+public class SyncTile extends QSTileImpl<BooleanState> {
+
+ private Object mSyncObserverHandle = null;
+ private boolean mListening;
+
+ @Inject
+ public SyncTile(QSHost host) {
+ super(host);
+ }
+
+ @Override
+ public BooleanState newTileState() {
+ return new BooleanState();
+ }
+
+ @Override
+ public void handleClick() {
+ ContentResolver.setMasterSyncAutomatically(!mState.value);
+ refreshState();
+ }
+
+ @Override
+ public Intent getLongClickIntent() {
+ Intent intent = new Intent("android.settings.SYNC_SETTINGS");
+ intent.addCategory(Intent.CATEGORY_DEFAULT);
+ return intent;
+ }
+
+ @Override
+ public CharSequence getTileLabel() {
+ return mContext.getString(R.string.quick_settings_sync_label);
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsEvent.BLISSIFY;
+ }
+
+ @Override
+ protected void handleUpdateState(BooleanState state, Object arg) {
+ state.value = ContentResolver.getMasterSyncAutomatically();
+ state.label = mContext.getString(R.string.quick_settings_sync_label);
+ if (state.value) {
+ state.icon = ResourceIcon.get(R.drawable.ic_qs_sync_on);
+ state.contentDescription = mContext.getString(
+ R.string.accessibility_quick_settings_sync_on);
+ state.state = Tile.STATE_ACTIVE;
+ } else {
+ state.icon = ResourceIcon.get(R.drawable.ic_qs_sync_off);
+ state.contentDescription = mContext.getString(
+ R.string.accessibility_quick_settings_sync_off);
+ state.state = Tile.STATE_INACTIVE;
+ }
+ }
+
+ @Override
+ protected String composeChangeAnnouncement() {
+ if (mState.value) {
+ return mContext.getString(R.string.accessibility_quick_settings_sync_changed_on);
+ } else {
+ return mContext.getString(R.string.accessibility_quick_settings_sync_changed_off);
+ }
+ }
+
+ @Override
+ public void handleSetListening(boolean listening) {
+ if (mListening == listening) return;
+ mListening = listening;
+
+ if (listening) {
+ mSyncObserverHandle = ContentResolver.addStatusChangeListener(
+ ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS, mSyncObserver);
+ } else {
+ ContentResolver.removeStatusChangeListener(mSyncObserverHandle);
+ mSyncObserverHandle = null;
+ }
+ }
+
+ private SyncStatusObserver mSyncObserver = new SyncStatusObserver() {
+ public void onStatusChanged(int which) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ refreshState();
+ }
+ });
+ }
+ };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UsbTetherTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UsbTetherTile.java
new file mode 100644
index 0000000..e45eaf0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UsbTetherTile.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2017-2018 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.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.hardware.usb.UsbManager;
+import android.provider.Settings;
+import android.net.ConnectivityManager;
+import android.service.quicksettings.Tile;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.systemui.plugins.qs.QSTile.BooleanState;
+import com.android.systemui.qs.QSHost;
+import com.android.systemui.qs.tileimpl.QSTileImpl;
+import com.android.systemui.R;
+
+import javax.inject.Inject;
+
+/**
+ * USB Tether quick settings tile
+ */
+public class UsbTetherTile extends QSTileImpl<BooleanState> {
+
+ private final Icon mIcon = ResourceIcon.get(R.drawable.ic_qs_usb_tether);
+
+ private static final Intent TETHER_SETTINGS = new Intent().setComponent(new ComponentName(
+ "com.android.settings", "com.android.settings.TetherSettings"));
+
+ private final ConnectivityManager mConnectivityManager;
+
+ private boolean mListening;
+
+ private boolean mUsbConnected = false;
+ private boolean mUsbTetherEnabled = false;
+
+ @Inject
+ public UsbTetherTile(QSHost host) {
+ super(host);
+ mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
+ }
+
+ public BooleanState newTileState() {
+ return new BooleanState();
+ }
+
+ @Override
+ public void handleSetListening(boolean listening) {
+ if (mListening == listening) {
+ return;
+ }
+ mListening = listening;
+ if (listening) {
+ final IntentFilter filter = new IntentFilter();
+ filter.addAction(UsbManager.ACTION_USB_STATE);
+ mContext.registerReceiver(mReceiver, filter);
+ } else {
+ mContext.unregisterReceiver(mReceiver);
+ }
+ }
+
+ @Override
+ protected void handleClick() {
+ if (mUsbConnected) {
+ mConnectivityManager.setUsbTethering(!mUsbTetherEnabled);
+ }
+ }
+
+ @Override
+ public Intent getLongClickIntent() {
+ return new Intent(TETHER_SETTINGS);
+ }
+
+ private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ mUsbConnected = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false);
+ if (mUsbConnected && mConnectivityManager.isTetheringSupported()) {
+ mUsbTetherEnabled = intent.getBooleanExtra(UsbManager.USB_FUNCTION_RNDIS, false);
+ } else {
+ mUsbTetherEnabled = false;
+ }
+ refreshState();
+ }
+ };
+
+ @Override
+ protected void handleUpdateState(BooleanState state, Object arg) {
+ state.value = mUsbTetherEnabled;
+ state.label = mContext.getString(R.string.quick_settings_usb_tether_label);
+ state.icon = mIcon;
+ state.state = !mUsbConnected ? Tile.STATE_UNAVAILABLE
+ : mUsbTetherEnabled ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
+ }
+
+ @Override
+ public CharSequence getTileLabel() {
+ return mContext.getString(R.string.quick_settings_usb_tether_label);
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsEvent.BLISSIFY;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index 1279d42..3e0e49a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -55,7 +55,7 @@
/** Quick settings tile: Wifi **/
public class WifiTile extends QSTileImpl<SignalState> {
- private static final Intent WIFI_SETTINGS = new Intent(Settings.ACTION_WIFI_SETTINGS);
+ private static final Intent WIFI_SETTINGS = new Intent(Settings.Panel.ACTION_WIFI);
protected final NetworkController mController;
private final AccessPointController mWifiController;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
index 3874903..b0e6f6e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
@@ -293,6 +293,10 @@
.setImageDrawable(navigationBarView.getBackDrawable());
((ImageView) mLayout.findViewById(R.id.screen_pinning_home_icon))
.setImageDrawable(navigationBarView.getHomeDrawable());
+ if (recentsVisible) {
+ ((ImageView) mLayout.findViewById(R.id.screen_pinning_recents_icon))
+ .setImageDrawable(navigationBarView.getRecentsDrawable());
+ }
}
// Create a bulleted list of the default description plus the two security notes.
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java
index 1a9abb9..5e08a3e 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java
@@ -38,6 +38,7 @@
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.net.Uri;
+import android.os.Environment;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -132,7 +133,7 @@
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mMediaRecorder.setVideoEncodingProfileLevel(
MediaCodecInfo.CodecProfileLevel.AVCProfileHigh,
- MediaCodecInfo.CodecProfileLevel.AVCLevel42);
+ MediaCodecInfo.CodecProfileLevel.AVCLevel3);
mMediaRecorder.setVideoSize(screenWidth, screenHeight);
mMediaRecorder.setVideoFrameRate(refereshRate);
mMediaRecorder.setVideoEncodingBitRate(vidBitRate);
@@ -223,6 +224,7 @@
values.put(MediaStore.Video.Media.MIME_TYPE, "video/mp4");
values.put(MediaStore.Video.Media.DATE_ADDED, System.currentTimeMillis());
values.put(MediaStore.Video.Media.DATE_TAKEN, System.currentTimeMillis());
+ values.put(MediaStore.Video.Media.RELATIVE_PATH, Environment.DIRECTORY_MOVIES + File.separator + "ScreenRecords");
ContentResolver resolver = mContext.getContentResolver();
Uri collectionUri = MediaStore.Video.Media.getContentUri(
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java
index dc47ab4..5071c47 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordDialog.java
@@ -73,7 +73,7 @@
window.getDecorView();
window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
window.addPrivateFlags(WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS);
- window.setGravity(Gravity.TOP);
+ window.setGravity(Gravity.BOTTOM);
setTitle(R.string.screenrecord_name);
setContentView(R.layout.screen_record_dialog);
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index c3c947b..fbedeb7 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -28,10 +28,13 @@
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.app.ActivityManager;
+import android.app.ActivityTaskManager;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
@@ -53,10 +56,12 @@
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
+import android.os.UserHandle;
import android.provider.Settings;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.MathUtils;
+import android.view.Choreographer;
import android.view.Display;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -81,10 +86,14 @@
import com.android.internal.logging.UiEventLogger;
import com.android.systemui.R;
import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.dagger.qualifiers.UiBackground;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.QuickStepContract;
+import com.android.systemui.shared.system.TaskStackChangeListener;
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.Executor;
import java.util.function.Consumer;
import javax.inject.Inject;
@@ -104,6 +113,7 @@
public Consumer<Uri> finisher;
public GlobalScreenshot.ActionsReadyListener mActionsReadyListener;
public int errorMsgResId;
+ public String appLabel;
void clearImage() {
image = null;
@@ -162,14 +172,14 @@
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 = 200;
+ private static final long SCREENSHOT_ACTIONS_ALPHA_DURATION_MS = 10;
private static final long SCREENSHOT_DISMISS_Y_DURATION_MS = 350;
private static final long SCREENSHOT_DISMISS_ALPHA_DURATION_MS = 183;
private static final long SCREENSHOT_DISMISS_ALPHA_OFFSET_MS = 50; // delay before starting fade
private static final float SCREENSHOT_ACTIONS_START_SCALE_X = .7f;
private static final float ROUNDED_CORNER_RADIUS = .05f;
- private static final int SCREENSHOT_CORNER_DEFAULT_TIMEOUT_MILLIS = 6000;
+ private static final int SCREENSHOT_CORNER_DEFAULT_TIMEOUT_MILLIS = 2000;
private static final int MESSAGE_CORNER_TIMEOUT = 2;
private final Interpolator mAccelerateInterpolator = new AccelerateInterpolator();
@@ -231,12 +241,40 @@
}
};
+ private ComponentName mTaskComponentName;
+ private PackageManager mPm;
+
+ private final Executor mUiBgExecutor;
+ private final TaskStackChangeListener mTaskListener = new TaskStackChangeListener() {
+ @Override
+ public void onTaskStackChanged() {
+ mUiBgExecutor.execute(() -> {
+ try {
+ final ActivityManager.StackInfo focusedStack =
+ ActivityTaskManager.getService().getFocusedStackInfo();
+ if (focusedStack != null && focusedStack.topActivity != null) {
+ mTaskComponentName = focusedStack.topActivity;
+ }
+ } catch (Exception e) {}
+ });
+ }
+ };
+
+ private String getForegroundAppLabel() {
+ try {
+ final ActivityInfo ai = mPm.getActivityInfo(mTaskComponentName, 0);
+ return ai.applicationInfo.loadLabel(mPm).toString();
+ } catch (PackageManager.NameNotFoundException e) {
+ return null;
+ }
+ }
+
@Inject
public GlobalScreenshot(
Context context, @Main Resources resources,
ScreenshotSmartActions screenshotSmartActions,
ScreenshotNotificationsController screenshotNotificationsController,
- UiEventLogger uiEventLogger) {
+ UiEventLogger uiEventLogger, @UiBackground Executor uiBgExecutor) {
mContext = context;
mScreenshotSmartActions = screenshotSmartActions;
mNotificationsController = screenshotNotificationsController;
@@ -276,6 +314,18 @@
// Setup the Camera shutter sound
mCameraSound = new MediaActionSound();
mCameraSound.load(MediaActionSound.SHUTTER_CLICK);
+
+ // Store UI background executor
+ mUiBgExecutor = uiBgExecutor;
+
+ // Grab PackageManager
+ mPm = mContext.getPackageManager();
+
+ // Register task stack listener
+ ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskListener);
+
+ // Initialize current foreground package name
+ mTaskListener.onTaskStackChanged();
}
@Override // ViewTreeObserver.OnComputeInternalInsetsListener
@@ -376,8 +426,11 @@
void stopScreenshot() {
// If the selector layer still presents on screen, we remove it and resets its state.
if (mScreenshotSelectorView.getSelectionRect() != null) {
- mWindowManager.removeView(mScreenshotLayout);
- mScreenshotSelectorView.stopSelection();
+ try {
+ mWindowManager.removeView(mScreenshotLayout);
+ mScreenshotSelectorView.stopSelection();
+ } catch (IllegalArgumentException ignored) {
+ }
}
}
@@ -554,13 +607,31 @@
* Takes a screenshot of the current display and shows an animation.
*/
private void takeScreenshotInternal(Consumer<Uri> finisher, Rect crop) {
- // copy the input Rect, since SurfaceControl.screenshot can mutate it
- Rect screenRect = new Rect(crop);
- int rot = mDisplay.getRotation();
- int width = crop.width();
- int height = crop.height();
- saveScreenshot(SurfaceControl.screenshot(crop, width, height, rot), finisher, screenRect,
- Insets.NONE, true);
+ if (mScreenshotLayout.getParent() != null) {
+ finisher.accept(null);
+ return;
+ }
+ // Dismiss the old screenshot first to prevent it from showing up in the new screenshot
+ dismissScreenshot("new screenshot requested", true);
+
+ // Force a new frame to be rendered now that the old screenshot has been cleared
+ mScreenshotLayout.getRootView().invalidate();
+ Choreographer.getInstance().postFrameCallback(time1 -> {
+ // Unfortunately, we need to introduce another frame of latency because this
+ // is a pre-draw callback
+ mScreenshotLayout.getRootView().invalidate();
+
+ // Finally, take the screenshot once we're sure that old screenshot view is gone
+ Choreographer.getInstance().postFrameCallback(time2 -> {
+ // copy the input Rect, since SurfaceControl.screenshot can mutate it
+ Rect screenRect = new Rect(crop);
+ int rot = mDisplay.getRotation();
+ int width = crop.width();
+ int height = crop.height();
+ saveScreenshot(SurfaceControl.screenshot(crop, width, height, rot), finisher, screenRect,
+ Insets.NONE, true);
+ });
+ });
}
private void saveScreenshot(Bitmap screenshot, Consumer<Uri> finisher, Rect screenRect,
@@ -614,7 +685,11 @@
private void saveScreenshotAndToast(Consumer<Uri> finisher) {
// Play the shutter sound to notify that we've taken a screenshot
mScreenshotHandler.post(() -> {
- mCameraSound.play(MediaActionSound.SHUTTER_CLICK);
+ if (Settings.System.getIntForUser(mContext.getContentResolver(),
+ Settings.System.SCREENSHOT_SHUTTER_SOUND, 1, UserHandle.USER_CURRENT) == 1) {
+ // Play the shutter sound to notify that we've taken a screenshot
+ mCameraSound.play(MediaActionSound.SHUTTER_CLICK);
+ }
});
saveScreenshotInWorkerThread(finisher, new ActionsReadyListener() {
@@ -669,8 +744,11 @@
}
});
- // Play the shutter sound to notify that we've taken a screenshot
- mCameraSound.play(MediaActionSound.SHUTTER_CLICK);
+ if (Settings.System.getIntForUser(mContext.getContentResolver(),
+ Settings.System.SCREENSHOT_SHUTTER_SOUND, 1, UserHandle.USER_CURRENT) == 1) {
+ // Play the shutter sound to notify that we've taken a screenshot
+ mCameraSound.play(MediaActionSound.SHUTTER_CLICK);
+ }
mScreenshotPreview.setLayerType(View.LAYER_TYPE_HARDWARE, null);
mScreenshotPreview.buildLayer();
@@ -688,6 +766,7 @@
data.image = mScreenBitmap;
data.finisher = finisher;
data.mActionsReadyListener = actionsReadyListener;
+ data.appLabel = getForegroundAppLabel();
if (mSaveInBgTask != null) {
// just log success/failure for the pre-existing screenshot
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
index df1d789..4d76839 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
@@ -17,6 +17,7 @@
package com.android.systemui.screenshot;
import android.app.ActivityTaskManager;
+import android.app.KeyguardManager;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.ClipData;
@@ -77,6 +78,7 @@
private static final String TAG = "SaveImageInBackgroundTask";
private static final String SCREENSHOT_FILE_NAME_TEMPLATE = "Screenshot_%s.png";
+ private static final String SCREENSHOT_FILE_NAME_TEMPLATE_APPNAME = "Screenshot_%s_%s.png";
private static final String SCREENSHOT_ID_TEMPLATE = "Screenshot_%s";
private static final String SCREENSHOT_SHARE_SUBJECT_TEMPLATE = "Screenshot (%s)";
@@ -101,7 +103,16 @@
mParams = data;
mImageTime = System.currentTimeMillis();
String imageDate = new SimpleDateFormat("yyyyMMdd-HHmmss").format(new Date(mImageTime));
- mImageFileName = String.format(SCREENSHOT_FILE_NAME_TEMPLATE, imageDate);
+ boolean onKeyguard = context.getSystemService(KeyguardManager.class).isKeyguardLocked();
+ if (!onKeyguard && data.appLabel != null) {
+ // Replace all spaces and special chars with an underscore
+ String appNameString = data.appLabel.toString().replaceAll("[\\\\/:*?\"<>|\\s]+", "_");
+ mImageFileName = String.format(SCREENSHOT_FILE_NAME_TEMPLATE_APPNAME,
+ imageDate, appNameString);
+ } else {
+ mImageFileName = String.format(SCREENSHOT_FILE_NAME_TEMPLATE, imageDate);
+ }
+
mScreenshotId = String.format(SCREENSHOT_ID_TEMPLATE, UUID.randomUUID());
// Initialize screenshot notification smart actions provider.
diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
index 71e7883..1180951 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
@@ -40,6 +40,9 @@
import android.service.vr.IVrStateCallbacks;
import android.util.Log;
import android.util.MathUtils;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.ImageView;
import com.android.internal.BrightnessSynchronizer;
import com.android.internal.logging.MetricsLogger;
@@ -52,8 +55,10 @@
public class BrightnessController implements ToggleSlider.Listener {
private static final String TAG = "StatusBar.BrightnessController";
+
private static final int SLIDER_ANIMATION_DURATION = 3000;
+ private static final int MSG_UPDATE_ICON = 0;
private static final int MSG_UPDATE_SLIDER = 1;
private static final int MSG_SET_CHECKED = 2;
private static final int MSG_ATTACH_LISTENER = 3;
@@ -77,6 +82,7 @@
private final float mDefaultBacklightForVr;
private final Context mContext;
+ private final ImageView mIcon;
private final ToggleSlider mControl;
private final boolean mAutomaticAvailable;
private final DisplayManager mDisplayManager;
@@ -226,6 +232,7 @@
} else {
mHandler.obtainMessage(MSG_SET_CHECKED, 0).sendToTarget();
}
+ mHandler.sendEmptyMessage(MSG_UPDATE_ICON);
}
};
@@ -268,6 +275,9 @@
mExternalChange = true;
try {
switch (msg.what) {
+ case MSG_UPDATE_ICON:
+ updateIcon();
+ break;
case MSG_UPDATE_SLIDER:
updateSlider(Float.intBitsToFloat(msg.arg1), msg.arg2 != 0);
break;
@@ -292,11 +302,12 @@
}
};
- public BrightnessController(Context context, ToggleSlider control,
+ public BrightnessController(Context context, ToggleSlider control, ImageView icon,
BroadcastDispatcher broadcastDispatcher) {
mContext = context;
mControl = control;
mControl.setMax(GAMMA_SPACE_MAX);
+ mIcon = icon;
mBackgroundHandler = new Handler((Looper) Dependency.get(Dependency.BG_LOOPER));
mUserTracker = new CurrentUserTracker(broadcastDispatcher) {
@Override
@@ -327,6 +338,19 @@
mDisplayManager = context.getSystemService(DisplayManager.class);
mVrManager = IVrManager.Stub.asInterface(ServiceManager.getService(
Context.VR_SERVICE));
+
+ if (mAutomaticAvailable) {
+ mIcon.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Settings.System.putIntForUser(mContext.getContentResolver(),
+ Settings.System.SCREEN_BRIGHTNESS_MODE, mAutomatic ?
+ Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL :
+ Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC,
+ UserHandle.USER_CURRENT);
+ }
+ });
+ }
}
public void addStateChangedCallback(BrightnessStateChangeCallback cb) {
@@ -355,6 +379,7 @@
@Override
public void onChanged(ToggleSlider toggleSlider, boolean tracking, boolean automatic,
int value, boolean stopTracking) {
+ updateIcon();
if (mExternalChange) return;
if (mSliderAnimator != null) {
@@ -425,6 +450,15 @@
mDisplayManager.setTemporaryBrightness(brightness);
}
+
+ private void updateIcon() {
+ if (mIcon != null) {
+ mIcon.setImageResource(mAutomatic ?
+ com.android.systemui.R.drawable.ic_qs_brightness_auto_on :
+ com.android.systemui.R.drawable.ic_qs_brightness_auto_off);
+ }
+ }
+
private void updateVrMode(boolean isEnabled) {
if (mIsVrModeEnabled != isEnabled) {
mIsVrModeEnabled = isEnabled;
diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
index 70c2531..3b943bf 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
@@ -24,6 +24,7 @@
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
+import android.widget.ImageView;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -59,7 +60,8 @@
setContentView(v);
final ToggleSliderView slider = findViewById(R.id.brightness_slider);
- mBrightnessController = new BrightnessController(this, slider, mBroadcastDispatcher);
+ final ImageView icon = findViewById(R.id.brightness_icon);
+ mBrightnessController = new BrightnessController(this, slider, icon, mBroadcastDispatcher);
}
@Override
@@ -86,4 +88,13 @@
return super.onKeyDown(keyCode, event);
}
+
+ @Override
+ public void onWindowFocusChanged(boolean hasFocus) {
+ super.onWindowFocusChanged(hasFocus);
+ // If the BrightnessDialog loses focus, dismiss it.
+ if (!hasFocus) {
+ finish();
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AlertingNotificationManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/AlertingNotificationManager.java
index eca4c80..99f7784 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/AlertingNotificationManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/AlertingNotificationManager.java
@@ -20,6 +20,8 @@
import android.annotation.Nullable;
import android.os.Handler;
import android.os.Looper;
+import android.os.UserHandle;
+import android.provider.Settings;
import android.os.SystemClock;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -272,7 +274,7 @@
@Nullable public NotificationEntry mEntry;
public long mPostTime;
public long mEarliestRemovaltime;
-
+
@Nullable protected Runnable mRemoveAlertRunnable;
public void setEntry(@NonNull final NotificationEntry entry) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 96d6ecb..d08fea5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -126,6 +126,11 @@
private static final int MSG_HIDE_TOAST = 54 << MSG_SHIFT;
private static final int MSG_TRACING_STATE_CHANGED = 55 << MSG_SHIFT;
private static final int MSG_SUPPRESS_AMBIENT_DISPLAY = 56 << MSG_SHIFT;
+ private static final int MSG_TOGGLE_CAMERA_FLASH = 90 << MSG_SHIFT;
+ private static final int MSG_TOGGLE_SETTINGS_PANEL = 91 << MSG_SHIFT;
+ private static final int MSG_SHOW_IN_DISPLAY_FINGERPRINT_VIEW = 57 << MSG_SHIFT;
+ private static final int MSG_HIDE_IN_DISPLAY_FINGERPRINT_VIEW = 58 << MSG_SHIFT;
+ private static final int MSG_TRIGGER_ACTION = 93 << MSG_SHIFT;
public static final int FLAG_EXCLUDE_NONE = 0;
public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0;
@@ -169,6 +174,7 @@
default void animateExpandNotificationsPanel() { }
default void animateCollapsePanels(int flags, boolean force) { }
default void togglePanel() { }
+ default void toggleSettingsPanel() { }
default void animateExpandSettingsPanel(String obj) { }
/**
@@ -268,6 +274,8 @@
default void onBiometricHelp(String message) { }
default void onBiometricError(int modality, int error, int vendorCode) { }
default void hideAuthenticationDialog() { }
+ default void showInDisplayFingerprintView() { }
+ default void hideInDisplayFingerprintView() { }
/**
* @see IStatusBar#onDisplayReady(int)
@@ -338,6 +346,10 @@
* @param enabled
*/
default void onTracingStateChanged(boolean enabled) { }
+
+ default void toggleCameraFlash(boolean proximityCheck) { }
+
+ default void triggerElmyraAction(String action) { }
}
public CommandQueue(Context context) {
@@ -499,6 +511,13 @@
}
}
+ public void toggleSettingsPanel() {
+ synchronized (mLock) {
+ mHandler.removeMessages(MSG_TOGGLE_SETTINGS_PANEL);
+ mHandler.obtainMessage(MSG_TOGGLE_SETTINGS_PANEL, 0, 0).sendToTarget();
+ }
+ }
+
public void animateExpandSettingsPanel(String subPanel) {
synchronized (mLock) {
mHandler.removeMessages(MSG_EXPAND_SETTINGS);
@@ -857,6 +876,20 @@
}
@Override
+ public void showInDisplayFingerprintView() {
+ synchronized (mLock) {
+ mHandler.obtainMessage(MSG_SHOW_IN_DISPLAY_FINGERPRINT_VIEW).sendToTarget();
+ }
+ }
+
+ @Override
+ public void hideInDisplayFingerprintView() {
+ synchronized (mLock) {
+ mHandler.obtainMessage(MSG_HIDE_IN_DISPLAY_FINGERPRINT_VIEW).sendToTarget();
+ }
+ }
+
+ @Override
public void onDisplayReady(int displayId) {
synchronized (mLock) {
mHandler.obtainMessage(MSG_DISPLAY_READY, displayId, 0).sendToTarget();
@@ -966,6 +999,22 @@
}
}
+ @Override
+ public void toggleCameraFlash(boolean proximityCheck) {
+ synchronized (mLock) {
+ mHandler.removeMessages(MSG_TOGGLE_CAMERA_FLASH);
+ mHandler.obtainMessage(MSG_TOGGLE_CAMERA_FLASH, proximityCheck).sendToTarget();
+ }
+ }
+
+ @Override
+ public void triggerElmyraAction(String action) {
+ synchronized (mLock) {
+ mHandler.removeMessages(MSG_TRIGGER_ACTION);
+ mHandler.obtainMessage(MSG_TRIGGER_ACTION, action).sendToTarget();
+ }
+ }
+
private final class H extends Handler {
private H(Looper l) {
super(l);
@@ -1013,6 +1062,11 @@
mCallbacks.get(i).togglePanel();
}
break;
+ case MSG_TOGGLE_SETTINGS_PANEL:
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ mCallbacks.get(i).toggleSettingsPanel();
+ }
+ break;
case MSG_EXPAND_SETTINGS:
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).animateExpandSettingsPanel((String) msg.obj);
@@ -1306,6 +1360,26 @@
callbacks.suppressAmbientDisplay((boolean) msg.obj);
}
break;
+ case MSG_TOGGLE_CAMERA_FLASH:
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ mCallbacks.get(i).toggleCameraFlash((boolean) msg.obj);
+ }
+ break;
+ case MSG_SHOW_IN_DISPLAY_FINGERPRINT_VIEW:
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ mCallbacks.get(i).showInDisplayFingerprintView();
+ }
+ break;
+ case MSG_HIDE_IN_DISPLAY_FINGERPRINT_VIEW:
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ mCallbacks.get(i).hideInDisplayFingerprintView();
+ }
+ break;
+ case MSG_TRIGGER_ACTION:
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ mCallbacks.get(i).triggerElmyraAction((String) msg.obj);
+ }
+ break;
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java
index 4fa7822..681844f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java
@@ -31,6 +31,9 @@
import com.android.systemui.R;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.statusbar.notification.row.ExpandableView;
+import android.util.Log;
+
+import com.android.internal.util.bliss.BlissUtils;
/**
* A utility class to enable the downward swipe on the lockscreen to go to the full shade and expand
@@ -58,7 +61,13 @@
private float mLastHeight;
private FalsingManager mFalsingManager;
- public DragDownHelper(Context context, View host, ExpandHelper.Callback callback,
+ private boolean mDoubleTapToSleepEnabled;
+ private int mStatusBarHeaderHeight;
+ private long mLastDownEvent = -1;
+ private long mDoubleTapTimeout;
+ private Runnable mGoToSleep;
+
+ public DragDownHelper(final Context context, View host, ExpandHelper.Callback callback,
DragDownCallback dragDownCallback,
FalsingManager falsingManager) {
mMinDragDistance = context.getResources().getDimensionPixelSize(
@@ -70,6 +79,14 @@
mDragDownCallback = dragDownCallback;
mHost = host;
mFalsingManager = falsingManager;
+ mStatusBarHeaderHeight = context
+ .getResources().getDimensionPixelSize(R.dimen.status_bar_header_height_keyguard);
+ mGoToSleep = new Runnable() {
+ @Override
+ public void run() {
+ BlissUtils.switchScreenOff(context);
+ }
+ };
}
@Override
@@ -84,6 +101,19 @@
mStartingChild = null;
mInitialTouchY = y;
mInitialTouchX = x;
+ if (mDoubleTapToSleepEnabled && y < mStatusBarHeaderHeight) {
+ long eventTime = event.getEventTime();
+ if (mLastDownEvent != -1) {
+ long diff = eventTime - mLastDownEvent;
+
+ if (diff < mDoubleTapTimeout) {
+ mGoToSleep.run();
+ }
+ mLastDownEvent = -1;
+ } else {
+ mLastDownEvent = eventTime;
+ }
+ }
break;
case MotionEvent.ACTION_MOVE:
@@ -281,4 +311,7 @@
*/
boolean isDragDownAnywhereEnabled();
}
+ public void updateDoubleTapToSleep(boolean updateDoubleTapToSleep) {
+ mDoubleTapToSleepEnabled = updateDoubleTapToSleep;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java
index b33424c..2f28e14 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java
@@ -81,7 +81,9 @@
Resources res = getResources();
mAbsoluteStartPadding = res.getDimensionPixelSize(R.dimen.notification_side_paddings)
+ res.getDimensionPixelSize(
- com.android.internal.R.dimen.notification_content_margin_start);
+ com.android.internal.R.dimen.notification_content_margin_start)
+ + res.getDimensionPixelSize(
+ R.dimen.rounded_corner_content_padding);
mEndMargin = res.getDimensionPixelSize(
com.android.internal.R.dimen.notification_content_margin_end);
setPaddingRelative(mAbsoluteStartPadding, 0, mEndMargin, 0);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 39d2f71..76b70ed 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -37,6 +37,7 @@
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
+import android.provider.Settings;
import android.text.TextUtils;
import android.text.format.Formatter;
import android.util.Log;
@@ -121,11 +122,14 @@
private boolean mBatteryOverheated;
private boolean mEnableBatteryDefender;
private int mChargingSpeed;
- private int mChargingWattage;
+ private double mChargingWattage;
private int mBatteryLevel;
private long mChargingTimeRemaining;
private float mDisclosureMaxAlpha;
private String mMessageToShowOnScreenOn;
+ private int mChargingCurrent;
+ private double mChargingVoltage;
+ private float mTemperature;
private KeyguardUpdateMonitorCallback mUpdateMonitorCallback;
@@ -291,9 +295,11 @@
hideTransientIndication();
}
updateIndication(false);
+ mLockIconController.getView().setAlpha(255);
} else if (!visible) {
// If we unlock and return to keyguard quickly, previous error should not be shown
hideTransientIndication();
+ mLockIconController.getView().setAlpha(0);
}
}
@@ -431,14 +437,7 @@
if (!mKeyguardUpdateMonitor.isUserUnlocked(userId)) {
mTextView.switchIndication(com.android.internal.R.string.lockscreen_storage_locked);
} else if (!TextUtils.isEmpty(mTransientIndication)) {
- if (powerIndication != null && !mTransientIndication.equals(powerIndication)) {
- String indication = mContext.getResources().getString(
- R.string.keyguard_indication_trust_unlocked_plugged_in,
- mTransientIndication, powerIndication);
- mTextView.switchIndication(indication);
- } else {
- mTextView.switchIndication(mTransientIndication);
- }
+ mTextView.switchIndication(mTransientIndication);
isError = mTransientTextIsError;
} else if (!TextUtils.isEmpty(trustGrantedIndication)
&& mKeyguardUpdateMonitor.getUserHasTrust(userId)) {
@@ -546,6 +545,21 @@
? R.string.keyguard_indication_charging_time_fast
: R.string.keyguard_plugged_in_charging_fast;
break;
+ case BatteryStatus.CHARGING_DASH:
+ chargingId = hasChargingTime
+ ? R.string.keyguard_indication_dash_charging_time
+ : R.string.keyguard_plugged_in_dash_charging;
+ break;
+ case BatteryStatus.CHARGING_WARP:
+ chargingId = hasChargingTime
+ ? R.string.keyguard_indication_warp_charging_time
+ : R.string.keyguard_plugged_in_warp_charging;
+ break;
+ case BatteryStatus.CHARGING_VOOC:
+ chargingId = hasChargingTime
+ ? R.string.keyguard_indication_vooc_charging_time
+ : R.string.keyguard_plugged_in_vooc_charging;
+ break;
case BatteryStatus.CHARGING_SLOWLY:
chargingId = hasChargingTime
? R.string.keyguard_indication_charging_time_slowly
@@ -563,6 +577,35 @@
: R.string.keyguard_plugged_in_wireless;
}
+ String batteryInfo = "";
+ int current = 0;
+ double voltage = 0;
+ boolean showbatteryInfo = Settings.System.getIntForUser(mContext.getContentResolver(),
+ Settings.System.LOCKSCREEN_BATTERY_INFO, 1, UserHandle.USER_CURRENT) == 1;
+ if (showbatteryInfo) {
+ if (mChargingCurrent > 0) {
+ current = (mChargingCurrent < 5 ? (mChargingCurrent * 1000)
+ : (mChargingCurrent < 4000 ? mChargingCurrent : (mChargingCurrent / 1000)));
+ batteryInfo = batteryInfo + current + "mA";
+ }
+ if (mChargingVoltage > 0 && mChargingCurrent > 0) {
+ voltage = mChargingVoltage / 1000 / 1000;
+ batteryInfo = (batteryInfo == "" ? "" : batteryInfo + " · ") +
+ String.format("%.1f" , ((double) current / 1000) * voltage) + "W";
+ }
+ if (mChargingVoltage > 0) {
+ batteryInfo = (batteryInfo == "" ? "" : batteryInfo + " · ") +
+ String.format("%.1f" , voltage) + "V";
+ }
+ if (mTemperature > 0) {
+ batteryInfo = (batteryInfo == "" ? "" : batteryInfo + " · ") +
+ mTemperature / 10 + "°C";
+ }
+ if (batteryInfo != "") {
+ batteryInfo = "\n" + batteryInfo;
+ }
+ }
+
if (hasChargingTime) {
// We now have battery percentage in these strings and it's expected that all
// locales will also have it in the future. For now, we still have to support the old
@@ -570,17 +613,21 @@
String chargingTimeFormatted = Formatter.formatShortElapsedTimeRoundingUpToMinutes(
mContext, mChargingTimeRemaining);
try {
- return mContext.getResources().getString(chargingId, chargingTimeFormatted,
+ String chargingText = mContext.getResources().getString(chargingId, chargingTimeFormatted,
percentage);
+ return chargingText + batteryInfo;
} catch (IllegalFormatConversionException e) {
- return mContext.getResources().getString(chargingId, chargingTimeFormatted);
+ String chargingText = mContext.getResources().getString(chargingId, chargingTimeFormatted);
+ return chargingText + batteryInfo;
}
} else {
// Same as above
try {
- return mContext.getResources().getString(chargingId, percentage);
+ String chargingText = mContext.getResources().getString(chargingId, percentage);
+ return chargingText + batteryInfo;
} catch (IllegalFormatConversionException e) {
- return mContext.getResources().getString(chargingId);
+ String chargingText = mContext.getResources().getString(chargingId);
+ return chargingText + batteryInfo;
}
}
}
@@ -689,8 +736,11 @@
mPowerPluggedInWired = status.isPluggedInWired() && isChargingOrFull;
mPowerPluggedIn = status.isPluggedIn() && isChargingOrFull;
mPowerCharged = status.isCharged();
+ mChargingCurrent = status.maxChargingCurrent;
+ mChargingVoltage = status.maxChargingVoltage;
mChargingWattage = status.maxChargingWattage;
mChargingSpeed = status.getChargingSpeed(mContext);
+ mTemperature = status.temperature;
mBatteryLevel = status.level;
mBatteryOverheated = status.isOverheated();
mEnableBatteryDefender = mBatteryOverheated && status.isPluggedIn();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/MediaArtworkProcessor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/MediaArtworkProcessor.kt
index 326757e..705aa15 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/MediaArtworkProcessor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/MediaArtworkProcessor.kt
@@ -35,7 +35,7 @@
private const val TAG = "MediaArtworkProcessor"
private const val COLOR_ALPHA = (255 * 0.7f).toInt()
-private const val BLUR_RADIUS = 25f
+//private const val BLUR_RADIUS = 25f
private const val DOWNSAMPLE = 6
@Singleton
@@ -43,8 +43,9 @@
private val mTmpSize = Point()
private var mArtworkCache: Bitmap? = null
+ private var mDownSample: Int = DOWNSAMPLE
- fun processArtwork(context: Context, artwork: Bitmap): Bitmap? {
+ fun processArtwork(context: Context, artwork: Bitmap, blur_radius: Float): Bitmap? {
if (mArtworkCache != null) {
return mArtworkCache
}
@@ -55,9 +56,10 @@
var inBitmap: Bitmap? = null
try {
@Suppress("DEPRECATION")
+ if (blur_radius < 5f) mDownSample = 2 else mDownSample = DOWNSAMPLE
context.display?.getSize(mTmpSize)
val rect = Rect(0, 0, artwork.width, artwork.height)
- MathUtils.fitRect(rect, Math.max(mTmpSize.x / DOWNSAMPLE, mTmpSize.y / DOWNSAMPLE))
+ MathUtils.fitRect(rect, Math.max(mTmpSize.x / mDownSample, mTmpSize.y / mDownSample))
inBitmap = Bitmap.createScaledBitmap(artwork, rect.width(), rect.height(),
true /* filter */)
// Render script blurs only support ARGB_8888, we need a conversion if we got a
@@ -67,20 +69,21 @@
inBitmap = oldIn.copy(Bitmap.Config.ARGB_8888, false /* isMutable */)
oldIn.recycle()
}
- val outBitmap = Bitmap.createBitmap(inBitmap.width, inBitmap.height,
- Bitmap.Config.ARGB_8888)
-
- input = Allocation.createFromBitmap(renderScript, inBitmap,
- Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_GRAPHICS_TEXTURE)
- output = Allocation.createFromBitmap(renderScript, outBitmap)
-
- blur.setRadius(BLUR_RADIUS)
- blur.setInput(input)
- blur.forEach(output)
- output.copyTo(outBitmap)
-
+ var outBitmap: Bitmap?
+ if (blur_radius >= 1f) {
+ outBitmap = Bitmap.createBitmap(inBitmap.width, inBitmap.height,
+ Bitmap.Config.ARGB_8888)
+ input = Allocation.createFromBitmap(renderScript, inBitmap,
+ Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_GRAPHICS_TEXTURE)
+ output = Allocation.createFromBitmap(renderScript, outBitmap)
+ blur.setRadius(blur_radius)
+ blur.setInput(input)
+ blur.forEach(output)
+ output.copyTo(outBitmap)
+ } else {
+ outBitmap = inBitmap.copy(Bitmap.Config.ARGB_8888, true/*mutable*/)
+ }
val swatch = MediaNotificationProcessor.findBackgroundSwatch(artwork)
-
val canvas = Canvas(outBitmap)
canvas.drawColor(ColorUtils.setAlphaComponent(swatch.rgb, COLOR_ALPHA))
return outBitmap
@@ -88,10 +91,12 @@
Log.e(TAG, "error while processing artwork", ex)
return null
} finally {
- input?.destroy()
- output?.destroy()
- blur.destroy()
+ if (blur_radius >= 1f) {
+ input?.destroy()
+ output?.destroy()
+ }
inBitmap?.recycle()
+ blur.destroy()
}
}
@@ -99,4 +104,4 @@
mArtworkCache?.recycle()
mArtworkCache = null
}
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
index 38e1de3..64accad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
@@ -41,6 +41,8 @@
import android.provider.DeviceConfig;
import android.provider.DeviceConfig.Properties;
import android.service.notification.NotificationListenerService;
+import android.text.TextUtils;
+import android.provider.Settings;
import android.util.ArraySet;
import android.util.Log;
import android.view.View;
@@ -72,6 +74,9 @@
import com.android.systemui.util.DeviceConfigProxy;
import com.android.systemui.util.Utils;
import com.android.systemui.util.concurrency.DelayableExecutor;
+import com.android.systemui.tuner.TunerService;
+import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.VisualizerView;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -88,10 +93,15 @@
* Handles tasks and state related to media notifications. For example, there is a 'current' media
* notification, which this class keeps track of.
*/
-public class NotificationMediaManager implements Dumpable {
+public class NotificationMediaManager implements Dumpable, TunerService.Tunable {
private static final String TAG = "NotificationMediaManager";
public static final boolean DEBUG_MEDIA = false;
+ private static final String LOCKSCREEN_MEDIA_METADATA =
+ Settings.Secure.LOCKSCREEN_MEDIA_METADATA;
+
+ //private static final String NOWPLAYING_SERVICE = "com.google.intelligence.sense";
+ private static final String NOWPLAYING_SERVICE = "com.google.android.as";
private final StatusBarStateController mStatusBarStateController
= Dependency.get(StatusBarStateController.class);
private final SysuiColorExtractor mColorExtractor = Dependency.get(SysuiColorExtractor.class);
@@ -128,17 +138,23 @@
private final Lazy<StatusBar> mStatusBarLazy;
private final MediaArtworkProcessor mMediaArtworkProcessor;
private final Set<AsyncTask<?, ?, ?>> mProcessArtworkTasks = new ArraySet<>();
+ private float mLockscreenMediaBlur;
protected NotificationPresenter mPresenter;
private MediaController mMediaController;
private String mMediaNotificationKey;
private MediaMetadata mMediaMetadata;
+ private String mNowPlayingNotificationKey;
+ private String mNowPlayingTrack;
+
private BackDropView mBackdrop;
private ImageView mBackdropFront;
private ImageView mBackdropBack;
private boolean mShowCompactMediaSeekbar;
+ private boolean mShowMediaMetadata;
+
private final DeviceConfig.OnPropertiesChangedListener mPropertiesChangedListener =
new DeviceConfig.OnPropertiesChangedListener() {
@Override
@@ -166,6 +182,11 @@
if (!isPlaybackActive(state.getState())) {
clearCurrentMediaNotification();
}
+ StatusBar statusBar = mStatusBarLazy.get();
+ if (statusBar != null) {
+ statusBar.getVisualizer().setPlaying(state.getState()
+ == PlaybackState.STATE_PLAYING);
+ }
findAndUpdateMediaNotifications();
}
}
@@ -277,6 +298,17 @@
deviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI,
mContext.getMainExecutor(),
mPropertiesChangedListener);
+
+ final TunerService tunerService = Dependency.get(TunerService.class);
+ tunerService.addTunable(this, LOCKSCREEN_MEDIA_METADATA);
+ }
+
+ @Override
+ public void onTuningChanged(String key, String newValue) {
+ if (LOCKSCREEN_MEDIA_METADATA.equals(key)) {
+ mShowMediaMetadata = TunerService.parseIntegerSwitch(newValue, false);
+ dispatchUpdateMediaMetaData(false /* changed */, true /* allowAnimation */);
+ }
}
private void removeEntry(NotificationEntry entry) {
@@ -302,6 +334,10 @@
clearCurrentMediaNotification();
dispatchUpdateMediaMetaData(true /* changed */, true /* allowEnterAnimation */);
}
+ if (key.equals(mNowPlayingNotificationKey)) {
+ mNowPlayingNotificationKey = null;
+ dispatchUpdateMediaMetaData(true /* changed */, true /* allowEnterAnimation */);
+ }
}
public String getMediaNotificationKey() {
@@ -350,6 +386,20 @@
// Promote the media notification with a controller in 'playing' state, if any.
NotificationEntry mediaNotification = null;
MediaController controller = null;
+
+ for (NotificationEntry entry : allNotifications) {
+ if (entry.getSbn().getPackageName().toLowerCase().equals(NOWPLAYING_SERVICE)) {
+ mNowPlayingNotificationKey = entry.getSbn().getKey();
+ String notificationText = null;
+ final String title = entry.getSbn().getNotification()
+ .extras.getString(Notification.EXTRA_TITLE);
+ if (!TextUtils.isEmpty(title)) {
+ mNowPlayingTrack = title;
+ }
+ break;
+ }
+ }
+
for (NotificationEntry entry : allNotifications) {
if (entry.isMediaNotification()) {
final MediaSession.Token token =
@@ -432,6 +482,13 @@
dispatchUpdateMediaMetaData(metaDataChanged, true /* allowEnterAnimation */);
}
+ public String getNowPlayingTrack() {
+ if (mNowPlayingNotificationKey == null) {
+ mNowPlayingTrack = null;
+ }
+ return mNowPlayingTrack;
+ }
+
public void clearCurrentMediaNotification() {
mMediaNotificationKey = null;
clearCurrentMediaNotificationSession();
@@ -555,7 +612,7 @@
}
mProcessArtworkTasks.clear();
}
- if (artworkBitmap != null && !Utils.useQsMediaPlayer(mContext)) {
+ if (artworkBitmap != null) {
mProcessArtworkTasks.add(new ProcessArtworkTask(this, metaDataChanged,
allowEnterAnimation).execute(artworkBitmap));
} else {
@@ -568,7 +625,7 @@
private void finishUpdateMediaMetaData(boolean metaDataChanged, boolean allowEnterAnimation,
@Nullable Bitmap bmp) {
Drawable artworkDrawable = null;
- if (bmp != null) {
+ if (bmp != null && (mShowMediaMetadata || !ENABLE_LOCKSCREEN_WALLPAPER)) {
artworkDrawable = new BitmapDrawable(mBackdropBack.getResources(), bmp);
}
boolean hasMediaArtwork = artworkDrawable != null;
@@ -595,6 +652,22 @@
mScrimController.setHasBackdrop(hasArtwork);
}
+ StatusBar statusBar = mStatusBarLazy.get();
+ if (statusBar != null &&
+ mStatusBarStateController.getState() != StatusBarState.SHADE) {
+ VisualizerView visualizerView = statusBar.getVisualizer();
+ if (!mKeyguardStateController.isKeyguardFadingAway()) {
+ // ensure visualizer is visible
+ visualizerView.setPlaying(getMediaControllerPlaybackState(mMediaController) ==
+ PlaybackState.STATE_PLAYING);
+ }
+
+ if (hasMediaArtwork && (artworkDrawable instanceof BitmapDrawable)) {
+ // always use current backdrop to color eq
+ visualizerView.setBitmap(((BitmapDrawable)artworkDrawable).getBitmap());
+ }
+ }
+
if ((hasArtwork || DEBUG_MEDIA_FAKE_ARTWORK)
&& (mStatusBarStateController.getState() != StatusBarState.SHADE || allowWhenShade)
&& mBiometricUnlockController != null && mBiometricUnlockController.getMode()
@@ -730,7 +803,13 @@
};
private Bitmap processArtwork(Bitmap artwork) {
- return mMediaArtworkProcessor.processArtwork(mContext, artwork);
+ return mMediaArtworkProcessor.processArtwork(mContext, artwork, mLockscreenMediaBlur);
+ }
+
+ public void setLockScreenMediaBlurLevel() {
+ mLockscreenMediaBlur = (float) Settings.System.getIntForUser(mContext.getContentResolver(),
+ Settings.System.LOCKSCREEN_MEDIA_BLUR, 25,
+ UserHandle.USER_CURRENT);
}
@MainThread
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationPresenter.java
index 1079f10..03b22ba 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationPresenter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationPresenter.java
@@ -71,4 +71,7 @@
* @return true if the shade is collapsing.
*/
boolean isCollapsing();
+
+ void setHeadsUpStoplist();
+ void setHeadsUpBlacklist();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
index 0445c98..294813c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
@@ -69,7 +69,7 @@
private const val VELOCITY_SCALE = 100f
private const val MAX_VELOCITY = 3000f
private const val MIN_VELOCITY = -MAX_VELOCITY
- private const val INTERACTION_BLUR_FRACTION = 0.4f
+ private const val INTERACTION_BLUR_FRACTION = 0.9f
private const val ANIMATION_BLUR_FRACTION = 1f - INTERACTION_BLUR_FRACTION
private const val TAG = "DepthController"
}
@@ -174,12 +174,7 @@
}
}
- // Home controls have black background, this means that we should not have blur when they
- // are fully visible, otherwise we'll enter Client Composition unnecessarily.
var globalActionsRadius = globalActionsSpring.radius
- if (showingHomeControls) {
- globalActionsRadius = 0
- }
var blur = max(shadeRadius.toInt(), globalActionsRadius)
// Make blur be 0 if it is necessary to stop blur effect.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index d798692..27953ac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -170,6 +170,12 @@
}
}
+ public void onOverlayChanged() {
+ initDimens();
+ updateBackgroundColors();
+ }
+
+
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 8cf8a22..7c2c291 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -488,7 +488,7 @@
android.R.integer.status_bar_notification_info_maxnum);
if (mIcon.number > tooBig) {
str = getContext().getResources().getString(
- android.R.string.status_bar_notification_info_overflow);
+ R.string.status_bar_notification_info_overflow);
} else {
NumberFormat f = NumberFormat.getIntegerInstance();
str = f.format(mIcon.number);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/VisualizerView.java b/packages/SystemUI/src/com/android/systemui/statusbar/VisualizerView.java
new file mode 100644
index 0000000..862975e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/VisualizerView.java
@@ -0,0 +1,561 @@
+/*
+ * Copyright (C) 2015 The CyanogenMod Project
+ * 2018-2019 crDroid Android Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar;
+
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.media.audiofx.Visualizer;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+
+import com.android.internal.graphics.palette.Palette;
+import com.android.internal.util.bliss.ColorAnimator;
+
+public class VisualizerView extends View
+ implements Palette.PaletteAsyncListener, ColorAnimator.ColorAnimationListener {
+
+ private static final String TAG = VisualizerView.class.getSimpleName();
+ private static final boolean DEBUG = false;
+
+ private Paint mPaint;
+ private Visualizer mVisualizer;
+ private ObjectAnimator mVisualizerColorAnimator;
+
+ private SettingsObserver mSettingObserver;
+ private Context mContext;
+
+ private ValueAnimator[] mValueAnimators;
+ private float[] mFFTPoints;
+
+ private int mStatusBarState;
+ private boolean mVisualizerEnabled = false;
+ private boolean mVisible = false;
+ private boolean mPlaying = false;
+ private boolean mPowerSaveMode = false;
+ private boolean mDisplaying = false; // the state we're animating to
+ private boolean mDozing = false;
+ private boolean mOccluded = false;
+
+ private int mColor;
+ private Bitmap mCurrentBitmap;
+
+ private ColorAnimator mLavaLamp;
+ private boolean mAutoColorEnabled;
+ private boolean mLavaLampEnabled;
+ private int mLavaLampSpeed;
+ private boolean shouldAnimate;
+ private int mUnits = 32;
+ private float mDbFuzzFactor = 16f;
+ private int mWidth, mHeight;
+ private int mOpacity = 140;
+
+ private Visualizer.OnDataCaptureListener mVisualizerListener =
+ new Visualizer.OnDataCaptureListener() {
+ byte rfk, ifk;
+ int dbValue;
+ float magnitude;
+
+ @Override
+ public void onWaveFormDataCapture(Visualizer visualizer, byte[] bytes, int samplingRate) {
+ }
+
+ @Override
+ public void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate) {
+ for (int i = 0; i < mUnits; i++) {
+ mValueAnimators[i].cancel();
+ rfk = fft[i * 2 + 2];
+ ifk = fft[i * 2 + 3];
+ magnitude = rfk * rfk + ifk * ifk;
+ dbValue = magnitude > 0 ? (int) (10 * Math.log10(magnitude)) : 0;
+
+ mValueAnimators[i].setFloatValues(mFFTPoints[i * 4 + 1],
+ mFFTPoints[3] - (dbValue * mDbFuzzFactor));
+ mValueAnimators[i].start();
+ }
+ }
+ };
+
+ private final Runnable mLinkVisualizer = new Runnable() {
+ @Override
+ public void run() {
+ if (DEBUG) {
+ Log.w(TAG, "+++ mLinkVisualizer run()");
+ }
+
+ try {
+ if (mVisualizer == null) {
+ mVisualizer = new Visualizer(0);
+ shouldAnimate = true;
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "error initializing visualizer", e);
+ return;
+ }
+
+ mVisualizer.setEnabled(false);
+ mVisualizer.setCaptureSize(66);
+ mVisualizer.setDataCaptureListener(mVisualizerListener,Visualizer.getMaxCaptureRate(),
+ false, true);
+ mVisualizer.setEnabled(true);
+
+ if (DEBUG) {
+ Log.w(TAG, "--- mLinkVisualizer run()");
+ }
+ }
+ };
+
+ private final Runnable mAsyncUnlinkVisualizer = new Runnable() {
+ @Override
+ public void run() {
+ AsyncTask.execute(mUnlinkVisualizer);
+ }
+ };
+
+ private final Runnable mUnlinkVisualizer = new Runnable() {
+ @Override
+ public void run() {
+ if (DEBUG) {
+ Log.w(TAG, "+++ mUnlinkVisualizer run(), mVisualizer: " + mVisualizer);
+ }
+
+ if (mVisualizer != null) {
+ mVisualizer.setEnabled(false);
+ mVisualizer.release();
+ mVisualizer = null;
+ }
+ shouldAnimate = false;
+
+ if (!mAutoColorEnabled && !mLavaLampEnabled) {
+ if (mCurrentBitmap != null) {
+ setBitmap(null);
+ } else {
+ setColor(Color.TRANSPARENT);
+ }
+ }
+
+ if (DEBUG) {
+ Log.w(TAG, "--- mUninkVisualizer run()");
+ }
+ }
+ };
+
+ public VisualizerView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ mContext = context;
+
+ mColor = Color.TRANSPARENT;
+
+ mPaint = new Paint();
+ mPaint.setAntiAlias(true);
+
+ mFFTPoints = new float[mUnits * 4];
+
+ mLavaLamp = new ColorAnimator();
+ mLavaLamp.setColorAnimatorListener(this);
+
+ loadValueAnimators();
+ }
+
+ public VisualizerView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public VisualizerView(Context context) {
+ this(context, null, 0);
+ }
+
+ private void updateViewVisibility() {
+ final int curVis = getVisibility();
+ final int newVis = mVisible && mStatusBarState != StatusBarState.SHADE
+ && mVisualizerEnabled ? View.VISIBLE : View.GONE;
+ if (curVis != newVis) {
+ setVisibility(newVis);
+ checkStateChanged();
+ }
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ mSettingObserver = new SettingsObserver(new Handler());
+ mSettingObserver.observe();
+ mSettingObserver.update();
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ mLavaLamp.stop();
+ mSettingObserver.unobserve();
+ mSettingObserver = null;
+ mCurrentBitmap = null;
+ }
+
+ private void loadValueAnimators() {
+ if (mValueAnimators != null) {
+ for (int i = 0; i < mValueAnimators.length; i++) {
+ mValueAnimators[i].cancel();
+ }
+ }
+ mValueAnimators = new ValueAnimator[mUnits];
+ for (int i = 0; i < mUnits; i++) {
+ final int j = i * 4 + 1;
+ mValueAnimators[i] = new ValueAnimator();
+ mValueAnimators[i].setDuration(128);
+ mValueAnimators[i].addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ mFFTPoints[j] = (float) animation.getAnimatedValue();
+ postInvalidate();
+ }
+ });
+ }
+ }
+
+ private void setPortraitPoints() {
+ float units = Float.valueOf(mUnits);
+ float barUnit = mWidth / units;
+ float barWidth = barUnit * 8f / 9f;
+ barUnit = barWidth + (barUnit - barWidth) * units / (units - 1);
+ mPaint.setStrokeWidth(barWidth);
+
+ for (int i = 0; i < mUnits; i++) {
+ mFFTPoints[i * 4] = mFFTPoints[i * 4 + 2] = i * barUnit + (barWidth / 2);
+ mFFTPoints[i * 4 + 1] = mHeight;
+ mFFTPoints[i * 4 + 3] = mHeight;
+ }
+ }
+
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ if (w > 0) mWidth = w;
+ if (h > 0) mHeight = h;
+
+ super.onSizeChanged(mWidth, mHeight, oldw, oldh);
+
+ loadValueAnimators();
+ setPortraitPoints();
+ }
+
+ @Override
+ public boolean hasOverlappingRendering() {
+ return false;
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+
+ if (mVisualizer != null) {
+ canvas.drawLines(mFFTPoints, mPaint);
+ }
+ }
+
+ @Override
+ public void onColorChanged(ColorAnimator colorAnimator, int color) {
+ if (mLavaLampEnabled)
+ setColor(color);
+ }
+
+ @Override
+ public void onStartAnimation(ColorAnimator colorAnimator, int firstColor) {
+ }
+
+ @Override
+ public void onStopAnimation(ColorAnimator colorAnimator, int lastColor) {
+ }
+
+ private void setVisualizerEnabled() {
+ mVisualizerEnabled = Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.LOCKSCREEN_VISUALIZER_ENABLED, 0) == 1;
+ }
+
+ private void setLavaLampEnabled() {
+ mLavaLampEnabled = Settings.System.getIntForUser(mContext.getContentResolver(),
+ Settings.System.LOCKSCREEN_LAVALAMP_ENABLED , 0, UserHandle.USER_CURRENT) == 1;
+ }
+
+ private void setLavaLampSpeed() {
+ mLavaLampSpeed = Settings.System.getIntForUser(mContext.getContentResolver(),
+ Settings.System.LOCKSCREEN_LAVALAMP_SPEED, 10000, UserHandle.USER_CURRENT);
+ mLavaLamp.setAnimationTime(mLavaLampSpeed);
+ }
+
+ private void setAutoColorEnabled() {
+ mAutoColorEnabled = Settings.System.getIntForUser(mContext.getContentResolver(),
+ Settings.System.LOCKSCREEN_VISUALIZER_AUTOCOLOR, 1, UserHandle.USER_CURRENT) == 1;
+ if (mCurrentBitmap != null && mAutoColorEnabled && !mLavaLampEnabled) {
+ Palette.generateAsync(mCurrentBitmap, this);
+ } else if (mCurrentBitmap != null) {
+ setBitmap(null);
+ } else {
+ setColor(Color.TRANSPARENT);
+ }
+ }
+
+ private void setSolidUnitsCount() {
+ int oldUnits = mUnits;
+ mUnits = Settings.System.getIntForUser(mContext.getContentResolver(),
+ Settings.System.LOCKSCREEN_SOLID_UNITS_COUNT, 32, UserHandle.USER_CURRENT);
+ if (mUnits != oldUnits) {
+ mFFTPoints = new float[mUnits * 4];
+ onSizeChanged(0, 0, 0, 0);
+ }
+ }
+
+ private void setSolidFudgeFactor() {
+ mDbFuzzFactor = Settings.System.getIntForUser(mContext.getContentResolver(),
+ Settings.System.LOCKSCREEN_SOLID_FUDGE_FACTOR, 16, UserHandle.USER_CURRENT);
+ }
+
+ private void setSolidUnitsOpacity() {
+ mOpacity = Settings.System.getIntForUser(mContext.getContentResolver(),
+ Settings.System.LOCKSCREEN_SOLID_UNITS_OPACITY, 140, UserHandle.USER_CURRENT);
+ }
+
+ public void setVisible(boolean visible) {
+ if (DEBUG) {
+ Log.i(TAG, "setVisible() called with visible = [" + visible + "]");
+ }
+ mVisible = visible;
+ updateViewVisibility();
+ }
+
+ public void setDozing(boolean dozing) {
+ if (mDozing != dozing) {
+ if (DEBUG) {
+ Log.i(TAG, "setDozing() called with dozing = [" + dozing + "]");
+ }
+ mDozing = dozing;
+ checkStateChanged();
+ }
+ }
+
+ public void setPlaying(boolean playing) {
+ if (mPlaying != playing) {
+ if (DEBUG) {
+ Log.i(TAG, "setPlaying() called with playing = [" + playing + "]");
+ }
+ mPlaying = playing;
+ checkStateChanged();
+ }
+ }
+
+ public void setPowerSaveMode(boolean powerSaveMode) {
+ if (mPowerSaveMode != powerSaveMode) {
+ if (DEBUG) {
+ Log.i(TAG, "setPowerSaveMode() called with powerSaveMode = [" + powerSaveMode + "]");
+ }
+ mPowerSaveMode = powerSaveMode;
+ checkStateChanged();
+ }
+ }
+
+ public void setOccluded(boolean occluded) {
+ if (mOccluded != occluded) {
+ if (DEBUG) {
+ Log.i(TAG, "setOccluded() called with occluded = [" + occluded + "]");
+ }
+ mOccluded = occluded;
+ checkStateChanged();
+ }
+ }
+
+ public void setStatusBarState(int statusBarState) {
+ if (mStatusBarState != statusBarState) {
+ mStatusBarState = statusBarState;
+ updateViewVisibility();
+ }
+ }
+
+ public void setBitmap(Bitmap bitmap) {
+ if (mCurrentBitmap == bitmap)
+ return;
+
+ mCurrentBitmap = bitmap;
+
+ if (mCurrentBitmap == null) {
+ setColor(Color.TRANSPARENT);
+ } else if (mAutoColorEnabled && !mLavaLampEnabled) {
+ Palette.generateAsync(mCurrentBitmap, this);
+ }
+ }
+
+ @Override
+ public void onGenerated(Palette palette) {
+ int color = Color.TRANSPARENT;
+
+ color = palette.getVibrantColor(color);
+ if (color == Color.TRANSPARENT) {
+ color = palette.getLightVibrantColor(color);
+ if (color == Color.TRANSPARENT) {
+ color = palette.getDarkVibrantColor(color);
+ }
+ }
+
+ setColor(color);
+ }
+
+ private void setColor(int color) {
+ if (color == Color.TRANSPARENT) {
+ color = Color.WHITE;
+ }
+
+ color = Color.argb(mOpacity, Color.red(color), Color.green(color), Color.blue(color));
+
+ if (mColor != color) {
+ mColor = color;
+
+ if (mVisualizer != null && shouldAnimate) {
+ shouldAnimate = false;
+
+ if (mVisualizerColorAnimator != null) {
+ mVisualizerColorAnimator.cancel();
+ }
+
+ mVisualizerColorAnimator = ObjectAnimator.ofArgb(mPaint, "color",
+ mPaint.getColor(), mColor);
+ mVisualizerColorAnimator.setStartDelay(600);
+ mVisualizerColorAnimator.setDuration(1200);
+ mVisualizerColorAnimator.start();
+ }
+ mPaint.setColor(mColor);
+ }
+ }
+
+ private void checkStateChanged() {
+ boolean isVisible = getVisibility() == View.VISIBLE;
+ if (isVisible && mPlaying && !mDozing && !mPowerSaveMode
+ && mVisualizerEnabled && !mOccluded) {
+ if (!mDisplaying) {
+ mDisplaying = true;
+ AsyncTask.execute(mLinkVisualizer);
+ animate()
+ .alpha(1f)
+ .withEndAction(null)
+ .setDuration(800);
+ if (mLavaLampEnabled) mLavaLamp.start();
+ }
+ } else {
+ if (mDisplaying) {
+ mDisplaying = false;
+ mLavaLamp.stop();
+ if (isVisible) {
+ animate()
+ .alpha(0f)
+ .withEndAction(mAsyncUnlinkVisualizer)
+ .setDuration(600);
+ } else {
+ animate().
+ alpha(0f)
+ .withEndAction(mAsyncUnlinkVisualizer)
+ .setDuration(0);
+ }
+ }
+ }
+ }
+
+ private class SettingsObserver extends ContentObserver {
+
+ public SettingsObserver(Handler handler) {
+ super(handler);
+ }
+
+ protected void observe() {
+ ContentResolver resolver = mContext.getContentResolver();
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.LOCKSCREEN_VISUALIZER_ENABLED),
+ false, this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.LOCKSCREEN_LAVALAMP_ENABLED),
+ false, this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.LOCKSCREEN_LAVALAMP_SPEED),
+ false, this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.LOCKSCREEN_VISUALIZER_AUTOCOLOR),
+ false, this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.LOCKSCREEN_SOLID_UNITS_COUNT),
+ false, this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.LOCKSCREEN_SOLID_FUDGE_FACTOR),
+ false, this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.LOCKSCREEN_SOLID_UNITS_OPACITY),
+ false, this, UserHandle.USER_ALL);
+ update();
+ }
+
+ protected void unobserve() {
+ mContext.getContentResolver().unregisterContentObserver(this);
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ ContentResolver resolver = mContext.getContentResolver();
+ if (uri.equals(Settings.System.getUriFor(
+ Settings.System.LOCKSCREEN_VISUALIZER_ENABLED))) {
+ setVisualizerEnabled();
+ } else if (uri.equals(Settings.System.getUriFor(
+ Settings.System.LOCKSCREEN_LAVALAMP_ENABLED))) {
+ setLavaLampEnabled();
+ } else if (uri.equals(Settings.System.getUriFor(
+ Settings.System.LOCKSCREEN_LAVALAMP_SPEED))) {
+ setLavaLampSpeed();
+ } else if (uri.equals(Settings.System.getUriFor(
+ Settings.System.LOCKSCREEN_VISUALIZER_AUTOCOLOR))) {
+ setAutoColorEnabled();
+ } else if (uri.equals(Settings.System.getUriFor(
+ Settings.System.LOCKSCREEN_SOLID_UNITS_COUNT))) {
+ setSolidUnitsCount();
+ } else if (uri.equals(Settings.System.getUriFor(
+ Settings.System.LOCKSCREEN_SOLID_FUDGE_FACTOR))) {
+ setSolidFudgeFactor();
+ } else if (uri.equals(Settings.System.getUriFor(
+ Settings.System.LOCKSCREEN_SOLID_UNITS_OPACITY))) {
+ setSolidUnitsOpacity();
+ }
+ }
+
+ protected void update() {
+ setVisualizerEnabled();
+ setLavaLampEnabled();
+ setLavaLampSpeed();
+ setAutoColorEnabled();
+ setSolidUnitsCount();
+ setSolidFudgeFactor();
+ setSolidUnitsOpacity();
+ checkStateChanged();
+ updateViewVisibility();
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProvider.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProvider.java
index 3292a8f..da2d240 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProvider.java
@@ -56,4 +56,6 @@
* Add a component that can suppress visual interruptions.
*/
void addSuppressor(NotificationInterruptSuppressor suppressor);
+
+ void setUseLessBoringHeadsUp(boolean lessBoring);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java
index 71f6dac..6da5b65 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java
@@ -71,6 +71,8 @@
@VisibleForTesting
protected boolean mUseHeadsUp = false;
+ private boolean mLessBoringHeadsUp;
+
@Inject
public NotificationInterruptStateProviderImpl(
ContentResolver contentResolver,
@@ -346,6 +348,20 @@
return true;
}
+ @Override
+ public void setUseLessBoringHeadsUp(boolean lessBoring) {
+ mLessBoringHeadsUp = lessBoring;
+ }
+
+ public boolean shouldSkipHeadsUp(StatusBarNotification sbn) {
+ boolean isImportantHeadsUp = false;
+ String notificationPackageName = sbn.getPackageName().toLowerCase();
+ isImportantHeadsUp = notificationPackageName.contains("dialer") ||
+ notificationPackageName.contains("messaging") ||
+ notificationPackageName.contains("clock");
+ return !mStatusBarStateController.isDozing() && mLessBoringHeadsUp && !isImportantHeadsUp;
+ }
+
/**
* Common checks between alerts that occur while the device is awake (heads up & bubbles).
*
@@ -364,6 +380,12 @@
return false;
}
}
+ if (shouldSkipHeadsUp(sbn)) {
+ if (DEBUG_HEADS_UP) {
+ Log.d(TAG, "No alerting: less boring headsup enabled");
+ }
+ return false;
+ }
return true;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
index f1727ec..edde422 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
@@ -212,6 +212,9 @@
* be useful in a configuration change.
*/
protected void initBackground() {
+ mNormalColor = mContext.getColor(R.color.notification_material_background_color);
+ mTintedRippleColor = mContext.getColor(R.color.notification_ripple_tinted_color);
+ mNormalRippleColor = mContext.getColor(R.color.notification_ripple_untinted_color);
mBackgroundNormal.setCustomBackground(R.drawable.notification_material_bg);
mBackgroundDimmed.setCustomBackground(R.drawable.notification_material_bg_dim);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index 70dd80e7..66fa5f0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -1200,6 +1200,10 @@
reInflateViews();
}
+ public void onOverlayChanged() {
+ onDensityOrFontScaleChanged();
+ }
+
private void reInflateViews() {
// Let's update our childrencontainer. This is intentionally not guarded with
// mIsSummaryWithChildren since we might have had children but not anymore.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
index f0c93b1..6ff4815 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
@@ -26,20 +26,26 @@
import android.annotation.IntDef;
import android.annotation.Nullable;
+import android.app.ActivityManager;
import android.app.INotificationManager;
+import android.app.KeyguardManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
import android.content.Context;
+import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
import android.metrics.LogMaker;
import android.os.Handler;
import android.os.RemoteException;
+import android.os.UserHandle;
+import android.provider.Settings;
import android.service.notification.StatusBarNotification;
import android.text.TextUtils;
import android.transition.ChangeBounds;
@@ -59,6 +65,9 @@
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.Dependency;
+import com.android.settingslib.Utils;
+import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.SystemUIDialog;
import com.android.systemui.R;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -312,6 +321,43 @@
final View settingsButton = findViewById(R.id.info);
settingsButton.setOnClickListener(getSettingsOnClickListener());
settingsButton.setVisibility(settingsButton.hasOnClickListeners() ? VISIBLE : GONE);
+
+ // Force stop button
+ final View killButton = findViewById(R.id.force_stop);
+ boolean killButtonEnabled = Settings.System.getIntForUser(
+ mContext.getContentResolver(),
+ Settings.System.NOTIFICATION_GUTS_KILL_APP_BUTTON, 0,
+ UserHandle.USER_CURRENT) != 0;
+ if (killButtonEnabled && !isThisASystemPackage(mPackageName)) {
+ killButton.setVisibility(View.VISIBLE);
+ killButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ KeyguardManager keyguardManager = (KeyguardManager)
+ mContext.getSystemService(Context.KEYGUARD_SERVICE);
+ if (keyguardManager.inKeyguardRestrictedInputMode()) {
+ // Don't do anything
+ return;
+ }
+ final SystemUIDialog killDialog = new SystemUIDialog(mContext);
+ killDialog.setTitle(mContext.getText(R.string.force_stop_dlg_title));
+ killDialog.setMessage(mContext.getText(R.string.force_stop_dlg_text));
+ killDialog.setPositiveButton(
+ R.string.dlg_ok, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ // kill pkg
+ ActivityManager actMan =
+ (ActivityManager) mContext.getSystemService(
+ Context.ACTIVITY_SERVICE);
+ actMan.forceStopPackage(mPackageName);
+ }
+ });
+ killDialog.setNegativeButton(R.string.dlg_cancel, null);
+ killDialog.show();
+ }
+ });
+ } else {
+ killButton.setVisibility(View.GONE);
+ }
}
private OnClickListener getSettingsOnClickListener() {
@@ -388,6 +434,21 @@
}
}
+ private boolean isThisASystemPackage(String packageName) {
+ try {
+ final UserHandle userHandle = mSbn.getUser();
+ PackageManager pm = StatusBar.getPackageManagerForUser(mContext,
+ userHandle.getIdentifier());
+ PackageInfo packageInfo = pm.getPackageInfo(packageName,
+ PackageManager.GET_SIGNATURES);
+ PackageInfo sys = pm.getPackageInfo("android", PackageManager.GET_SIGNATURES);
+ return (packageInfo != null && packageInfo.signatures != null &&
+ sys.signatures[0].equals(packageInfo.signatures[0]));
+ } catch (PackageManager.NameNotFoundException e) {
+ return false;
+ }
+ }
+
private void saveImportance() {
if (!mIsNonblockable) {
if (mChosenImportance == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
index c747a7c..8e5cf99 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
@@ -189,6 +189,8 @@
}
public void applyConversationSkin() {
+ //since we don't want this anymore...
+ /*
if (mAppNameText != null) {
mAppNameText.setTextAppearance(
com.android.internal.R.style
@@ -212,7 +214,7 @@
ViewGroup.MarginLayoutParams layoutParams =
(ViewGroup.MarginLayoutParams) mIcon.getLayoutParams();
layoutParams.setMarginEnd(0);
- }
+ }*/
}
public void clearConversationSkin() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index a4a5819..98d1620 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -761,6 +761,7 @@
mCornerRadius = newRadius;
invalidate();
}
+ onUiModeChanged();
reinflateViews();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
index e03db2c..d84e622 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
@@ -22,20 +22,32 @@
import android.app.Fragment;
import android.os.Bundle;
import android.os.Parcelable;
+import android.provider.Settings;
import android.util.SparseArray;
+import android.content.ContentResolver;
+import android.database.ContentObserver;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.provider.Settings;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewStub;
+import android.widget.ImageSwitcher;
+import android.widget.ImageView;
import android.widget.LinearLayout;
import com.android.systemui.Dependency;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.BatteryMeterView;
import com.android.systemui.statusbar.phone.StatusBarIconController.DarkIconManager;
+import com.android.systemui.statusbar.phone.StatusIconContainer;
+import com.android.systemui.statusbar.policy.Clock;
import com.android.systemui.statusbar.policy.EncryptionHelper;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.NetworkController;
@@ -59,7 +71,9 @@
private KeyguardStateController mKeyguardStateController;
private NetworkController mNetworkController;
private LinearLayout mSystemIconArea;
+ private LinearLayout mCustomIconArea;
private View mClockView;
+ private int mClockStyle;
private View mNotificationIconAreaInner;
private View mCenteredIconArea;
private int mDisabled1;
@@ -67,6 +81,46 @@
private DarkIconManager mDarkIconManager;
private View mOperatorNameFrame;
private CommandQueue mCommandQueue;
+ private LinearLayout mCenterClockLayout;
+ private View mRightClock;
+ private boolean mShowClock = true;
+ private ImageView mBlissLogo;
+ private boolean mShowLogo;
+ private BatteryMeterView mBatteryMeterView;
+ private StatusIconContainer mStatusIcons;
+ private int mSignalClusterEndPadding = 0;
+ private View mCustomCarrierLabel;
+ private int mShowCarrierLabel;
+ private boolean mHasCarrierLabel;
+ private final Handler mHandler = new Handler();
+
+ private class SettingsObserver extends ContentObserver {
+ SettingsObserver(Handler handler) {
+ super(handler);
+ }
+
+ void observe() {
+ mContentResolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.STATUSBAR_CLOCK),
+ false, this, UserHandle.USER_ALL);
+ mContentResolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.STATUSBAR_CLOCK_STYLE),
+ false, this, UserHandle.USER_ALL);
+ mContentResolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.STATUS_BAR_LOGO),
+ false, this, UserHandle.USER_ALL);
+ mContentResolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.STATUS_BAR_SHOW_CARRIER),
+ false, this, UserHandle.USER_ALL);
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ updateSettings(true);
+ }
+ }
+ private SettingsObserver mSettingsObserver = new SettingsObserver(mHandler);
+ private ContentResolver mContentResolver;
private SignalCallback mSignalCallback = new SignalCallback() {
@Override
@@ -75,14 +129,25 @@
}
};
+ private BatteryMeterView.BatteryMeterViewCallbacks mBatteryMeterViewCallback =
+ new BatteryMeterView.BatteryMeterViewCallbacks() {
+ @Override
+ public void onHiddenBattery(boolean hidden) {
+ mStatusIcons.setPadding(
+ mStatusIcons.getPaddingLeft(), mStatusIcons.getPaddingTop(), (hidden ? 0 : mSignalClusterEndPadding), mStatusIcons.getPaddingBottom());
+ }
+ };
+
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ mContentResolver = getContext().getContentResolver();
mKeyguardStateController = Dependency.get(KeyguardStateController.class);
mNetworkController = Dependency.get(NetworkController.class);
mStatusBarStateController = Dependency.get(StatusBarStateController.class);
mStatusBarComponent = Dependency.get(StatusBar.class);
mCommandQueue = Dependency.get(CommandQueue.class);
+ mSettingsObserver.observe();
}
@Override
@@ -99,16 +164,33 @@
mStatusBar.restoreHierarchyState(
savedInstanceState.getSparseParcelableArray(EXTRA_PANEL_STATE));
}
+ mContentResolver = getContext().getContentResolver();
+ mSettingsObserver = new SettingsObserver(mHandler);
mDarkIconManager = new DarkIconManager(view.findViewById(R.id.statusIcons),
Dependency.get(CommandQueue.class));
mDarkIconManager.setShouldLog(true);
Dependency.get(StatusBarIconController.class).addIconGroup(mDarkIconManager);
mSystemIconArea = mStatusBar.findViewById(R.id.system_icon_area);
+ mSignalClusterEndPadding = getResources().getDimensionPixelSize(R.dimen.signal_cluster_battery_padding);
+ mStatusIcons = mStatusBar.findViewById(R.id.statusIcons);
+ int batteryStyle = Settings.System.getInt(getContext().getContentResolver(),
+ Settings.System.STATUS_BAR_BATTERY_STYLE, 0);
+ mStatusIcons.setPadding(mStatusIcons.getPaddingLeft(), mStatusIcons.getPaddingTop(), (batteryStyle == 5/*hidden*/ ? 0 : mSignalClusterEndPadding), mStatusIcons.getPaddingBottom());
+ mBatteryMeterView = mStatusBar.findViewById(R.id.battery);
+ mBatteryMeterView.addCallback(mBatteryMeterViewCallback);
+ mCustomIconArea = mStatusBar.findViewById(R.id.left_icon_area);
mClockView = mStatusBar.findViewById(R.id.clock);
+ mCenterClockLayout = (LinearLayout) mStatusBar.findViewById(R.id.center_clock_layout);
+ mRightClock = mStatusBar.findViewById(R.id.right_clock);
+ mBlissLogo = (ImageView)mStatusBar.findViewById(R.id.status_bar_logo);
+ Dependency.get(DarkIconDispatcher.class).addDarkReceiver(mBlissLogo);
+ mCustomCarrierLabel = mStatusBar.findViewById(R.id.statusbar_carrier_text);
showSystemIconArea(false);
- showClock(false);
initEmergencyCryptkeeperText();
+ animateHide(mClockView, false, false);
initOperatorName();
+ mSettingsObserver.observe();
+ updateSettings(false);
}
@Override
@@ -140,6 +222,10 @@
if (mNetworkController.hasEmergencyCryptKeeperText()) {
mNetworkController.removeCallback(mSignalCallback);
}
+ if (mBatteryMeterView != null) {
+ mBatteryMeterView.removeCallback(mBatteryMeterViewCallback);
+ }
+ Dependency.get(DarkIconDispatcher.class).removeDarkReceiver(mBlissLogo);
}
public void initNotificationIconArea(NotificationIconAreaController
@@ -186,17 +272,13 @@
if ((diff1 & DISABLE_NOTIFICATION_ICONS) != 0) {
if ((state1 & DISABLE_NOTIFICATION_ICONS) != 0) {
hideNotificationIconArea(animate);
+ hideCarrierName(animate);
+ animateHide(mClockView, animate, false);
} else {
showNotificationIconArea(animate);
- }
- }
- // The clock may have already been hidden, but we might want to shift its
- // visibility to GONE from INVISIBLE or vice versa
- if ((diff1 & DISABLE_CLOCK) != 0 || mClockView.getVisibility() != clockHiddenMode()) {
- if ((state1 & DISABLE_CLOCK) != 0) {
- hideClock(animate);
- } else {
- showClock(animate);
+ showCarrierName(animate);
+ updateClockStyle(animate);
+ setCarrierLabel(animate);
}
}
}
@@ -248,46 +330,63 @@
}
public void hideSystemIconArea(boolean animate) {
- animateHide(mSystemIconArea, animate);
+ animateHide(mCenterClockLayout, animate, true);
+ if (mClockStyle == 2) {
+ animateHide(mRightClock, animate, true);
+ }
+ animateHide(mSystemIconArea, animate, true);
}
public void showSystemIconArea(boolean animate) {
+ animateShow(mCenterClockLayout, animate);
+ if (mClockStyle == 2) {
+ animateShow(mRightClock, animate);
+ }
animateShow(mSystemIconArea, animate);
}
- public void hideClock(boolean animate) {
- animateHiddenState(mClockView, clockHiddenMode(), animate);
+/* public void hideClock(boolean animate) {
+ animateHide(mClockView, animate, false);
}
public void showClock(boolean animate) {
animateShow(mClockView, animate);
}
-
+*/
/**
* If panel is expanded/expanding it usually means QS shade is opening, so
* don't set the clock GONE otherwise it'll mess up the animation.
- */
private int clockHiddenMode() {
if (!mStatusBar.isClosed() && !mKeyguardStateController.isShowing()
&& !mStatusBarStateController.isDozing()) {
return View.INVISIBLE;
}
return View.GONE;
- }
+ }*/
public void hideNotificationIconArea(boolean animate) {
- animateHide(mNotificationIconAreaInner, animate);
- animateHide(mCenteredIconArea, animate);
+ animateHide(mNotificationIconAreaInner, animate, true);
+ animateHide(mCenteredIconArea, animate, true);
+ animateHide(mCenterClockLayout, animate, true);
+ if (mShowLogo) {
+ animateHide(mBlissLogo, animate, true);
+ }
+ animateHide(mCustomIconArea, animate, true);
}
public void showNotificationIconArea(boolean animate) {
animateShow(mNotificationIconAreaInner, animate);
animateShow(mCenteredIconArea, animate);
+ animateShow(mCenterClockLayout, animate);
+ if (mShowLogo) {
+ animateShow(mBlissLogo, animate);
+ }
+ animateShow(mCustomIconArea, animate);
}
public void hideOperatorName(boolean animate) {
if (mOperatorNameFrame != null) {
- animateHide(mOperatorNameFrame, animate);
+ animateHide(mOperatorNameFrame, animate, true);
}
}
@@ -297,14 +396,26 @@
}
}
+ public void hideCarrierName(boolean animate) {
+ if (mCustomCarrierLabel != null) {
+ animateHide(mCustomCarrierLabel, animate, true);
+ }
+ }
+
+ public void showCarrierName(boolean animate) {
+ if (mCustomCarrierLabel != null) {
+ setCarrierLabel(animate);
+ }
+ }
+
/**
- * Animate a view to INVISIBLE or GONE
+ * Hides a view.
*/
- private void animateHiddenState(final View v, int state, boolean animate) {
+ private void animateHide(final View v, boolean animate, final boolean invisible) {
v.animate().cancel();
if (!animate) {
v.setAlpha(0f);
- v.setVisibility(state);
+ v.setVisibility(invisible ? View.INVISIBLE : View.GONE);
return;
}
@@ -313,20 +424,16 @@
.setDuration(160)
.setStartDelay(0)
.setInterpolator(Interpolators.ALPHA_OUT)
- .withEndAction(() -> v.setVisibility(state));
- }
-
- /**
- * Hides a view.
- */
- private void animateHide(final View v, boolean animate) {
- animateHiddenState(v, View.INVISIBLE, animate);
+ .withEndAction(() -> v.setVisibility(invisible ? View.INVISIBLE : View.GONE));
}
/**
* Shows a view, and synchronizes the animation with Keyguard exit animations, if applicable.
*/
private void animateShow(View v, boolean animate) {
+ if (v instanceof Clock && !((Clock)v).isClockVisible()) {
+ return;
+ }
v.animate().cancel();
v.setVisibility(View.VISIBLE);
if (!animate) {
@@ -383,4 +490,53 @@
public void onDozingChanged(boolean isDozing) {
disable(getContext().getDisplayId(), mDisabled1, mDisabled1, false /* animate */);
}
+
+ public void updateSettings(boolean animate) {
+ mShowClock = Settings.System.getIntForUser(mContentResolver,
+ Settings.System.STATUSBAR_CLOCK, 1,
+ UserHandle.USER_CURRENT) == 1;
+ mShowLogo = Settings.System.getIntForUser(mContentResolver,
+ Settings.System.STATUS_BAR_LOGO, 0,
+ UserHandle.USER_CURRENT) == 1;
+ mShowCarrierLabel = Settings.System.getIntForUser(mContentResolver,
+ Settings.System.STATUS_BAR_SHOW_CARRIER, 1,
+ UserHandle.USER_CURRENT);
+ mHasCarrierLabel = (mShowCarrierLabel == 2 || mShowCarrierLabel == 3);
+ if (!mShowClock) {
+ mClockStyle = 1; // internally switch to centered clock layout because
+ // left & right will show up again after QS pulldown
+ } else {
+ mClockStyle = Settings.System.getIntForUser(mContentResolver,
+ Settings.System.STATUSBAR_CLOCK_STYLE, 0,
+ UserHandle.USER_CURRENT);
+ }
+ updateClockStyle(animate);
+ if (mNotificationIconAreaInner != null) {
+ if (mShowLogo) {
+ if (mNotificationIconAreaInner.getVisibility() == View.VISIBLE) {
+ animateShow(mBlissLogo, animate);
+ }
+ } else {
+ animateHide(mBlissLogo, animate, false);
+ }
+ }
+ }
+
+ private void updateClockStyle(boolean animate) {
+ if (mClockStyle == 1 || mClockStyle == 2) {
+ animateHide(mClockView, animate, false);
+ } else {
+ if (((Clock)mClockView).isClockVisible()) {
+ animateShow(mClockView, animate);
+ }
+ }
+ }
+
+ private void setCarrierLabel(boolean animate) {
+ if (mHasCarrierLabel) {
+ animateShow(mCustomCarrierLabel, animate);
+ } else {
+ animateHide(mCustomCarrierLabel, animate, false);
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
index 4afeba8..73018c8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
@@ -34,6 +34,7 @@
import com.android.systemui.doze.DozeHost;
import com.android.systemui.doze.DozeLog;
import com.android.systemui.doze.DozeReceiver;
+import com.android.systemui.keyguard.KeyguardSliceProvider;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.statusbar.PulseExpansionHandler;
@@ -362,30 +363,39 @@
}
@Override
- public void onSlpiTap(float screenX, float screenY) {
- if (screenX > 0 && screenY > 0 && mAmbientIndicationContainer != null
- && mAmbientIndicationContainer.getVisibility() == View.VISIBLE) {
- int[] locationOnScreen = new int[2];
- mAmbientIndicationContainer.getLocationOnScreen(locationOnScreen);
- float viewX = screenX - locationOnScreen[0];
- float viewY = screenY - locationOnScreen[1];
- if (0 <= viewX && viewX <= mAmbientIndicationContainer.getWidth()
- && 0 <= viewY && viewY <= mAmbientIndicationContainer.getHeight()) {
-
- // Dispatch a tap
- long now = SystemClock.elapsedRealtime();
- MotionEvent ev = MotionEvent.obtain(
- now, now, MotionEvent.ACTION_DOWN, screenX, screenY, 0);
- mAmbientIndicationContainer.dispatchTouchEvent(ev);
- ev.recycle();
- ev = MotionEvent.obtain(
- now, now, MotionEvent.ACTION_UP, screenX, screenY, 0);
- mAmbientIndicationContainer.dispatchTouchEvent(ev);
- ev.recycle();
+ public void onSlpiTap(float screenX, float screenY, int pulseReason) {
+ if (isDoubleTapOnMusicTicker(screenX, screenY)) {
+ for (Callback callback : mCallbacks) {
+ callback.skipTrack();
+ }
+ } else {
+ for (Callback callback : mCallbacks) {
+ callback.wakeUpFromDoubleTap(pulseReason);
}
}
}
+ public boolean isDoubleTapOnMusicTicker(float screenX, float screenY) {
+ final KeyguardSliceProvider sliceProvider = KeyguardSliceProvider.getAttachedInstance();
+ View trackTitleView = null;
+ if (mNotificationPanel != null) {
+ trackTitleView = mNotificationPanel.getKeyguardStatusView().getKeyguardSliceView().getTitleView();
+ }
+ if (screenX <= 0 || screenY <= 0 || sliceProvider == null || trackTitleView == null
+ || !sliceProvider.needsMediaLocked()) {
+ return false;
+ }
+ int[] locationOnScreen = new int[2];
+ trackTitleView.getLocationOnScreen(locationOnScreen);
+ float viewX = screenX - locationOnScreen[0];
+ float viewY = screenY - locationOnScreen[1];
+ if (0 <= viewX && viewX <= trackTitleView.getWidth()
+ && 0 <= viewY && viewY <= trackTitleView.getHeight()) {
+ return true;
+ }
+ return false;
+ }
+
@Override
public void setDozeScreenBrightness(int value) {
mNotificationShadeWindowController.setDozeScreenBrightness(value);
@@ -415,6 +425,16 @@
}
}
+ @Override
+ public void performToggleFlashlight() {
+ mStatusBar.toggleFlashlight();
+ }
+
+ @Override
+ public void performTriggeredAction(String action) {
+ mStatusBar.performTriggeredAction(action);
+ }
+
/**
* When the dozing host is waiting for scrims to fade out to change the display state.
*/
@@ -461,4 +481,16 @@
public boolean isDozeSuppressed() {
return mSuppressed;
}
+
+ public void toggleFlashlightProximityCheck() {
+ for (Callback callback : mCallbacks) {
+ callback.toggleFlashlightProximityCheck();
+ }
+ }
+
+ public void triggerActionProximityCheck(String action) {
+ for (Callback callback : mCallbacks) {
+ callback.triggerActionProximityCheck(action);
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
index 51c02c9..16da96d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
@@ -16,11 +16,16 @@
package com.android.systemui.statusbar.phone;
+import android.content.ContentResolver;
+import android.content.Context;
import android.graphics.Point;
import android.graphics.Rect;
import android.view.DisplayCutout;
+import android.os.UserHandle;
+import android.provider.Settings;
import android.view.View;
import android.view.WindowInsets;
+import android.widget.LinearLayout;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.widget.ViewClippingUtil;
@@ -57,6 +62,8 @@
private final View mCenteredIconView;
private final View mClockView;
private final View mOperatorNameView;
+ private final View mBlissLogoView;
+ private final LinearLayout mCustomIconArea;
private final DarkIconDispatcher mDarkIconDispatcher;
private final NotificationPanelViewController mNotificationPanelViewController;
private final Consumer<ExpandableNotificationRow>
@@ -107,7 +114,9 @@
notificationPanelViewController,
statusBarView.findViewById(R.id.clock),
statusBarView.findViewById(R.id.operator_name_frame),
- statusBarView.findViewById(R.id.centered_icon_area));
+ statusBarView.findViewById(R.id.centered_icon_area),
+ statusBarView.findViewById(R.id.status_bar_logo),
+ statusBarView.findViewById(R.id.left_icon_area));
}
@VisibleForTesting
@@ -124,7 +133,9 @@
NotificationPanelViewController notificationPanelViewController,
View clockView,
View operatorNameView,
- View centeredIconView) {
+ View centeredIconView,
+ View blissLogoView,
+ LinearLayout customIconArea) {
mNotificationIconAreaController = notificationIconAreaController;
mHeadsUpManager = headsUpManager;
mHeadsUpManager.addListener(this);
@@ -141,7 +152,9 @@
mStackScroller.addOnLayoutChangeListener(mStackScrollLayoutChangeListener);
mStackScroller.setHeadsUpAppearanceController(this);
mClockView = clockView;
+ mBlissLogoView = blissLogoView;
mOperatorNameView = operatorNameView;
+ mCustomIconArea = customIconArea;
mDarkIconDispatcher = Dependency.get(DarkIconDispatcher.class);
mDarkIconDispatcher.addDarkReceiver(this);
@@ -274,6 +287,11 @@
}
private void setShown(boolean isShown) {
+ final int clockStyle = Settings.System.getIntForUser(mClockView.getContext().getContentResolver(),
+ Settings.System.STATUSBAR_CLOCK_STYLE, 0, UserHandle.USER_CURRENT);
+ final boolean isClockVisible = Settings.System.getIntForUser(mClockView.getContext().getContentResolver(),
+ Settings.System.STATUSBAR_CLOCK, 1,
+ UserHandle.USER_CURRENT) == 1;
if (mShown != isShown) {
mShown = isShown;
if (isShown) {
@@ -287,14 +305,26 @@
if (mOperatorNameView != null) {
hide(mOperatorNameView, View.INVISIBLE);
}
+ if (mBlissLogoView.getVisibility() != View.GONE) {
+ hide(mBlissLogoView, View.INVISIBLE);
+ }
+ hide(mCustomIconArea, View.INVISIBLE);
} else {
- show(mClockView);
+ if (clockStyle == 0 && isClockVisible) {
+ show(mClockView);
+ } else {
+ mClockView.setVisibility(View.GONE);
+ }
if (mCenteredIconView.getVisibility() != View.GONE) {
show(mCenteredIconView);
}
if (mOperatorNameView != null) {
show(mOperatorNameView);
}
+ if (mBlissLogoView.getVisibility() != View.GONE) {
+ show(mBlissLogoView);
+ }
+ show(mCustomIconArea);
hide(mHeadsUpStatusBarView, View.GONE, () -> {
updateParentClipping(true /* shouldClip */);
});
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
index a3f14ba..24148c9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
@@ -39,6 +39,11 @@
private static float CLOCK_HEIGHT_WEIGHT = 0.7f;
/**
+ * Allow using the default clock Y calculations
+ */
+ public static int CLOCK_USE_DEFAULT_Y = -1;
+
+ /**
* Margin between the bottom of the clock and the notification shade.
*/
private int mClockNotificationsMargin;
@@ -180,12 +185,17 @@
return mHeight / 2 - mKeyguardStatusHeight - mClockNotificationsMargin;
}
- private int getPreferredClockY() {
- return mClockPreferredY;
+ private int getPreferredAlternativeClockY(int alternative) {
+ if (mClockPreferredY != CLOCK_USE_DEFAULT_Y) {
+ return mClockPreferredY;
+ } else {
+ return alternative;
+ }
}
private int getExpandedPreferredClockY() {
- return (mHasCustomClock && (!mHasVisibleNotifs || mBypassEnabled)) ? getPreferredClockY()
+ return (mHasCustomClock && (!mHasVisibleNotifs || mBypassEnabled))
+ ? getPreferredAlternativeClockY(getExpandedClockPosition())
: getExpandedClockPosition();
}
@@ -215,8 +225,8 @@
private int getClockY(float panelExpansion) {
// Dark: Align the bottom edge of the clock at about half of the screen:
- float clockYDark = (mHasCustomClock ? getPreferredClockY() : getMaxClockY())
- + burnInPreventionOffsetY();
+ float clockYDark = (mHasCustomClock ? getPreferredAlternativeClockY(getMaxClockY())
+ : getMaxClockY()) + burnInPreventionOffsetY();
clockYDark = MathUtils.max(0, clockYDark);
float clockYRegular = getExpandedPreferredClockY();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
index 8636cb2..222505d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
@@ -24,7 +24,12 @@
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Rect;
+import android.database.ContentObserver;
import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.provider.Settings;
import android.util.AttributeSet;
import android.util.Pair;
import android.util.TypedValue;
@@ -78,6 +83,8 @@
private boolean mKeyguardUserSwitcherShowing;
private boolean mBatteryListening;
+ private int mShowCarrierLabel;
+
private TextView mCarrierLabel;
private MultiUserSwitch mMultiUserSwitch;
private ImageView mMultiUserAvatar;
@@ -107,8 +114,21 @@
// right and left padding applied to this view to account for cutouts and rounded corners
private Pair<Integer, Integer> mPadding = new Pair(0, 0);
+ private ContentObserver mObserver = new ContentObserver(new Handler()) {
+ public void onChange(boolean selfChange, Uri uri) {
+ showStatusBarCarrier();
+ updateVisibilities();
+ }
+ };
+
public KeyguardStatusBarView(Context context, AttributeSet attrs) {
super(context, attrs);
+ showStatusBarCarrier();
+ }
+
+ private void showStatusBarCarrier() {
+ mShowCarrierLabel = Settings.System.getIntForUser(getContext().getContentResolver(),
+ Settings.System.STATUS_BAR_SHOW_CARRIER, 1, UserHandle.USER_CURRENT);
}
@Override
@@ -213,6 +233,15 @@
}
}
mBatteryView.setForceShowPercent(mBatteryCharging && mShowPercentAvailable);
+ if (mCarrierLabel != null) {
+ if (mShowCarrierLabel == 1 || mShowCarrierLabel == 3) {
+ mCarrierLabel.setVisibility(View.VISIBLE);
+ mCarrierLabel.setSelected(true);
+ } else {
+ mCarrierLabel.setVisibility(View.GONE);
+ mCarrierLabel.setSelected(false);
+ }
+ }
}
private void updateSystemIconsLayoutParams() {
@@ -353,6 +382,8 @@
mIconManager = new TintedIconManager(findViewById(R.id.statusIcons),
Dependency.get(CommandQueue.class));
Dependency.get(StatusBarIconController.class).addIconGroup(mIconManager);
+ getContext().getContentResolver().registerContentObserver(Settings.System.getUriFor(
+ Settings.System.STATUS_BAR_SHOW_CARRIER), false, mObserver);
onThemeChanged();
}
@@ -479,6 +510,8 @@
@Override
public void onOverlayChanged() {
+ mShowPercentAvailable = getContext().getResources().getBoolean(
+ com.android.internal.R.bool.config_battery_percentage_setting_available);
mCarrierLabel.setTextAppearance(
Utils.getThemeAttr(mContext, com.android.internal.R.attr.textAppearanceSmall));
onThemeChanged();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
index ec54b30..a4a95ab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
@@ -115,7 +115,7 @@
boolean updateIconVisibility(boolean visible) {
boolean wasVisible = getVisibility() == VISIBLE;
if (visible != wasVisible) {
- setVisibility(visible ? VISIBLE : INVISIBLE);
+ setVisibility((visible && !mPulsing) ? VISIBLE : INVISIBLE);
animate().cancel();
if (visible) {
setScaleX(0);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java
index 7a8dc32..5bf487a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java
@@ -145,6 +145,11 @@
private int mDensity;
@Override
+ public void onOverlayChanged() {
+ onThemeChanged();
+ }
+
+ @Override
public void onThemeChanged() {
if (mLockIcon == null) {
return;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index e60293c..3869b31 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -25,9 +25,7 @@
import static android.view.InsetsState.containsType;
import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;
import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_NAVIGATION_BARS;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
-import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
import static com.android.internal.accessibility.common.ShortcutConstants.CHOOSER_PACKAGE_NAME;
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.NAV_BAR_HANDLE_FORCE_OPAQUE;
@@ -59,9 +57,6 @@
import android.content.res.Configuration;
import android.database.ContentObserver;
import android.graphics.PixelFormat;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.hardware.display.DisplayManager;
import android.inputmethodservice.InputMethodService;
import android.net.Uri;
import android.os.Binder;
@@ -77,7 +72,6 @@
import android.text.TextUtils;
import android.util.Log;
import android.view.Display;
-import android.view.Gravity;
import android.view.InsetsState.InternalInsetsType;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -145,7 +139,7 @@
* on clicks and view states of the nav bar.
*/
public class NavigationBarFragment extends LifecycleFragment implements Callbacks,
- NavigationModeController.ModeChangedListener, DisplayManager.DisplayListener {
+ NavigationModeController.ModeChangedListener {
public static final String TAG = "NavigationBar";
private static final boolean DEBUG = false;
@@ -211,23 +205,7 @@
private boolean mIsOnDefaultDisplay;
public boolean mHomeBlockedThisTouch;
- /**
- * When user is QuickSwitching between apps of different orientations, we'll draw a fake
- * home handle on the orientation they originally touched down to start their swipe
- * gesture to indicate to them that they can continue in that orientation without having to
- * rotate the phone
- * The secondary handle will show when we get
- * {@link OverviewProxyListener#onQuickSwitchToNewTask(int)} callback with the
- * original handle hidden and we'll flip the visibilities once the
- * {@link #mTasksFrozenListener} fires
- */
- private QuickswitchOrientedNavHandle mOrientationHandle;
- private WindowManager.LayoutParams mOrientationParams;
- private int mStartingQuickSwitchRotation = -1;
- private int mCurrentRotation;
- private ViewTreeObserver.OnGlobalLayoutListener mOrientationHandleGlobalLayoutListener;
private UiEventLogger mUiEventLogger;
- private boolean mShowOrientedHandleForImmersiveMode;
@com.android.internal.annotations.VisibleForTesting
public enum NavBarActionEvent implements UiEventLogger.UiEventEnum {
@@ -297,15 +275,6 @@
}
@Override
- public void onQuickSwitchToNewTask(@Surface.Rotation int rotation) {
- mStartingQuickSwitchRotation = rotation;
- if (rotation == -1) {
- mShowOrientedHandleForImmersiveMode = false;
- }
- orientSecondaryHomeHandle();
- }
-
- @Override
public void startAssistant(Bundle bundle) {
mAssistManager.startAssist(bundle);
}
@@ -346,14 +315,6 @@
}
};
- private NavigationBarTransitions.DarkIntensityListener mOrientationHandleIntensityListener =
- new NavigationBarTransitions.DarkIntensityListener() {
- @Override
- public void onDarkIntensity(float darkIntensity) {
- mOrientationHandle.setDarkIntensity(darkIntensity);
- }
- };
-
private final Runnable mAutoDim = () -> getBarTransitions().setAutoDim(true);
private final ContentObserver mAssistContentObserver = new ContentObserver(
@@ -531,8 +492,6 @@
new AssistHandleViewController(mHandler, mNavigationBarView);
getBarTransitions().addDarkIntensityListener(mAssistHandlerViewController);
}
-
- initSecondaryHomeHandleForRotation();
}
@Override
@@ -549,14 +508,6 @@
}
mOverviewProxyService.removeCallback(mOverviewProxyListener);
mBroadcastDispatcher.unregisterReceiver(mBroadcastReceiver);
- if (mOrientationHandle != null) {
- resetSecondaryHandle();
- getContext().getSystemService(DisplayManager.class).unregisterDisplayListener(this);
- getBarTransitions().removeDarkIntensityListener(mOrientationHandleIntensityListener);
- mWindowManager.removeView(mOrientationHandle);
- mOrientationHandle.getViewTreeObserver().removeOnGlobalLayoutListener(
- mOrientationHandleGlobalLayoutListener);
- }
}
@Override
@@ -589,115 +540,6 @@
repositionNavigationBar();
}
- private void initSecondaryHomeHandleForRotation() {
- if (!canShowSecondaryHandle()) {
- return;
- }
-
- getContext().getSystemService(DisplayManager.class)
- .registerDisplayListener(this, new Handler(Looper.getMainLooper()));
-
- mOrientationHandle = new QuickswitchOrientedNavHandle(getContext());
- mOrientationHandle.setId(R.id.secondary_home_handle);
-
- getBarTransitions().addDarkIntensityListener(mOrientationHandleIntensityListener);
- mOrientationParams = new WindowManager.LayoutParams(0, 0,
- WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
- WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
- | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
- | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
- | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
- | WindowManager.LayoutParams.FLAG_SLIPPERY,
- PixelFormat.TRANSLUCENT);
- mOrientationParams.setTitle("SecondaryHomeHandle" + getContext().getDisplayId());
- mOrientationParams.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION;
- mWindowManager.addView(mOrientationHandle, mOrientationParams);
- mOrientationHandle.setVisibility(View.GONE);
- mOrientationParams.setFitInsetsTypes(0 /* types*/);
- mOrientationHandleGlobalLayoutListener =
- () -> {
- if (mStartingQuickSwitchRotation == -1) {
- return;
- }
-
- RectF boundsOnScreen = mOrientationHandle.computeHomeHandleBounds();
- mOrientationHandle.mapRectFromViewToScreenCoords(boundsOnScreen, true);
- Rect boundsRounded = new Rect();
- boundsOnScreen.roundOut(boundsRounded);
- mNavigationBarView.setOrientedHandleSamplingRegion(boundsRounded);
- };
- mOrientationHandle.getViewTreeObserver().addOnGlobalLayoutListener(
- mOrientationHandleGlobalLayoutListener);
- }
-
- private void orientSecondaryHomeHandle() {
- if (!canShowSecondaryHandle()) {
- return;
- }
-
- if (mStartingQuickSwitchRotation == -1 || mDivider.isDividerVisible()) {
- // Hide the secondary home handle if we are in multiwindow since apps in multiwindow
- // aren't allowed to set the display orientation
- resetSecondaryHandle();
- } else {
- int deltaRotation = deltaRotation(mCurrentRotation, mStartingQuickSwitchRotation);
- if (mStartingQuickSwitchRotation == -1 || deltaRotation == -1) {
- // Curious if starting quickswitch can change between the if check and our delta
- Log.d(TAG, "secondary nav delta rotation: " + deltaRotation
- + " current: " + mCurrentRotation
- + " starting: " + mStartingQuickSwitchRotation);
- }
- int height = 0;
- int width = 0;
- Rect dispSize = mWindowManager.getCurrentWindowMetrics().getBounds();
- mOrientationHandle.setDeltaRotation(deltaRotation);
- switch (deltaRotation) {
- case Surface.ROTATION_90:
- case Surface.ROTATION_270:
- height = dispSize.height();
- width = mNavigationBarView.getHeight();
- break;
- case Surface.ROTATION_180:
- case Surface.ROTATION_0:
- // TODO(b/152683657): Need to determine best UX for this
- if (!mShowOrientedHandleForImmersiveMode) {
- resetSecondaryHandle();
- return;
- }
- width = dispSize.width();
- height = mNavigationBarView.getHeight();
- break;
- }
-
- mOrientationParams.gravity =
- deltaRotation == Surface.ROTATION_0 ? Gravity.BOTTOM :
- (deltaRotation == Surface.ROTATION_90 ? Gravity.LEFT : Gravity.RIGHT);
- mOrientationParams.height = height;
- mOrientationParams.width = width;
- mWindowManager.updateViewLayout(mOrientationHandle, mOrientationParams);
- mNavigationBarView.setVisibility(View.GONE);
- mOrientationHandle.setVisibility(View.VISIBLE);
- }
- }
-
- private void resetSecondaryHandle() {
- if (mOrientationHandle != null) {
- // Case where nav mode is changed w/o ever invoking a quickstep
- // mOrientedHandle is initialized lazily
- mOrientationHandle.setVisibility(View.GONE);
- }
- if (mNavigationBarView != null) {
- mNavigationBarView.setVisibility(View.VISIBLE);
- mNavigationBarView.setOrientedHandleSamplingRegion(null);
- }
- }
-
- private int deltaRotation(int oldRotation, int newRotation) {
- int delta = newRotation - oldRotation;
- if (delta < 0) delta += 4;
- return delta;
- }
-
@Override
public void dump(String prefix, FileDescriptor fd, PrintWriter pw, String[] args) {
if (mNavigationBarView != null) {
@@ -708,8 +550,6 @@
dumpBarTransitions(pw, "mNavigationBarView", mNavigationBarView.getBarTransitions());
}
- pw.print(" mStartingQuickSwitchRotation=" + mStartingQuickSwitchRotation);
- pw.print(" mCurrentRotation=" + mCurrentRotation);
pw.print(" mNavigationBarView=");
if (mNavigationBarView == null) {
pw.println("null");
@@ -765,11 +605,6 @@
&& mNavigationBarWindowState != state) {
mNavigationBarWindowState = state;
updateSystemUiStateFlags(-1);
- mShowOrientedHandleForImmersiveMode = state == WINDOW_STATE_HIDDEN;
- if (mOrientationHandle != null
- && mStartingQuickSwitchRotation != -1) {
- orientSecondaryHomeHandle();
- }
if (DEBUG_WINDOW_STATE) Log.d(TAG, "Navigation bar " + windowStateToString(state));
if (mNavigationBarView != null) {
@@ -1339,10 +1174,6 @@
mNavBarMode = mode;
updateScreenPinningGestures();
- if (!canShowSecondaryHandle()) {
- resetSecondaryHandle();
- }
-
// Workaround for b/132825155, for secondary users, we currently don't receive configuration
// changes on overlay package change since SystemUI runs for the system user. In this case,
// trigger a new configuration change to ensure that the nav bar is updated in the same way.
@@ -1387,34 +1218,6 @@
private final AccessibilityServicesStateChangeListener mAccessibilityListener =
this::updateAccessibilityServicesState;
- @Override
- public void onDisplayAdded(int displayId) {
-
- }
-
- @Override
- public void onDisplayRemoved(int displayId) {
-
- }
-
- @Override
- public void onDisplayChanged(int displayId) {
- if (!canShowSecondaryHandle()) {
- return;
- }
-
- int rotation = getContext().getResources().getConfiguration()
- .windowConfiguration.getRotation();
- if (rotation != mCurrentRotation) {
- mCurrentRotation = rotation;
- orientSecondaryHomeHandle();
- }
- }
-
- private boolean canShowSecondaryHandle() {
- return mNavBarMode == NAV_BAR_MODE_GESTURAL;
- }
-
private final Consumer<Integer> mRotationWatcher = rotation -> {
if (mNavigationBarView != null
&& mNavigationBarView.needsReorient(rotation)) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 5bb3c83..7e99af6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -530,6 +530,10 @@
return drawable;
}
+ public KeyButtonDrawable getRecentsDrawable() {
+ return getDrawable(R.drawable.ic_sysbar_recent);
+ }
+
private void orientBackButton(KeyButtonDrawable drawable) {
final boolean useAltBack =
(mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) != 0;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationHandle.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationHandle.java
index b874795..abceb11 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationHandle.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationHandle.java
@@ -32,11 +32,11 @@
public class NavigationHandle extends View implements ButtonInterface {
- protected final Paint mPaint = new Paint();
+ private final Paint mPaint = new Paint();
private @ColorInt final int mLightColor;
private @ColorInt final int mDarkColor;
- protected final int mRadius;
- protected final int mBottom;
+ private final int mRadius;
+ private final int mBottom;
private boolean mRequiresInvalidate;
public NavigationHandle(Context context) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index 799e16c..1981882 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -29,8 +29,11 @@
import android.app.ActivityManager;
import android.app.Fragment;
import android.app.StatusBarManager;
+import android.content.ContentResolver;
+import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
+import android.database.ContentObserver;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
@@ -40,9 +43,13 @@
import android.graphics.Region;
import android.graphics.drawable.Drawable;
import android.hardware.biometrics.BiometricSourceType;
+import android.net.Uri;
import android.os.Bundle;
+import android.os.Handler;
import android.os.PowerManager;
import android.os.SystemClock;
+import android.os.UserHandle;
+import android.provider.Settings;
import android.util.Log;
import android.util.MathUtils;
import android.view.LayoutInflater;
@@ -57,11 +64,14 @@
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
import android.widget.TextView;
+import android.content.Context;
+import android.view.GestureDetector;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.LatencyTracker;
+import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardClockSwitch;
import com.android.keyguard.KeyguardStatusView;
import com.android.keyguard.KeyguardUpdateMonitor;
@@ -125,6 +135,8 @@
import javax.inject.Inject;
+import com.android.internal.util.bliss.BlissUtils;
+
@StatusBarComponent.StatusBarScope
public class NotificationPanelViewController extends PanelViewController {
@@ -260,7 +272,6 @@
private QS mQs;
private FrameLayout mQsFrame;
private KeyguardStatusView mKeyguardStatusView;
- private View mQsNavbarScrim;
private NotificationsQuickSettingsContainer mNotificationContainerParent;
private NotificationStackScrollLayout mNotificationStackScroller;
private boolean mAnimateNextPositionUpdate;
@@ -302,6 +313,8 @@
private float mDownX;
private float mDownY;
+ private boolean mKeyguardOrShadeShowing;
+
private final KeyguardClockPositionAlgorithm
mClockPositionAlgorithm =
new KeyguardClockPositionAlgorithm();
@@ -348,6 +361,9 @@
private FalsingManager mFalsingManager;
private String mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_AFFORDANCE;
+ private LockPatternUtils mLockPatternUtils;
+ private boolean mStatusBarLockedOnSecureKeyguard;
+
private Runnable mHeadsUpExistenceChangedRunnable = () -> {
setHeadsUpAnimatingAway(false);
notifyBarPanelExpansionChanged();
@@ -389,6 +405,9 @@
private ArrayList<Runnable> mVerticalTranslationListener = new ArrayList<>();
private HeadsUpAppearanceController mHeadsUpAppearanceController;
+ private SettingsObserver mSettingsObserver;
+ private Handler mHandler = new Handler();
+
private int mPanelAlpha;
private Runnable mPanelAlphaEndAction;
private float mBottomAreaShadeAlpha;
@@ -415,6 +434,11 @@
private final ShadeController mShadeController;
private int mDisplayId;
+ private int mStatusBarHeaderHeight;
+ private GestureDetector mDoubleTapGesture;
+ private GestureDetector mLockscreenDoubleTapToSleep;
+ private boolean mIsLockscreenDoubleTapEnabled;
+
/**
* Cache the resource id of the theme to avoid unnecessary work in onThemeChanged.
*
@@ -433,6 +457,7 @@
private boolean mShowingKeyguardHeadsUp;
private boolean mAllowExpandForSmallExpansion;
private Runnable mExpandAfterLayoutRunnable;
+ private int mOneFingerQuickSettingsIntercept;
/**
* Is this a collapse that started on the panel where we should allow the panel to intercept
@@ -553,6 +578,26 @@
});
mBottomAreaShadeAlphaAnimator.setDuration(160);
mBottomAreaShadeAlphaAnimator.setInterpolator(Interpolators.ALPHA_OUT);
+ mDoubleTapGesture = new GestureDetector(mView.getContext(), new GestureDetector.SimpleOnGestureListener() {
+ @Override
+ public boolean onDoubleTap(MotionEvent e) {
+ BlissUtils.switchScreenOff(mView.getContext());
+ // quick pulldown can trigger those values
+ // on double tap - so reset them
+ mQsExpandImmediate = false;
+ requestPanelHeightUpdate();
+ setListening(false);
+ return true;
+ }
+ });
+ mLockscreenDoubleTapToSleep = new GestureDetector(mView.getContext(),
+ new GestureDetector.SimpleOnGestureListener() {
+ @Override
+ public boolean onDoubleTap(MotionEvent e) {
+ BlissUtils.switchScreenOff(mView.getContext());
+ return true;
+ }
+ });
mShadeController = shadeController;
mLockscreenUserManager = notificationLockscreenUserManager;
mEntryManager = notificationEntryManager;
@@ -571,6 +616,8 @@
mView.getOverlay().add(new DebugDrawable());
}
+ mSettingsObserver = new SettingsObserver(mHandler);
+ mLockPatternUtils = new LockPatternUtils(mView.getContext());
onFinishInflate();
}
@@ -590,7 +637,6 @@
mNotificationStackScroller.setOnEmptySpaceClickListener(mOnEmptySpaceClickListener);
addTrackingHeadsUpListener(mNotificationStackScroller::setTrackingHeadsUp);
mKeyguardBottomArea = mView.findViewById(R.id.keyguard_bottom_area);
- mQsNavbarScrim = mView.findViewById(R.id.qs_navbar_scrim);
mLastOrientation = mResources.getConfiguration().orientation;
initBottomArea();
@@ -649,6 +695,8 @@
com.android.internal.R.dimen.status_bar_height);
mHeadsUpInset = statusbarHeight + mResources.getDimensionPixelSize(
R.dimen.heads_up_status_bar_padding);
+ mStatusBarHeaderHeight = mResources.getDimensionPixelSize(
+ R.dimen.status_bar_height);
}
/**
@@ -658,6 +706,14 @@
return mKeyguardStatusView.hasCustomClock();
}
+ public KeyguardStatusView getKeyguardStatusView() {
+ return mKeyguardStatusView;
+ }
+
+ public boolean hasCustomClockInBigContainer() {
+ return mKeyguardStatusView.hasCustomClockInBigContainer();
+ }
+
private void setStatusBar(StatusBar bar) {
// TODO: this can be injected.
mStatusBar = bar;
@@ -813,7 +869,7 @@
mClockPositionAlgorithm.setup(mStatusBarMinHeight, totalHeight - bottomPadding,
mNotificationStackScroller.getIntrinsicContentHeight(), getExpandedFraction(),
totalHeight, (int) (mKeyguardStatusView.getHeight() - mShelfHeight / 2.0f
- - mDarkIconSize / 2.0f), clockPreferredY, hasCustomClock(),
+ - mDarkIconSize / 2.0f), clockPreferredY, hasCustomClockInBigContainer(),
hasVisibleNotifications, mInterpolatedDarkAmount, mEmptyDragAmount,
bypassEnabled, getUnlockedStackScrollerPadding());
mClockPositionAlgorithm.run(mClockPositionResult);
@@ -949,10 +1005,15 @@
mAnimateNextPositionUpdate = true;
}
+ private boolean isQSEventBlocked() {
+ return mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser())
+ && mStatusBarLockedOnSecureKeyguard && mKeyguardOrShadeShowing;
+ }
+
public void setQsExpansionEnabled(boolean qsExpansionEnabled) {
mQsExpansionEnabled = qsExpansionEnabled;
if (mQs == null) return;
- mQs.setHeaderClickable(qsExpansionEnabled);
+ mQs.setHeaderClickable(mQsExpansionEnabled);
}
@Override
@@ -1017,7 +1078,7 @@
}
public void expandWithQs() {
- if (mQsExpansionEnabled) {
+ if (mQsExpansionEnabled && !isQSEventBlocked()) {
mQsExpandImmediate = true;
mNotificationStackScroller.setShouldShowShelfOnly(true);
}
@@ -1249,11 +1310,15 @@
return mNotificationStackScroller.getOpeningHeight();
}
+ public void setLockscreenDoubleTapToSleep(boolean isDoubleTapEnabled) {
+ mIsLockscreenDoubleTapEnabled = isDoubleTapEnabled;
+ }
private boolean handleQsTouch(MotionEvent event) {
final int action = event.getActionMasked();
if (action == MotionEvent.ACTION_DOWN && getExpandedFraction() == 1f
- && mBarState != StatusBarState.KEYGUARD && !mQsExpanded && mQsExpansionEnabled) {
+ && mBarState != StatusBarState.KEYGUARD && !mQsExpanded
+ && mQsExpansionEnabled && !isQSEventBlocked()) {
// Down in the empty area while fully expanded - go to QS.
mQsTracking = true;
@@ -1275,7 +1340,7 @@
if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
mConflictingQsExpansionGesture = false;
}
- if (action == MotionEvent.ACTION_DOWN && isFullyCollapsed() && mQsExpansionEnabled) {
+ if (action == MotionEvent.ACTION_DOWN && isFullyCollapsed() && mQsExpansionEnabled && !isQSEventBlocked()) {
mTwoFingerQsExpandPossible = true;
}
if (mTwoFingerQsExpandPossible && isOpenQsEvent(event) && event.getY(event.getActionIndex())
@@ -1318,7 +1383,23 @@
MotionEvent.BUTTON_SECONDARY) || event.isButtonPressed(
MotionEvent.BUTTON_TERTIARY));
- return twoFingerDrag || stylusButtonClickDrag || mouseButtonClickDrag;
+ final float w = mView.getMeasuredWidth();
+
+ final float x = event.getX();
+ float region = w * 1.f / 4.f; // TODO overlay region fraction?
+ boolean showQsOverride = false;
+
+ switch (mOneFingerQuickSettingsIntercept) {
+ case 1: // Right side pulldown
+ showQsOverride = mView.isLayoutRtl() ? x < region : w - region < x;
+ break;
+ case 2: // Left side pulldown
+ showQsOverride = mView.isLayoutRtl() ? w - region < x : x < region;
+ break;
+ }
+ showQsOverride &= mBarState == StatusBarState.SHADE;
+
+ return twoFingerDrag || showQsOverride || stylusButtonClickDrag || mouseButtonClickDrag;
}
private void handleQsDown(MotionEvent event) {
@@ -1663,9 +1744,6 @@
|| mQsExpansionFromOverscroll));
updateEmptyShadeView();
- mQsNavbarScrim.setVisibility(
- mBarState == StatusBarState.SHADE && mQsExpanded && !mStackScrollerOverscrolling
- && mQsScrimEnabled ? View.VISIBLE : View.INVISIBLE);
if (mKeyguardUserSwitcher != null && mQsExpanded && !mStackScrollerOverscrolling) {
mKeyguardUserSwitcher.hideIfNotSimple(true /* animate */);
}
@@ -1690,10 +1768,6 @@
updateKeyguardBottomAreaAlpha();
updateBigClockAlpha();
}
- if (mBarState == StatusBarState.SHADE && mQsExpanded && !mStackScrollerOverscrolling
- && mQsScrimEnabled) {
- mQsNavbarScrim.setAlpha(getQsExpansionFraction());
- }
if (mAccessibilityManager.isEnabled()) {
mView.setAccessibilityPaneTitle(determineAccessibilityPaneTitle());
@@ -1915,7 +1989,7 @@
* @return Whether we should intercept a gesture to open Quick Settings.
*/
private boolean shouldQuickSettingsIntercept(float x, float y, float yDiff) {
- if (!mQsExpansionEnabled || mCollapsedOnDown || (mKeyguardShowing
+ if (!mQsExpansionEnabled || mCollapsedOnDown || isQSEventBlocked() || (mKeyguardShowing
&& mKeyguardBypassController.getBypassEnabled())) {
return false;
}
@@ -2627,7 +2701,7 @@
* @param x the x-coordinate the touch event
*/
protected void updateVerticalPanelPosition(float x) {
- if (mNotificationStackScroller.getWidth() * 1.75f > mView.getWidth()) {
+ if (mKeyguardShowing || mNotificationStackScroller.getWidth() * 1.75f > mView.getWidth()) {
resetHorizontalPanelPosition();
return;
}
@@ -2808,6 +2882,42 @@
return !isFullWidth() || !mShowIconsWhenExpanded;
}
+ class SettingsObserver extends ContentObserver {
+ SettingsObserver(Handler handler) {
+ super(handler);
+ }
+
+ void observe() {
+ ContentResolver resolver = mView.getContext().getContentResolver();
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.STATUS_BAR_LOCKED_ON_SECURE_KEYGUARD),
+ false, this, UserHandle.USER_ALL);
+ update();
+ }
+
+ void unobserve() {
+ ContentResolver resolver = mView.getContext().getContentResolver();
+ resolver.unregisterContentObserver(this);
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ update();
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ update();
+ }
+
+ public void update() {
+ ContentResolver resolver = mView.getContext().getContentResolver();
+ mStatusBarLockedOnSecureKeyguard = Settings.System.getIntForUser(
+ resolver, Settings.System.STATUS_BAR_LOCKED_ON_SECURE_KEYGUARD, 0,
+ UserHandle.USER_CURRENT) == 1;
+ }
+ }
+
private final FragmentListener mFragmentListener = new FragmentListener() {
@Override
public void onFragmentViewCreated(String tag, Fragment fragment) {
@@ -3067,6 +3177,10 @@
mOnReinflationListener = onReinflationListener;
}
+ public void setQsQuickPulldown(int mode) {
+ mOneFingerQuickSettingsIntercept = mode;
+ }
+
public void setAlpha(float alpha) {
mView.setAlpha(alpha);
}
@@ -3156,6 +3270,16 @@
if (mStatusBar.isBouncerShowingScrimmed()) {
return false;
}
+ if (!mQsExpanded
+ && mDoubleTapToSleepEnabled
+ && event.getY() < mStatusBarHeaderHeight) {
+ mDoubleTapGesture.onTouchEvent(event);
+ }
+
+ if (mIsLockscreenDoubleTapEnabled
+ && mBarState == StatusBarState.KEYGUARD) {
+ mLockscreenDoubleTapToSleep.onTouchEvent(event);
+ }
// Make sure the next touch won't the blocked after the current ends.
if (event.getAction() == MotionEvent.ACTION_UP
@@ -3244,7 +3368,7 @@
if (mQsExpanded) {
flingSettings(0 /* vel */, FLING_COLLAPSE, null /* onFinishRunnable */,
true /* isClick */);
- } else if (mQsExpansionEnabled) {
+ } else if (mQsExpansionEnabled && !isQSEventBlocked()) {
mLockscreenGestureLogger.write(MetricsEvent.ACTION_SHADE_QS_TAP, 0, 0);
flingSettings(0 /* vel */, FLING_EXPAND, null /* onFinishRunnable */,
true /* isClick */);
@@ -3257,7 +3381,7 @@
@Override
public void onOverscrollTopChanged(float amount, boolean isRubberbanded) {
cancelQsAnimation();
- if (!mQsExpansionEnabled) {
+ if (!mQsExpansionEnabled || isQSEventBlocked()) {
amount = 0f;
}
float rounded = amount >= 1f ? amount : 0f;
@@ -3273,8 +3397,8 @@
mLastOverscroll = 0f;
mQsExpansionFromOverscroll = false;
setQsExpansion(mQsExpansionHeight);
- flingSettings(!mQsExpansionEnabled && open ? 0f : velocity,
- open && mQsExpansionEnabled ? FLING_EXPAND : FLING_COLLAPSE, () -> {
+ flingSettings((!mQsExpansionEnabled || isQSEventBlocked()) && open ? 0f : velocity,
+ open && (mQsExpansionEnabled && !isQSEventBlocked()) ? FLING_EXPAND : FLING_COLLAPSE, () -> {
mStackScrollerOverscrolling = false;
setOverScrolling(false);
updateQsState();
@@ -3545,11 +3669,15 @@
boolean keyguardFadingAway = mKeyguardStateController.isKeyguardFadingAway();
int oldState = mBarState;
boolean keyguardShowing = statusBarState == StatusBarState.KEYGUARD;
+ boolean keyguardOrShadeShowing = statusBarState == StatusBarState.KEYGUARD
+ || statusBarState == StatusBarState.SHADE_LOCKED;
+
setKeyguardStatusViewVisibility(statusBarState, keyguardFadingAway, goingToFullShade);
setKeyguardBottomAreaVisibility(statusBarState, goingToFullShade);
mBarState = statusBarState;
mKeyguardShowing = keyguardShowing;
+ mKeyguardOrShadeShowing = keyguardOrShadeShowing;
if (oldState == StatusBarState.KEYGUARD && (goingToFullShade
|| statusBarState == StatusBarState.SHADE_LOCKED)) {
@@ -3610,6 +3738,7 @@
private class OnAttachStateChangeListener implements View.OnAttachStateChangeListener {
@Override
public void onViewAttachedToWindow(View v) {
+ mSettingsObserver.observe();
FragmentHostManager.get(mView).addTagListener(QS.TAG, mFragmentListener);
mStatusBarStateController.addCallback(mStatusBarStateListener);
mZenModeController.addCallback(mZenModeControllerCallback);
@@ -3623,6 +3752,7 @@
@Override
public void onViewDetachedFromWindow(View v) {
+ mSettingsObserver.unobserve();
FragmentHostManager.get(mView).removeTagListener(QS.TAG, mFragmentListener);
mStatusBarStateController.removeCallback(mStatusBarStateListener);
mZenModeController.removeCallback(mZenModeControllerCallback);
@@ -3758,4 +3888,7 @@
return insets;
}
}
+ public void updateDoubleTapToSleep(boolean doubleTapToSleepEnabled) {
+ mDoubleTapToSleepEnabled = doubleTapToSleepEnabled;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java
index 42222d7..24c8277 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java
@@ -54,6 +54,7 @@
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.util.InjectionInflationController;
+import com.android.internal.util.bliss.LineageButtons;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -82,6 +83,7 @@
private final NotificationShadeWindowView mView;
private final ShadeController mShadeController;
private final NotificationShadeDepthController mDepthController;
+ private AmbientDisplayConfiguration mAmbientConfig;
private GestureDetector mGestureDetector;
private View mBrightnessMirror;
@@ -107,6 +109,8 @@
private RectF mTempRect = new RectF();
private boolean mIsTrackingBarGesture = false;
+ private boolean mIsMusicTickerTap;
+
@Inject
public NotificationShadeWindowViewController(
InjectionInflationController injectionInflationController,
@@ -154,6 +158,7 @@
// This view is not part of the newly inflated expanded status bar.
mBrightnessMirror = mView.findViewById(R.id.brightness_mirror);
+ mAmbientConfig = new AmbientDisplayConfiguration(mView.getContext());
}
/** Inflates the {@link R.layout#status_bar_expanded} layout and sets it up. */
@@ -161,15 +166,13 @@
mStackScrollLayout = mView.findViewById(R.id.notification_stack_scroller);
TunerService.Tunable tunable = (key, newValue) -> {
- AmbientDisplayConfiguration configuration =
- new AmbientDisplayConfiguration(mView.getContext());
switch (key) {
case Settings.Secure.DOZE_DOUBLE_TAP_GESTURE:
- mDoubleTapEnabled = configuration.doubleTapGestureEnabled(
+ mDoubleTapEnabled = mAmbientConfig.doubleTapGestureEnabled(
UserHandle.USER_CURRENT);
break;
case Settings.Secure.DOZE_TAP_SCREEN_GESTURE:
- mSingleTapEnabled = configuration.tapGestureEnabled(UserHandle.USER_CURRENT);
+ mSingleTapEnabled = mAmbientConfig.tapGestureEnabled(UserHandle.USER_CURRENT);
}
};
mTunerService.addTunable(tunable,
@@ -190,6 +193,12 @@
@Override
public boolean onDoubleTap(MotionEvent e) {
+ if (mIsMusicTickerTap) {
+ /* this gets called in pulsing Ambient screen,
+ for double taps on screen OFF or AoD check DozeTriggers onSlpiTap*/
+ LineageButtons.getAttachedInstance(mView.getContext()).skipTrack();
+ return true;
+ }
if (mDoubleTapEnabled || mSingleTapEnabled) {
mService.wakeUpIfDozing(
SystemClock.uptimeMillis(), mView, "DOUBLE_TAP");
@@ -287,10 +296,16 @@
@Override
public boolean shouldInterceptTouchEvent(MotionEvent ev) {
- if (mStatusBarStateController.isDozing() && !mService.isPulsing()
+ mIsMusicTickerTap = false;
+ if (mStatusBarStateController.isDozing()) {
+ if (!mAmbientConfig.deviceHasSoli() && mService.isDoubleTapOnMusicTicker(ev.getX(), ev.getY())) {
+ mIsMusicTickerTap = true;
+ }
+ if (!mService.isPulsing()
&& !mDockManager.isDocked()) {
- // Capture all touch events in always-on.
- return true;
+ // Capture all touch events in always-on.
+ return true;
+ }
}
boolean intercept = false;
if (mNotificationPanelViewController.isFullyExpanded()
@@ -481,4 +496,28 @@
mTempLocation[1] + view.getHeight());
return mTempRect.contains(x, y);
}
+ public void updateSettings() {
+ boolean doubleTapToSleepEnabled = Settings.System.getIntForUser(
+ mView.getContext().getContentResolver(), Settings.System.DOUBLE_TAP_SLEEP_GESTURE, 1,
+ UserHandle.USER_CURRENT) == 1;
+ boolean isDoubleTapEnabled = Settings.System.getIntForUser(
+ mView.getContext().getContentResolver(), Settings.System.DOUBLE_TAP_SLEEP_LOCKSCREEN, 1,
+ UserHandle.USER_CURRENT) == 1;
+ if (mNotificationPanelViewController != null) {
+ mNotificationPanelViewController.updateDoubleTapToSleep(doubleTapToSleepEnabled);
+ mNotificationPanelViewController.setLockscreenDoubleTapToSleep(isDoubleTapEnabled);
+ }
+ if (mDragDownHelper != null) {
+ mDragDownHelper.updateDoubleTapToSleep(doubleTapToSleepEnabled);
+ }
+ }
+
+ public void setStatusBarWindowViewOptions() {
+ int isQsQuickPulldown = Settings.System.getIntForUser(mView.getContext().getContentResolver(),
+ Settings.System.STATUS_BAR_QUICK_QS_PULLDOWN, 0, UserHandle.USER_CURRENT);
+ if (mNotificationPanelViewController != null) {
+ mNotificationPanelViewController.setQsQuickPulldown(isQsQuickPulldown);
+ }
+ }
+
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
index e942d85..98d90a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
@@ -151,6 +151,8 @@
protected final KeyguardStateController mKeyguardStateController;
protected final SysuiStatusBarStateController mStatusBarStateController;
+ protected boolean mDoubleTapToSleepEnabled;
+
protected void onExpandingFinished() {
mBar.onExpandingFinished();
}
@@ -407,7 +409,7 @@
&& !mStatusBar.isBouncerShowing()
&& !mKeyguardStateController.isKeyguardFadingAway()) {
long timePassed = SystemClock.uptimeMillis() - mDownTime;
- if (timePassed < ViewConfiguration.getLongPressTimeout()) {
+ if (timePassed < ViewConfiguration.getLongPressTimeout() && !mDoubleTapToSleepEnabled) {
// Lets show the user that he can actually expand the panel
runPeekAnimation(
PEEK_ANIMATION_DURATION, getPeekHeight(), true /* collapseWhenFinished */);
@@ -415,7 +417,7 @@
// We need to collapse the panel since we peeked to the small height.
mView.postOnAnimation(mPostCollapseRunnable);
}
- } else if (!mStatusBar.isBouncerShowing()) {
+ } else if (!mStatusBar.isBouncerShowing() && !mDoubleTapToSleepEnabled) {
boolean expands = onEmptySpaceClick(mInitialTouchX);
onTrackingStopped(expands);
}
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 4e71a7e..c2fbe3e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -22,6 +22,9 @@
import android.app.AlarmManager.AlarmClockInfo;
import android.app.IActivityManager;
import android.app.SynchronousUserSwitchObserver;
+import android.bluetooth.BluetoothClass;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothProfile;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -42,6 +45,7 @@
import androidx.lifecycle.Observer;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.systemui.R;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.qualifiers.DisplayId;
@@ -75,6 +79,7 @@
import java.io.PrintWriter;
import java.io.StringWriter;
+import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.Executor;
@@ -229,6 +234,7 @@
filter.addAction(AudioManager.ACTION_HEADSET_PLUG);
filter.addAction(Intent.ACTION_SIM_STATE_CHANGED);
+ filter.addAction(BluetoothDevice.ACTION_BATTERY_LEVEL_CHANGED);
filter.addAction(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED);
filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);
filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
@@ -440,16 +446,82 @@
if (mBluetooth.isBluetoothConnected()
&& (mBluetooth.isBluetoothAudioActive()
|| !mBluetooth.isBluetoothAudioProfileOnly())) {
- contentDescription = mResources.getString(
- R.string.accessibility_bluetooth_connected);
- bluetoothVisible = mBluetooth.isBluetoothEnabled();
- }
+ final Collection<CachedBluetoothDevice> devices = mBluetooth.getDevices();
+ if (devices != null) {
+ // get battery level for the first device with battery level support
+ for (CachedBluetoothDevice device : devices) {
+ // don't get the level if still pairing
+ if (mBluetooth.getBondState(device) == BluetoothDevice.BOND_NONE) continue;
+ int state = device.getMaxConnectionState();
+ if (state == BluetoothProfile.STATE_CONNECTED) {
+ int batteryLevel = device.getBatteryLevel();
+ BluetoothClass type = device.getBtClass();
+ if (batteryLevel != BluetoothDevice.BATTERY_LEVEL_UNKNOWN && showBatteryForThis(type)) {
+ iconId = getBtLevelIconRes(batteryLevel);
+ } else {
+ iconId = R.drawable.stat_sys_data_bluetooth_connected;
+ }
+ contentDescription = mResources.getString(
+ R.string.accessibility_bluetooth_connected);
+ break;
+ }
+ }
+ }
+ bluetoothVisible = mBluetooth.isBluetoothEnabled();
+ }
}
mIconController.setIcon(mSlotBluetooth, iconId, contentDescription);
mIconController.setIconVisibility(mSlotBluetooth, bluetoothVisible);
}
+ private int getBtLevelIconRes(int batteryLevel) {
+ if (batteryLevel == 100) {
+ return R.drawable.stat_sys_data_bluetooth_connected_battery_9;
+ } else if (batteryLevel >= 90) {
+ return R.drawable.stat_sys_data_bluetooth_connected_battery_8;
+ } else if (batteryLevel >= 80) {
+ return R.drawable.stat_sys_data_bluetooth_connected_battery_7;
+ } else if (batteryLevel >= 70) {
+ return R.drawable.stat_sys_data_bluetooth_connected_battery_6;
+ } else if (batteryLevel >= 60) {
+ return R.drawable.stat_sys_data_bluetooth_connected_battery_5;
+ } else if (batteryLevel >= 50) {
+ return R.drawable.stat_sys_data_bluetooth_connected_battery_4;
+ } else if (batteryLevel >= 40) {
+ return R.drawable.stat_sys_data_bluetooth_connected_battery_3;
+ } else if (batteryLevel >= 30) {
+ return R.drawable.stat_sys_data_bluetooth_connected_battery_2;
+ } else if (batteryLevel >= 20) {
+ return R.drawable.stat_sys_data_bluetooth_connected_battery_1;
+ } else if (batteryLevel >= 10) {
+ return R.drawable.stat_sys_data_bluetooth_connected_battery_0;
+ } else {
+ return R.drawable.stat_sys_data_bluetooth_connected;
+ }
+ }
+
+ private boolean showBatteryForThis(BluetoothClass type) {
+ boolean show = false;
+ if (type != null) {
+ switch (type.getDeviceClass()) {
+ case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET:
+ case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE:
+ case BluetoothClass.Device.AUDIO_VIDEO_PORTABLE_AUDIO:
+ case BluetoothClass.Device.AUDIO_VIDEO_LOUDSPEAKER:
+ case BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES:
+ show = true;
+ break;
+ default:
+ show = false;
+ break;
+ }
+ } else {
+ show = false;
+ }
+ return show;
+ }
+
private final void updateTTY() {
if (mTelecomManager == null) {
updateTTY(TelecomManager.TTY_MODE_OFF);
@@ -715,6 +787,9 @@
case AudioManager.ACTION_HEADSET_PLUG:
updateHeadsetPlug(intent);
break;
+ case BluetoothDevice.ACTION_BATTERY_LEVEL_CHANGED:
+ updateBluetooth();
+ break;
}
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java
index 2052ee6..610ac9c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java
@@ -31,7 +31,8 @@
private final float mIconAlphaWhenOpaque;
- private View mLeftSide, mStatusIcons, mBattery;
+ private View mLeftSide, mStatusIcons, mBattery, mClock, mCenterClock, mRightClock;
+
private Animator mCurrentAnimation;
/**
@@ -44,6 +45,9 @@
mLeftSide = statusBarView.findViewById(R.id.status_bar_left_side);
mStatusIcons = statusBarView.findViewById(R.id.statusIcons);
mBattery = statusBarView.findViewById(R.id.battery);
+ mClock = statusBarView.findViewById(R.id.clock);
+ mCenterClock = statusBarView.findViewById(R.id.center_clock);
+ mRightClock = statusBarView.findViewById(R.id.right_clock);
applyModeBackground(-1, getMode(), false /*animate*/);
applyMode(getMode(), false /*animate*/);
}
@@ -86,7 +90,10 @@
anims.playTogether(
animateTransitionTo(mLeftSide, newAlpha),
animateTransitionTo(mStatusIcons, newAlpha),
- animateTransitionTo(mBattery, newAlphaBC)
+ animateTransitionTo(mBattery, newAlphaBC),
+ animateTransitionTo(mClock, newAlphaBC),
+ animateTransitionTo(mCenterClock, newAlphaBC),
+ animateTransitionTo(mRightClock, newAlphaBC)
);
if (isLightsOut(mode)) {
anims.setDuration(LIGHTS_OUT_DURATION);
@@ -97,6 +104,9 @@
mLeftSide.setAlpha(newAlpha);
mStatusIcons.setAlpha(newAlpha);
mBattery.setAlpha(newAlphaBC);
+ mClock.setAlpha(newAlphaBC);
+ mCenterClock.setAlpha(newAlphaBC);
+ mRightClock.setAlpha(newAlphaBC);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickswitchOrientedNavHandle.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickswitchOrientedNavHandle.java
deleted file mode 100644
index fe74677..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickswitchOrientedNavHandle.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.phone;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.RectF;
-import android.view.Surface;
-
-import com.android.systemui.R;
-
-/** Temporarily shown view when using QuickSwitch to switch between apps of different rotations */
-public class QuickswitchOrientedNavHandle extends NavigationHandle {
- private final int mWidth;
- private final RectF mTmpBoundsRectF = new RectF();
- private @Surface.Rotation int mDeltaRotation;
-
- public QuickswitchOrientedNavHandle(Context context) {
- super(context);
- mWidth = context.getResources().getDimensionPixelSize(R.dimen.navigation_home_handle_width);
- }
-
- void setDeltaRotation(@Surface.Rotation int rotation) {
- mDeltaRotation = rotation;
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- canvas.drawRoundRect(computeHomeHandleBounds(), mRadius, mRadius, mPaint);
- }
-
- RectF computeHomeHandleBounds() {
- int left;
- int top;
- int bottom;
- int right;
- int radiusOffset = mRadius * 2;
- int topStart = getLocationOnScreen()[1];
-
- switch (mDeltaRotation) {
- default:
- case Surface.ROTATION_0:
- case Surface.ROTATION_180:
- int height = mRadius * 2;
- left = getWidth() / 2 - mWidth / 2;
- top = (getHeight() - mBottom - height);
- right = getWidth() / 2 + mWidth / 2;
- bottom = top + height;
- break;
- case Surface.ROTATION_90:
- left = mBottom;
- right = left + radiusOffset;
- top = getHeight() / 2 - (mWidth / 2) - (topStart / 2);
- bottom = top + mWidth;
- break;
- case Surface.ROTATION_270:
- right = getWidth() - mBottom;
- left = right - radiusOffset;
- top = getHeight() / 2 - (mWidth / 2) - (topStart / 2);
- bottom = top + mWidth;
- break;
- }
- mTmpBoundsRectF.set(left, top, right, bottom);
- return mTmpBoundsRectF;
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index f125b7d..c05226b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -67,12 +67,14 @@
import android.content.ComponentCallbacks2;
import android.content.ComponentName;
import android.content.Context;
+import android.database.ContentObserver;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
+import android.content.ContentResolver;
import android.graphics.Point;
import android.graphics.PointF;
import android.media.AudioAttributes;
@@ -81,6 +83,7 @@
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
+import android.os.Process;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
@@ -117,6 +120,7 @@
import android.view.WindowManagerGlobal;
import android.view.accessibility.AccessibilityManager;
import android.widget.DateTimeView;
+import android.database.ContentObserver;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner;
@@ -131,7 +135,14 @@
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.RegisterStatusBarResult;
+import com.android.internal.util.bliss.LineageButtons;
import com.android.internal.view.AppearanceRegion;
+import com.android.internal.util.hwkeys.ActionConstants;
+import com.android.internal.util.hwkeys.ActionUtils;
+import com.android.internal.util.hwkeys.PackageMonitor;
+import com.android.internal.util.hwkeys.PackageMonitor.PackageChangedListener;
+import com.android.internal.util.hwkeys.PackageMonitor.PackageState;
+import com.android.internal.util.bliss.BlissUtils;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.keyguard.ViewMediatorCallback;
@@ -156,6 +167,7 @@
import com.android.systemui.fragments.ExtensionFragmentListener;
import com.android.systemui.fragments.FragmentHostManager;
import com.android.systemui.keyguard.DismissCallbackRegistry;
+import com.android.systemui.keyguard.KeyguardSliceProvider;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.keyguard.WakefulnessLifecycle;
@@ -170,6 +182,8 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.QSFragment;
import com.android.systemui.qs.QSPanel;
+import com.android.systemui.qs.QuickQSPanel;
+import com.android.systemui.qs.QuickStatusBarHeader;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.ScreenPinningRequest;
import com.android.systemui.shared.plugins.PluginManager;
@@ -197,6 +211,7 @@
import com.android.systemui.statusbar.SuperStatusBarViewFactory;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.VibratorHelper;
+import com.android.systemui.statusbar.VisualizerView;
import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
@@ -220,6 +235,7 @@
import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
import com.android.systemui.statusbar.policy.ExtensionController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.statusbar.policy.FlashlightController;
import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
@@ -245,7 +261,8 @@
OnHeadsUpChangedListener, CommandQueue.Callbacks,
ColorExtractor.OnColorsChangedListener, ConfigurationListener,
StatusBarStateController.StateListener, ActivityLaunchAnimator.Callback,
- LifecycleOwner, BatteryController.BatteryStateChangeCallback {
+ LifecycleOwner, BatteryController.BatteryStateChangeCallback,
+ PackageChangedListener {
public static final boolean MULTIUSER_DEBUG = false;
protected static final int MSG_HIDE_RECENT_APPS = 1020;
@@ -402,6 +419,7 @@
// settings
private QSPanel mQSPanel;
+ private QuickQSPanel mQuickQSPanel;
KeyguardIndicationController mKeyguardIndicationController;
@@ -411,6 +429,7 @@
private final RemoteInputQuickSettingsDisabler mRemoteInputQuickSettingsDisabler;
private View mReportRejectedTouch;
+ private View mQSBarHeader;
private boolean mExpandedVisible;
@@ -436,6 +455,8 @@
private final DisplayMetrics mDisplayMetrics;
+ private PackageMonitor mPackageMonitor;
+
// XXX: gesture research
private final GestureRecorder mGestureRec = DEBUG_GESTURES
? new GestureRecorder("/sdcard/statusbar_gestures.dat")
@@ -527,6 +548,8 @@
private final NotificationRemoteInputManager mRemoteInputManager;
private boolean mWallpaperSupported;
+ private VisualizerView mVisualizerView;
+
private final BroadcastReceiver mWallpaperChangedReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -591,6 +614,7 @@
}
};
+ private FlashlightController mFlashlightController;
private KeyguardUserSwitcher mKeyguardUserSwitcher;
private final UserSwitcherController mUserSwitcherController;
private final NetworkController mNetworkController;
@@ -646,6 +670,36 @@
private ActivityIntentHelper mActivityIntentHelper;
+ private StatusBarSettingsObserver mStatusBarSettingsObserver = new StatusBarSettingsObserver(mHandler);
+ private class StatusBarSettingsObserver extends ContentObserver {
+ StatusBarSettingsObserver(Handler handler) {
+ super(handler);
+ }
+
+ void observe() {
+ mContext.getContentResolver().registerContentObserver(Settings.System.getUriFor(
+ Settings.System.DOUBLE_TAP_SLEEP_GESTURE),
+ false, this, UserHandle.USER_ALL);
+ mContext.getContentResolver().registerContentObserver(Settings.System.getUriFor(
+ Settings.System.DOUBLE_TAP_SLEEP_LOCKSCREEN),
+ false, this, UserHandle.USER_ALL);
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ update();
+ }
+
+ public void update() {
+ if (mNotificationShadeWindowViewController != null) {
+ mNotificationShadeWindowViewController.updateSettings();
+ }
+ setHeadsUpStoplist();
+ setHeadsUpBlacklist();
+ setStatusBarWindowViewOptions();
+ }
+ }
+
/**
* Public constructor for StatusBar.
*
@@ -731,7 +785,8 @@
KeyguardIndicationController keyguardIndicationController,
DismissCallbackRegistry dismissCallbackRegistry,
Lazy<NotificationShadeDepthController> notificationShadeDepthControllerLazy,
- StatusBarTouchableRegionManager statusBarTouchableRegionManager) {
+ StatusBarTouchableRegionManager statusBarTouchableRegionManager,
+ FlashlightController flashlightController) {
super(context);
mNotificationsController = notificationsController;
mLightBarController = lightBarController;
@@ -808,6 +863,7 @@
mUserInfoControllerImpl = userInfoControllerImpl;
mIconPolicy = phoneStatusBarPolicy;
mDismissCallbackRegistry = dismissCallbackRegistry;
+ mFlashlightController = flashlightController;
mBubbleExpandListener =
(isExpanding, key) -> {
@@ -840,6 +896,10 @@
mDisplayId = mDisplay.getDisplayId();
updateDisplaySize();
+ mPackageMonitor = new PackageMonitor();
+ mPackageMonitor.register(mContext, mHandler);
+ mPackageMonitor.addListener(this);
+
mVibrateOnOpening = mContext.getResources().getBoolean(
R.bool.config_vibrateOnIconAnimation);
@@ -871,6 +931,9 @@
createAndAddWindows(result);
+ mStatusBarSettingsObserver.observe();
+ mStatusBarSettingsObserver.update();
+
if (mWallpaperSupported) {
// Make sure we always have the most current wallpaper info.
IntentFilter wallpaperChangedFilter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED);
@@ -1163,6 +1226,8 @@
backdrop.setScaleY(scale);
});
+ mVisualizerView = (VisualizerView) mNotificationShadeWindowView.findViewById(R.id.visualizerview);
+
mNotificationPanelViewController.setUserSetupComplete(mUserSetup);
if (UserManager.get(mContext).isUserSwitcherEnabled()) {
createUserSwitcher();
@@ -1192,8 +1257,10 @@
fragmentHostManager.addTagListener(QS.TAG, (tag, f) -> {
QS qs = (QS) f;
if (qs instanceof QSFragment) {
+ mQSBarHeader = ((QSFragment) qs).getHeader();
mQSPanel = ((QSFragment) qs).getQsPanel();
mQSPanel.setBrightnessMirror(mBrightnessMirrorController);
+ mQuickQSPanel = ((QSFragment) qs).getQuickQsPanel();
}
});
}
@@ -1288,6 +1355,7 @@
filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG);
+ filter.addAction("android.intent.action.SCREEN_CAMERA_GESTURE");
mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter, null, UserHandle.ALL);
}
@@ -1643,7 +1711,7 @@
flagdbg.append(0 != ((state2 & StatusBarManager.DISABLE2_NOTIFICATION_SHADE)) ? 'N' : 'n');
flagdbg.append(0 != ((diff2 & StatusBarManager.DISABLE2_NOTIFICATION_SHADE)) ? '!' : ' ');
flagdbg.append('>');
- Log.d(TAG, flagdbg.toString());
+ if (DEBUG) Log.d(TAG, flagdbg.toString());
if ((diff1 & StatusBarManager.DISABLE_EXPAND) != 0) {
if ((state1 & StatusBarManager.DISABLE_EXPAND) != 0) {
@@ -1824,6 +1892,13 @@
return mDozeServiceHost.isPulsing();
}
+ public boolean isDoubleTapOnMusicTicker(float screenX, float screenY) {
+ if (mDozeServiceHost != null) {
+ return mDozeServiceHost.isDoubleTapOnMusicTicker(screenX, screenY);
+ }
+ return false;
+ }
+
public boolean hideStatusBarIconsWhenExpanded() {
return mNotificationPanelViewController.hideStatusBarIconsWhenExpanded();
}
@@ -1948,6 +2023,88 @@
mUserSetup = userSetup;
}
+ private BlissSettingsObserver mBlissSettingsObserver = new BlissSettingsObserver(mHandler);
+ private class BlissSettingsObserver extends ContentObserver {
+
+ BlissSettingsObserver(Handler handler) {
+ super(handler);
+ }
+
+ void observe() {
+ ContentResolver resolver = mContext.getContentResolver();
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.LOCKSCREEN_MEDIA_BLUR),
+ false, this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.PULSE_ON_NEW_TRACKS),
+ false, this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.HEADS_UP_STOPLIST_VALUES), false, this);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.HEADS_UP_BLACKLIST_VALUES), false, this);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.STATUS_BAR_QUICK_QS_PULLDOWN),
+ false, this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.QS_SHOW_BATTERY_PERCENT),
+ false, this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.LESS_BORING_HEADS_UP),
+ false, this, UserHandle.USER_ALL);
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ if (uri.equals(Settings.System.getUriFor(
+ Settings.System.LOCKSCREEN_MEDIA_BLUR))) {
+ setLockScreenMediaBlurLevel();
+ } else if (uri.equals(Settings.System.getUriFor(
+ Settings.System.PULSE_ON_NEW_TRACKS))) {
+ setPulseOnNewTracks();
+ } else if (uri.equals(Settings.System.getUriFor(
+ Settings.System.STATUS_BAR_QUICK_QS_PULLDOWN))) {
+ setStatusBarWindowViewOptions();
+ } else if (uri.equals(Settings.System.getUriFor(Settings.System.QS_SHOW_BATTERY_PERCENT))) {
+ setQsBatteryPercentMode();
+ }
+ update();
+ }
+
+ public void update() {
+ setLockScreenMediaBlurLevel();
+ setPulseOnNewTracks();
+ setQsBatteryPercentMode();
+ setUseLessBoringHeadsUp();
+ }
+ }
+
+ private void setQsBatteryPercentMode() {
+ if (mQSBarHeader != null) {
+ ((QuickStatusBarHeader) mQSBarHeader).setBatteryPercentMode();
+ }
+ }
+
+ private void setLockScreenMediaBlurLevel() {
+ if (mMediaManager != null) {
+ mMediaManager.setLockScreenMediaBlurLevel();
+ }
+ }
+
+ private void setPulseOnNewTracks() {
+ if (KeyguardSliceProvider.getAttachedInstance() != null) {
+ KeyguardSliceProvider.getAttachedInstance().setPulseOnNewTracks(Settings.System.getIntForUser(mContext.getContentResolver(),
+ Settings.System.PULSE_ON_NEW_TRACKS, 1,
+ UserHandle.USER_CURRENT) == 1);
+ }
+ }
+
+ private void setUseLessBoringHeadsUp() {
+ boolean lessBoringHeadsUp = Settings.System.getIntForUser(mContext.getContentResolver(),
+ Settings.System.LESS_BORING_HEADS_UP, 0,
+ UserHandle.USER_CURRENT) == 1;
+ mNotificationInterruptStateProvider.setUseLessBoringHeadsUp(lessBoringHeadsUp);
+ }
+
/**
* All changes to the status bar and notifications funnel through here and are batched.
*/
@@ -2051,6 +2208,41 @@
}
}
+ @Override
+ public void toggleCameraFlash(boolean proximityCheck) {
+ if (!proximityCheck ||
+ (!isScreenFullyOff() && mDeviceInteractive && !isPulsing() && !mDozing)) {
+ toggleFlashlight();
+ return;
+ }
+ mDozeServiceHost.toggleFlashlightProximityCheck();
+ }
+
+ public void toggleFlashlight() {
+ if (mFlashlightController != null) {
+ mFlashlightController.initFlashLight();
+ if (mFlashlightController.hasFlashlight() && mFlashlightController.isAvailable()) {
+ mFlashlightController.setFlashlight(!mFlashlightController.isEnabled());
+ }
+ }
+ }
+
+ // Elmyra app actions
+ @Override
+ public void triggerElmyraAction(String action) {
+ if (!isScreenFullyOff() && mDeviceInteractive && !isPulsing() && !mDozing) {
+ performTriggeredAction(action);
+ return;
+ }
+ mDozeServiceHost.triggerActionProximityCheck(action);
+ }
+
+ // Elmyra app actions
+ public void performTriggeredAction(String action) {
+ mVibrator.vibrate(VibrationEffect.createPredefined(VibrationEffect.EFFECT_HEAVY_CLICK));
+ LineageButtons.getAttachedInstance(mContext).performTriggeredAction(action, mContext, mDeviceInteractive);
+ }
+
void makeExpandedVisible(boolean force) {
if (SPEW) Log.d(TAG, "Make expanded visible: expanded visible=" + mExpandedVisible);
if (!force && (mExpandedVisible || !mCommandQueue.panelsEnabled())) {
@@ -2091,6 +2283,15 @@
}
@Override
+ public void toggleSettingsPanel() {
+ if (mPanelExpanded) {
+ mShadeController.animateCollapsePanels();
+ } else {
+ animateExpandSettingsPanel(null);
+ }
+ }
+
+ @Override
public void animateCollapsePanels(int flags, boolean force) {
mShadeController.animateCollapsePanels(flags, force, false /* delayed */,
1.0f /* speedUpFactor */);
@@ -2805,6 +3006,18 @@
else if (DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG.equals(action)) {
mQSPanel.showDeviceMonitoringDialog();
}
+ else if ("android.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;
+ }
+
+ onCameraLaunchGestureDetected(StatusBarManager.CAMERA_LAUNCH_SOURCE_SCREEN_GESTURE);
+ }
}
};
@@ -2922,6 +3135,9 @@
if (mBrightnessMirrorController != null) {
mBrightnessMirrorController.updateResources();
}
+ if (mQuickQSPanel != null) {
+ mQuickQSPanel.updateResources();
+ }
}
// Visibility reporting
@@ -3089,6 +3305,26 @@
startActivityDismissingKeyguard(intent, onlyProvisioned, true /* dismissShade */);
}
+ @Override
+ public void onPackageChanged(String pkg, PackageState state) {
+ if (state == PackageState.PACKAGE_REMOVED
+ || state == PackageState.PACKAGE_CHANGED) {
+ final Context ctx = mContext;
+ final Thread thread = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ if (!ActionUtils.hasNavbarByDefault(ctx)) {
+ ActionUtils.resolveAndUpdateButtonActions(ctx,
+ ActionConstants
+ .getDefaults(ActionConstants.HWKEYS));
+ }
+ }
+ });
+ thread.setPriority(Process.THREAD_PRIORITY_BACKGROUND);
+ thread.start();
+ }
+ }
+
private boolean mDemoModeAllowed;
private boolean mDemoMode;
@@ -3396,6 +3632,7 @@
public void keyguardGoingAway() {
// Treat Keyguard exit animation as an app transition to achieve nice transition for status
// bar.
+ mKeyguardIndicationController.setVisible(false);
mKeyguardStateController.notifyKeyguardGoingAway(true);
mCommandQueue.appTransitionPending(mDisplayId, true /* forced */);
}
@@ -3454,6 +3691,7 @@
|| (mDozing && mDozeServiceHost.shouldAnimateScreenOff() && visibleNotOccluded);
mNotificationPanelViewController.setDozing(mDozing, animate, mWakeUpTouchLocation);
+ mVisualizerView.setDozing(mDozing);
updateQsExpansionEnabled();
Trace.endSection();
}
@@ -3574,7 +3812,6 @@
mAmbientIndicationContainer.setVisibility(View.VISIBLE);
}
} else {
- mKeyguardIndicationController.setVisible(false);
if (mKeyguardUserSwitcher != null) {
mKeyguardUserSwitcher.setKeyguard(false,
mStatusBarStateController.goingToFullShade() ||
@@ -3589,6 +3826,7 @@
checkBarModes();
updateScrimController();
mPresenter.updateMediaMetaData(false, mState != StatusBarState.KEYGUARD);
+ mVisualizerView.setStatusBarState(newState);
updateKeyguardState();
Trace.endSection();
}
@@ -3630,6 +3868,8 @@
// the closing
mNotificationShadeWindowController.setNotificationShadeFocusable(true);
}
+ // It's closed; no need to leave it open.
+ mStatusBarStateController.setLeaveOpenOnKeyguardHide(false);
}
public void onUnlockHintStarted() {
@@ -3845,12 +4085,17 @@
@Override
public void onScreenTurnedOn() {
mScrimController.onScreenTurnedOn();
+ mVisualizerView.setVisible(true);
}
@Override
public void onScreenTurnedOff() {
mFalsingManager.onScreenOff();
mScrimController.onScreenTurnedOff();
+ if (mNotificationPanelViewController.isQsExpanded()) {
+ mNotificationPanelViewController.closeQs();
+ }
+ mVisualizerView.setVisible(false);
updateIsKeyguard();
}
};
@@ -3916,7 +4161,9 @@
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(TAG, "Camera launch");
@@ -4036,6 +4283,10 @@
Trace.endSection();
}
+ public VisualizerView getVisualizer() {
+ return mVisualizerView;
+ }
+
public boolean isKeyguardShowing() {
if (mStatusBarKeyguardViewManager == null) {
Slog.i(TAG, "isKeyguardShowing() called before startKeyguard(), returning true");
@@ -4100,6 +4351,22 @@
return mDeviceInteractive;
}
+ private void setHeadsUpStoplist() {
+ if (mPresenter != null)
+ mPresenter.setHeadsUpStoplist();
+ }
+
+ private void setHeadsUpBlacklist() {
+ if (mPresenter != null)
+ mPresenter.setHeadsUpBlacklist();
+ }
+
+ private void setStatusBarWindowViewOptions() {
+ if (mNotificationShadeWindowViewController != null) {
+ mNotificationShadeWindowViewController.setStatusBarWindowViewOptions();
+ }
+ }
+
private final BroadcastReceiver mBannerActionBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
index 93df14f..eaf398b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -19,6 +19,7 @@
import static com.android.systemui.statusbar.phone.StatusBarIconHolder.TYPE_ICON;
import static com.android.systemui.statusbar.phone.StatusBarIconHolder.TYPE_MOBILE;
+import static com.android.systemui.statusbar.phone.StatusBarIconHolder.TYPE_NETWORK_TRAFFIC;
import static com.android.systemui.statusbar.phone.StatusBarIconHolder.TYPE_WIFI;
import android.content.Context;
@@ -47,6 +48,7 @@
import com.android.systemui.statusbar.StatusIconDisplayable;
import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState;
import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState;
+import com.android.systemui.statusbar.policy.NetworkTrafficSB;
import com.android.systemui.util.Utils.DisableStateTracker;
import java.util.List;
@@ -144,8 +146,10 @@
@Override
public void onSetIcon(int viewIndex, StatusBarIcon icon) {
- super.onSetIcon(viewIndex, icon);
- mDarkIconDispatcher.applyDark((DarkReceiver) mGroup.getChildAt(viewIndex));
+ View view = mGroup.getChildAt(viewIndex);
+ if (view instanceof StatusBarIconView) {
+ ((StatusBarIconView) view).set(icon);
+ }
}
@Override
@@ -260,6 +264,9 @@
case TYPE_MOBILE:
return addMobileIcon(index, slot, holder.getMobileState());
+
+ case TYPE_NETWORK_TRAFFIC:
+ return addNetworkTraffic(index, slot);
}
return null;
@@ -286,6 +293,12 @@
return view;
}
+ protected NetworkTrafficSB addNetworkTraffic(int index, String slot) {
+ NetworkTrafficSB view = onCreateNetworkTraffic(slot);
+ mGroup.addView(view, index, onCreateLayoutParams());
+ return view;
+ }
+
@VisibleForTesting
protected StatusBarMobileView addMobileIcon(int index, String slot, MobileIconState state) {
StatusBarMobileView view = onCreateStatusBarMobileView(slot);
@@ -312,6 +325,13 @@
return view;
}
+ private NetworkTrafficSB onCreateNetworkTraffic(String slot) {
+ NetworkTrafficSB view = new NetworkTrafficSB(mContext);
+ view.setPadding(2, 0, 2, 0);
+ view.setGravity(Gravity.RIGHT | Gravity.CENTER_VERTICAL);
+ return view;
+ }
+
protected LinearLayout.LayoutParams onCreateLayoutParams() {
return new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, mIconSize);
}
@@ -353,8 +373,10 @@
}
public void onSetIcon(int viewIndex, StatusBarIcon icon) {
- StatusBarIconView view = (StatusBarIconView) mGroup.getChildAt(viewIndex);
- view.set(icon);
+ View view = mGroup.getChildAt(viewIndex);
+ if (view instanceof StatusBarIconView) {
+ ((StatusBarIconView) view).set(icon);
+ }
}
public void onSetIconHolder(int viewIndex, StatusBarIconHolder holder) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconHolder.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconHolder.java
index 88d0035..78dcb3a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconHolder.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconHolder.java
@@ -32,6 +32,7 @@
public static final int TYPE_ICON = 0;
public static final int TYPE_WIFI = 1;
public static final int TYPE_MOBILE = 2;
+ public static final int TYPE_NETWORK_TRAFFIC = 42;
private StatusBarIcon mIcon;
private WifiIconState mWifiState;
@@ -70,6 +71,12 @@
return holder;
}
+ public static StatusBarIconHolder fromNetworkTraffic() {
+ StatusBarIconHolder holder = new StatusBarIconHolder();
+ holder.mType = TYPE_NETWORK_TRAFFIC;
+ return holder;
+ }
+
public int getType() {
return mType;
}
@@ -105,6 +112,8 @@
return mWifiState.visible;
case TYPE_MOBILE:
return mMobileState.visible;
+ case TYPE_NETWORK_TRAFFIC:
+ return true;
default: return true;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java
index c876c32..4085582 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java
@@ -27,6 +27,8 @@
import java.util.ArrayList;
import java.util.List;
+import com.android.systemui.statusbar.policy.NetworkTrafficSB;
+
public class StatusBarIconList {
private ArrayList<Slot> mSlots = new ArrayList<>();
@@ -35,6 +37,8 @@
for (int i=0; i < N; i++) {
mSlots.add(new Slot(slots[i], null));
}
+ // Network traffic slot
+ mSlots.add(0, new Slot(NetworkTrafficSB.SLOT, StatusBarIconHolder.fromNetworkTraffic()));
}
public int getSlotIndex(String slot) {
@@ -45,8 +49,8 @@
return i;
}
}
- // Auto insert new items at the beginning.
- mSlots.add(0, new Slot(slot, null));
+ // Auto insert new items behind network traffic
+ mSlots.add(1, new Slot(slot, null));
return 0;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 81d0699..0c233f9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -116,6 +116,7 @@
@Override
public void onStartingToShow() {
+ updateStates();
updateLockIcon();
}
@@ -163,6 +164,7 @@
protected boolean mLastShowing;
protected boolean mLastOccluded;
private boolean mLastBouncerShowing;
+ private boolean mLastBouncerInTransit;
private boolean mLastBouncerDismissible;
protected boolean mLastRemoteInputActive;
private boolean mLastDozing;
@@ -544,6 +546,7 @@
mMediaManager.updateMediaMetaData(false, animate && !occluded);
}
mNotificationShadeWindowController.setKeyguardOccluded(occluded);
+ mStatusBar.getVisualizer().setOccluded(occluded);
// setDozing(false) will call reset once we stop dozing.
if (!mDozing) {
@@ -808,6 +811,7 @@
boolean showing = mShowing;
boolean occluded = mOccluded;
boolean bouncerShowing = mBouncer.isShowing();
+ boolean bouncerInTransit = mBouncer.inTransit();
boolean bouncerDismissible = !mBouncer.isFullscreenBouncer();
boolean remoteInputActive = mRemoteInputActive;
@@ -836,8 +840,11 @@
if ((showing && !occluded) != (mLastShowing && !mLastOccluded) || mFirstUpdate) {
mKeyguardUpdateManager.onKeyguardVisibilityChanged(showing && !occluded);
}
- if (bouncerShowing != mLastBouncerShowing || mFirstUpdate) {
- mKeyguardUpdateManager.sendKeyguardBouncerChanged(bouncerShowing);
+
+ boolean bouncerVisible = bouncerShowing || bouncerInTransit;
+ boolean lastBouncerVisible = mLastBouncerShowing || mLastBouncerInTransit;
+ if (bouncerVisible != lastBouncerVisible || mFirstUpdate) {
+ mKeyguardUpdateManager.sendKeyguardBouncerChanged(bouncerVisible);
}
mFirstUpdate = false;
@@ -845,6 +852,7 @@
mLastGlobalActionsVisible = mGlobalActionsVisible;
mLastOccluded = occluded;
mLastBouncerShowing = bouncerShowing;
+ mLastBouncerInTransit = bouncerInTransit;
mLastBouncerDismissible = bouncerDismissible;
mLastRemoteInputActive = remoteInputActive;
mLastDozing = mDozing;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
index 8e933a2..9256194 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
@@ -20,13 +20,18 @@
import static com.android.systemui.statusbar.phone.StatusBar.SPEW;
import android.annotation.Nullable;
+import android.app.ActivityManager;
import android.app.KeyguardManager;
+import android.content.ComponentName;
+import android.content.ContentResolver;
import android.content.Context;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.provider.Settings;
import android.service.notification.StatusBarNotification;
import android.service.vr.IVrManager;
import android.service.vr.IVrStateCallbacks;
+import android.text.TextUtils;
import android.util.Log;
import android.util.Slog;
import android.view.View;
@@ -76,6 +81,7 @@
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
+import java.util.ArrayList;
import java.util.List;
public class StatusBarNotificationPresenter implements NotificationPresenter,
@@ -129,6 +135,10 @@
protected boolean mVrMode;
private int mMaxKeyguardNotifications;
+ ActivityManager mAm;
+ private ArrayList<String> mStoplist = new ArrayList<String>();
+ private ArrayList<String> mBlacklist = new ArrayList<String>();
+
public StatusBarNotificationPresenter(Context context,
NotificationPanelViewController panel,
HeadsUpManagerPhone headsUp,
@@ -167,6 +177,7 @@
R.integer.keyguard_max_notification_count);
mBarService = IStatusBarService.Stub.asInterface(
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
+ mAm = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
if (MULTIUSER_DEBUG) {
mNotificationPanelDebugText = mNotificationPanel.getHeaderDebugInfo();
@@ -333,6 +344,42 @@
return mEntryManager.hasVisibleNotifications();
}
+ private boolean isPackageInStoplist(String packageName) {
+ return mStoplist.contains(packageName);
+ }
+ private boolean isPackageBlacklisted(String packageName) {
+ return mBlacklist.contains(packageName);
+ }
+ private boolean isDialerApp(String packageName) {
+ return packageName.equals("com.android.dialer")
+ || packageName.equals("com.google.android.dialer");
+ }
+ private void splitAndAddToArrayList(ArrayList<String> arrayList,
+ String baseString, String separator) {
+ // clear first
+ arrayList.clear();
+ if (baseString != null) {
+ final String[] array = TextUtils.split(baseString, separator);
+ for (String item : array) {
+ arrayList.add(item.trim());
+ }
+ }
+ }
+
+ @Override
+ public void setHeadsUpStoplist() {
+ final String stopString = Settings.System.getString(mContext.getContentResolver(),
+ Settings.System.HEADS_UP_STOPLIST_VALUES);
+ splitAndAddToArrayList(mStoplist, stopString, "\\|");
+ }
+
+ @Override
+ public void setHeadsUpBlacklist() {
+ final String blackString = Settings.System.getString(mContext.getContentResolver(),
+ Settings.System.HEADS_UP_BLACKLIST_VALUES);
+ splitAndAddToArrayList(mBlacklist, blackString, "\\|");
+ }
+
@Override
public void onUserSwitched(int newUserId) {
// Begin old BaseStatusBar.userSwitched
@@ -482,6 +529,20 @@
@Override
public boolean suppressAwakeHeadsUp(NotificationEntry entry) {
final StatusBarNotification sbn = entry.getSbn();
+ // get the info from the currently running task
+ List<ActivityManager.RunningTaskInfo> taskInfo = mAm.getRunningTasks(1);
+ if(taskInfo != null && !taskInfo.isEmpty()) {
+ ComponentName componentInfo = taskInfo.get(0).topActivity;
+ if(isPackageInStoplist(componentInfo.getPackageName())
+ && !isDialerApp(sbn.getPackageName())) {
+ return false;
+ }
+ }
+
+ if(isPackageBlacklisted(sbn.getPackageName())) {
+ return false;
+ }
+
if (mStatusBar.isOccluded()) {
boolean devicePublic = mLockscreenUserManager
.isLockscreenPublicMode(mLockscreenUserManager.getCurrentUserId());
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
index 02e0312..4abca28 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
@@ -92,6 +92,7 @@
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.ExtensionController;
+import com.android.systemui.statusbar.policy.FlashlightController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
@@ -198,7 +199,8 @@
KeyguardIndicationController keyguardIndicationController,
Lazy<NotificationShadeDepthController> notificationShadeDepthController,
DismissCallbackRegistry dismissCallbackRegistry,
- StatusBarTouchableRegionManager statusBarTouchableRegionManager) {
+ StatusBarTouchableRegionManager statusBarTouchableRegionManager,
+ FlashlightController flashlightController) {
return new StatusBar(
context,
notificationsController,
@@ -276,6 +278,7 @@
keyguardIndicationController,
dismissCallbackRegistry,
notificationShadeDepthController,
- statusBarTouchableRegionManager);
+ statusBarTouchableRegionManager,
+ flashlightController);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
index 78111fb..218b707 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
@@ -20,7 +20,11 @@
import android.content.res.Resources;
import android.util.ArraySet;
import android.view.LayoutInflater;
+import android.content.ContentResolver;
+import android.os.UserHandle;
+import android.provider.Settings;
import android.view.View;
+import android.widget.ImageView;
import android.widget.FrameLayout;
import com.android.systemui.R;
@@ -44,6 +48,7 @@
private final ArraySet<BrightnessMirrorListener> mBrightnessMirrorListeners = new ArraySet<>();
private final int[] mInt2Cache = new int[2];
private View mBrightnessMirror;
+ private ImageView mIcon;
public BrightnessMirrorController(NotificationShadeWindowView statusBarWindow,
NotificationPanelViewController notificationPanelViewController,
@@ -57,9 +62,11 @@
mBrightnessMirror.setVisibility(View.INVISIBLE);
});
mVisibilityCallback = visibilityCallback;
+ mIcon = (ImageView) mBrightnessMirror.findViewById(R.id.brightness_icon);
}
public void showMirror() {
+ updateIcon();
mBrightnessMirror.setVisibility(View.VISIBLE);
mVisibilityCallback.accept(true);
mNotificationPanel.setPanelAlpha(0, true /* animate */);
@@ -140,4 +147,19 @@
public interface BrightnessMirrorListener {
void onBrightnessMirrorReinflated(View brightnessMirror);
}
+
+ private void updateIcon() {
+ if (mIcon == null) {
+ return;
+ }
+ // enable the brightness icon
+ mIcon = (ImageView) mBrightnessMirror.findViewById(R.id.brightness_icon);
+ boolean automatic = Settings.System.getIntForUser(mBrightnessMirror.getContext().getContentResolver(),
+ Settings.System.SCREEN_BRIGHTNESS_MODE,
+ Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL,
+ UserHandle.USER_CURRENT) != Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL;
+ mIcon.setImageResource(automatic ?
+ com.android.systemui.R.drawable.ic_qs_brightness_auto_on :
+ com.android.systemui.R.drawable.ic_qs_brightness_auto_off);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
index da1ef2f..1c2c510 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
@@ -193,7 +193,7 @@
@Override
public void startCasting(CastDevice device) {
- if (device == null || device.tag == null) return;
+ if (device == null || !(device.tag instanceof RouteInfo)) return;
final RouteInfo route = (RouteInfo) device.tag;
if (DEBUG) Log.d(TAG, "startCasting: " + routeToString(route));
mMediaRouter.selectRoute(ROUTE_TYPE_REMOTE_DISPLAY, route);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
index 6dd96f92..6067fb7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
@@ -18,16 +18,19 @@
import android.app.StatusBarManager;
import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.TypedArray;
+import android.database.ContentObserver;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
import android.os.Parcelable;
import android.os.SystemClock;
import android.os.UserHandle;
+import android.provider.Settings;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.format.DateFormat;
@@ -48,25 +51,22 @@
import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
import com.android.systemui.settings.CurrentUserTracker;
import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
-import com.android.systemui.tuner.TunerService;
-import com.android.systemui.tuner.TunerService.Tunable;
import libcore.icu.LocaleData;
import java.text.SimpleDateFormat;
import java.util.Calendar;
+import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
/**
* Digital clock for the status bar.
*/
-public class Clock extends TextView implements DemoMode, Tunable, CommandQueue.Callbacks,
+public class Clock extends TextView implements DemoMode, CommandQueue.Callbacks,
DarkReceiver, ConfigurationListener {
- public static final String CLOCK_SECONDS = "clock_seconds";
private static final String CLOCK_SUPER_PARCELABLE = "clock_super_parcelable";
private static final String CURRENT_USER_ID = "current_user_id";
private static final String VISIBLE_BY_POLICY = "visible_by_policy";
@@ -78,25 +78,51 @@
private final CommandQueue mCommandQueue;
private int mCurrentUserId;
- private boolean mClockVisibleByPolicy = true;
- private boolean mClockVisibleByUser = true;
+ protected boolean mClockVisibleByPolicy = true;
+ protected boolean mClockVisibleByUser = true;
+ protected boolean mClockHideableByUser = true;
- private boolean mAttached;
+ protected boolean mAttached;
private boolean mScreenReceiverRegistered;
- private Calendar mCalendar;
- private String mClockFormatString;
- private SimpleDateFormat mClockFormat;
+ protected Calendar mCalendar;
+ protected String mClockFormatString;
+ protected SimpleDateFormat mClockFormat;
private SimpleDateFormat mContentDescriptionFormat;
- private Locale mLocale;
+ private boolean mScreenOn = true;
+ protected Locale mLocale;
- private static final int AM_PM_STYLE_NORMAL = 0;
- private static final int AM_PM_STYLE_SMALL = 1;
- private static final int AM_PM_STYLE_GONE = 2;
+ public static final int AM_PM_STYLE_GONE = 0;
+ public static final int AM_PM_STYLE_SMALL = 1;
+ public static final int AM_PM_STYLE_NORMAL = 2;
- private final int mAmPmStyle;
+ private static int AM_PM_STYLE = AM_PM_STYLE_GONE;
+
+ public static final int CLOCK_DATE_DISPLAY_GONE = 0;
+ public static final int CLOCK_DATE_DISPLAY_SMALL = 1;
+ public static final int CLOCK_DATE_DISPLAY_NORMAL = 2;
+
+ public static final int CLOCK_DATE_STYLE_REGULAR = 0;
+ public static final int CLOCK_DATE_STYLE_LOWERCASE = 1;
+ public static final int CLOCK_DATE_STYLE_UPPERCASE = 2;
+
+ public static final int STYLE_CLOCK_LEFT = 0;
+ public static final int STYLE_CLOCK_CENTER = 1;
+ public static final int STYLE_CLOCK_RIGHT = 2;
+ public static final int STYLE_DATE_LEFT = 0;
+ public static final int STYLE_DATE_RIGHT = 1;
+
+ protected int mClockDateDisplay = CLOCK_DATE_DISPLAY_GONE;
+ protected int mClockDateStyle = CLOCK_DATE_STYLE_REGULAR;
+ protected int mClockStyle = STYLE_CLOCK_LEFT;
+ protected String mClockDateFormat = null;
+ protected int mClockDatePosition;
+ protected boolean mShowClock = true;
+ private int mAmPmStyle;
private final boolean mShowDark;
+ protected boolean mQsHeader;
private boolean mShowSeconds;
private Handler mSecondsHandler;
+ private SettingsObserver mSettingsObserver;
/**
* Whether we should use colors that adapt based on wallpaper/the scrim behind quick settings
@@ -111,6 +137,46 @@
private final BroadcastDispatcher mBroadcastDispatcher;
+ protected class SettingsObserver extends ContentObserver {
+ SettingsObserver(Handler handler) {
+ super(handler);
+ }
+
+ void observe() {
+ ContentResolver resolver = mContext.getContentResolver();
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.STATUSBAR_CLOCK),
+ false, this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.STATUSBAR_CLOCK_STYLE),
+ false, this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.STATUSBAR_CLOCK_SECONDS),
+ false, this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.STATUSBAR_CLOCK_AM_PM_STYLE),
+ false, this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.STATUSBAR_CLOCK_DATE_DISPLAY),
+ false, this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.STATUSBAR_CLOCK_DATE_STYLE),
+ false, this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.STATUSBAR_CLOCK_DATE_FORMAT),
+ false, this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.STATUSBAR_CLOCK_DATE_POSITION),
+ false, this, UserHandle.USER_ALL);
+ updateSettings();
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ updateSettings();
+ }
+ }
+
public Clock(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
@@ -136,6 +202,7 @@
mCurrentUserId = newUserId;
}
};
+ updateSettings();
}
@Override
@@ -185,14 +252,14 @@
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
filter.addAction(Intent.ACTION_USER_SWITCHED);
+ filter.addAction(Intent.ACTION_SCREEN_ON);
+ filter.addAction(Intent.ACTION_SCREEN_OFF);
// NOTE: This receiver could run before this method returns, as it's not dispatching
// on the main thread and BroadcastDispatcher may not need to register with Context.
// The receiver will return immediately if the view does not have a Handler yet.
mBroadcastDispatcher.registerReceiverWithHandler(mIntentReceiver, filter,
Dependency.get(Dependency.TIME_TICK_HANDLER), UserHandle.ALL);
- Dependency.get(TunerService.class).addTunable(this, CLOCK_SECONDS,
- StatusBarIconController.ICON_BLACKLIST);
mCommandQueue.addCallback(this);
if (mShowDark) {
Dependency.get(DarkIconDispatcher.class).addDarkReceiver(this);
@@ -205,9 +272,11 @@
mCalendar = Calendar.getInstance(TimeZone.getDefault());
mClockFormatString = "";
- // Make sure we update to the current time
- updateClock();
- updateClockVisibility();
+ if (mSettingsObserver == null) {
+ mSettingsObserver = new SettingsObserver(new Handler());
+ }
+ mSettingsObserver.observe();
+ updateSettings();
updateShowSeconds();
}
@@ -224,8 +293,8 @@
}
if (mAttached) {
mBroadcastDispatcher.unregisterReceiver(mIntentReceiver);
+ getContext().getContentResolver().unregisterContentObserver(mSettingsObserver);
mAttached = false;
- Dependency.get(TunerService.class).removeTunable(this);
mCommandQueue.removeCallback(this);
if (mShowDark) {
Dependency.get(DarkIconDispatcher.class).removeDarkReceiver(this);
@@ -257,11 +326,21 @@
handler.post(() -> {
if (!newLocale.equals(mLocale)) {
mLocale = newLocale;
- mClockFormatString = ""; // force refresh
}
+ updateSettings();
+ return;
});
}
- handler.post(() -> updateClock());
+
+ if (action.equals(Intent.ACTION_SCREEN_ON)) {
+ mScreenOn = true;
+ } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
+ mScreenOn = false;
+ }
+
+ if (mScreenOn) {
+ handler.post(() -> updateClock());
+ }
}
};
@@ -275,8 +354,10 @@
}
public void setClockVisibleByUser(boolean visible) {
- mClockVisibleByUser = visible;
- updateClockVisibility();
+ if (mClockHideableByUser) {
+ mClockVisibleByUser = visible;
+ updateClockVisibility();
+ }
}
public void setClockVisibilityByPolicy(boolean visible) {
@@ -288,12 +369,21 @@
return mClockVisibleByPolicy && mClockVisibleByUser;
}
- private void updateClockVisibility() {
- boolean visible = shouldBeVisible();
+ protected void updateClockVisibility() {
+ boolean visible = ((mClockStyle == STYLE_CLOCK_LEFT) || (mQsHeader))
+ && mShowClock && mClockVisibleByPolicy && mClockVisibleByUser;
int visibility = visible ? View.VISIBLE : View.GONE;
super.setVisibility(visibility);
}
+ public boolean isClockVisible() {
+ return mClockVisibleByPolicy && mClockVisibleByUser;
+ }
+
+ public void setClockHideableByUser(boolean value) {
+ mClockHideableByUser = value;
+ }
+
final void updateClock() {
if (mDemoMode) return;
mCalendar.setTimeInMillis(System.currentTimeMillis());
@@ -302,18 +392,6 @@
}
@Override
- public void onTuningChanged(String key, String newValue) {
- if (CLOCK_SECONDS.equals(key)) {
- mShowSeconds = TunerService.parseIntegerSwitch(newValue, false);
- updateShowSeconds();
- } else {
- setClockVisibleByUser(!StatusBarIconController.getIconBlacklist(getContext(), newValue)
- .contains("clock"));
- updateClockVisibility();
- }
- }
-
- @Override
public void disable(int displayId, int state1, int state2, boolean animate) {
if (displayId != getDisplay().getDisplayId()) {
return;
@@ -437,13 +515,61 @@
} else {
sdf = mClockFormat;
}
- String result = sdf.format(mCalendar.getTime());
+
+ CharSequence dateString = null;
+
+ String result = "";
+ String timeResult = sdf.format(mCalendar.getTime());
+ String dateResult = "";
+
+ if (mClockDateDisplay != CLOCK_DATE_DISPLAY_GONE) {
+ Date now = new Date();
+
+ if (mClockDateFormat == null || mClockDateFormat.isEmpty()) {
+ // Set dateString to short uppercase Weekday if empty
+ dateString = DateFormat.format("EEE", now);
+ } else {
+ dateString = DateFormat.format(mClockDateFormat, now);
+ }
+ if (mClockDateStyle == CLOCK_DATE_STYLE_LOWERCASE) {
+ // When Date style is small, convert date to uppercase
+ dateResult = dateString.toString().toLowerCase();
+ } else if (mClockDateStyle == CLOCK_DATE_STYLE_UPPERCASE) {
+ dateResult = dateString.toString().toUpperCase();
+ } else {
+ dateResult = dateString.toString();
+ }
+ result = (mClockDatePosition == STYLE_DATE_LEFT) ? dateResult + " " + timeResult
+ : timeResult + " " + dateResult;
+ } else {
+ // No date, just show time
+ result = timeResult;
+ }
+
+ SpannableStringBuilder formatted = new SpannableStringBuilder(result);
+
+ if (mClockDateDisplay != CLOCK_DATE_DISPLAY_NORMAL) {
+ if (dateString != null) {
+ int dateStringLen = dateString.length();
+ int timeStringOffset = (mClockDatePosition == STYLE_DATE_RIGHT)
+ ? timeResult.length() + 1 : 0;
+ if (mClockDateDisplay == CLOCK_DATE_DISPLAY_GONE) {
+ formatted.delete(0, dateStringLen);
+ } else {
+ if (mClockDateDisplay == CLOCK_DATE_DISPLAY_SMALL) {
+ CharacterStyle style = new RelativeSizeSpan(0.7f);
+ formatted.setSpan(style, timeStringOffset,
+ timeStringOffset + dateStringLen,
+ Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
+ }
+ }
+ }
+ }
if (mAmPmStyle != AM_PM_STYLE_NORMAL) {
int magic1 = result.indexOf(MAGIC1);
int magic2 = result.indexOf(MAGIC2);
if (magic1 >= 0 && magic2 > magic1) {
- SpannableStringBuilder formatted = new SpannableStringBuilder(result);
if (mAmPmStyle == AM_PM_STYLE_GONE) {
formatted.delete(magic1, magic2+1);
} else {
@@ -455,12 +581,77 @@
formatted.delete(magic2, magic2 + 1);
formatted.delete(magic1, magic1 + 1);
}
- return formatted;
}
}
+ return formatted;
+ }
- return result;
+ private void updateStatus() {
+ if (mAttached) {
+ updateClock();
+ updateShowSeconds();
+ }
+ }
+ protected void updateSettings() {
+ ContentResolver resolver = mContext.getContentResolver();
+
+ mShowClock = Settings.System.getIntForUser(resolver,
+ Settings.System.STATUSBAR_CLOCK, 1,
+ UserHandle.USER_CURRENT) == 1;
+ if (mQsHeader) {
+ mShowClock = true; // QSHeader clock may override show clock
+ }
+
+ mShowSeconds = Settings.System.getIntForUser(resolver,
+ Settings.System.STATUSBAR_CLOCK_SECONDS, 0,
+ UserHandle.USER_CURRENT) == 1;
+
+ if (!mShowClock) {
+ mClockStyle = 1; // internally switch to centered clock layout because
+ // left & right will show up again after QS pulldown
+ } else {
+ mClockStyle = Settings.System.getIntForUser(resolver,
+ Settings.System.STATUSBAR_CLOCK_STYLE, STYLE_CLOCK_LEFT,
+ UserHandle.USER_CURRENT);
+ }
+
+ boolean is24hour = DateFormat.is24HourFormat(mContext);
+ int amPmStyle = Settings.System.getIntForUser(resolver,
+ Settings.System.STATUSBAR_CLOCK_AM_PM_STYLE,
+ AM_PM_STYLE_GONE,
+ UserHandle.USER_CURRENT);
+ mAmPmStyle = is24hour ? AM_PM_STYLE_GONE : amPmStyle;
+ mClockFormatString = "";
+
+ mClockDateDisplay = Settings.System.getIntForUser(resolver,
+ Settings.System.STATUSBAR_CLOCK_DATE_DISPLAY, CLOCK_DATE_DISPLAY_GONE,
+ UserHandle.USER_CURRENT);
+
+ mClockDateStyle = Settings.System.getIntForUser(resolver,
+ Settings.System.STATUSBAR_CLOCK_DATE_STYLE, CLOCK_DATE_STYLE_REGULAR,
+ UserHandle.USER_CURRENT);
+
+ mClockDateFormat = Settings.System.getString(resolver,
+ Settings.System.STATUSBAR_CLOCK_DATE_FORMAT);
+
+ mClockDatePosition = Settings.System.getIntForUser(resolver,
+ Settings.System.STATUSBAR_CLOCK_DATE_POSITION, STYLE_DATE_LEFT,
+ UserHandle.USER_CURRENT);
+
+ if (mAttached) {
+ updateClockVisibility();
+ updateClock();
+ updateShowSeconds();
+ }
+ }
+
+ public boolean isClockDateEnabled() {
+ return isClockVisible() && mClockDateDisplay != CLOCK_DATE_DISPLAY_GONE;
+ }
+
+ public void setQsHeader() {
+ mQsHeader = true;
}
private boolean mDemoMode;
@@ -520,4 +711,3 @@
}
};
}
-
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ClockCenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ClockCenter.java
new file mode 100644
index 0000000..b429865
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ClockCenter.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.policy;
+
+import android.app.StatusBarManager;
+import android.content.Context;
+import android.os.Handler;
+import android.util.AttributeSet;
+import android.view.View;
+
+import com.android.systemui.Dependency;
+
+public class ClockCenter extends Clock {
+
+ private boolean mClockVisibleByPolicy = true;
+ private boolean mClockVisibleByUser = true;
+
+ public ClockCenter(Context context) {
+ this(context, null);
+ }
+
+ public ClockCenter(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public ClockCenter(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ public void setClockVisibleByUser(boolean visible) {
+ mClockVisibleByUser = visible;
+ updateClockVisibility();
+ }
+
+ public void setClockVisibilityByPolicy(boolean visible) {
+ mClockVisibleByPolicy = visible;
+ updateClockVisibility();
+ }
+
+ protected void updateClockVisibility() {
+ boolean visible = mClockStyle == STYLE_CLOCK_CENTER && mShowClock
+ && mClockVisibleByPolicy && mClockVisibleByUser;
+ int visibility = visible ? View.VISIBLE : View.GONE;
+ setVisibility(visibility);
+ }
+
+ public void disable(int state1, int state2, boolean animate) {
+ boolean clockVisibleByPolicy = (state1 & StatusBarManager.DISABLE_CLOCK) == 0;
+ if (clockVisibleByPolicy != mClockVisibleByPolicy) {
+ setClockVisibilityByPolicy(clockVisibleByPolicy);
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ClockRight.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ClockRight.java
new file mode 100644
index 0000000..0765a53
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ClockRight.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.policy;
+
+import android.app.StatusBarManager;
+import android.content.Context;
+import android.os.Handler;
+import android.util.AttributeSet;
+import android.view.View;
+
+import com.android.systemui.Dependency;
+
+public class ClockRight extends Clock {
+
+ private boolean mClockVisibleByPolicy = true;
+ private boolean mClockVisibleByUser = true;
+
+ public ClockRight(Context context) {
+ this(context, null);
+ }
+
+ public ClockRight(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public ClockRight(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ public void setClockVisibleByUser(boolean visible) {
+ mClockVisibleByUser = visible;
+ updateClockVisibility();
+ }
+
+ public void setClockVisibilityByPolicy(boolean visible) {
+ mClockVisibleByPolicy = visible;
+ updateClockVisibility();
+ }
+
+ protected void updateClockVisibility() {
+ boolean visible = mClockStyle == STYLE_CLOCK_RIGHT && mShowClock
+ && mClockVisibleByPolicy && mClockVisibleByUser;
+ int visibility = visible ? View.VISIBLE : View.GONE;
+ setVisibility(visibility);
+ }
+
+ public void disable(int state1, int state2, boolean animate) {
+ boolean clockVisibleByPolicy = (state1 & StatusBarManager.DISABLE_CLOCK) == 0;
+ if (clockVisibleByPolicy != mClockVisibleByPolicy) {
+ setClockVisibilityByPolicy(clockVisibleByPolicy);
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java
index b4c154a..f588e4a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java
@@ -45,6 +45,8 @@
private String mDatePattern;
private final BroadcastDispatcher mBroadcastDispatcher;
+ private boolean mScreenOn = true;
+
private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -55,6 +57,12 @@
if (handler == null) return;
final String action = intent.getAction();
+ if (action.equals(Intent.ACTION_SCREEN_ON)) {
+ mScreenOn = true;
+ } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
+ mScreenOn = false;
+ }
+
if (Intent.ACTION_TIME_TICK.equals(action)
|| Intent.ACTION_TIME_CHANGED.equals(action)
|| Intent.ACTION_TIMEZONE_CHANGED.equals(action)
@@ -64,7 +72,9 @@
// need to get a fresh date format
handler.post(() -> mDateFormat = null);
}
- handler.post(() -> updateClock());
+ if (mScreenOn) {
+ handler.post(() -> updateClock());
+ }
}
}
};
@@ -92,6 +102,8 @@
super.onAttachedToWindow();
IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_SCREEN_ON);
+ filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_TIME_TICK);
filter.addAction(Intent.ACTION_TIME_CHANGED);
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java
index 54502e4..4789ef4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java
@@ -43,7 +43,7 @@
public static final int HORIZONTAL = 0; // Consume taps along the top edge.
public static final int VERTICAL = 1; // Consume taps along the left edge.
- private static final boolean CHATTY = true; // print to logcat when we eat a click
+ private static final boolean CHATTY = false; // print to logcat when we eat a click
private final NavigationBarController mNavBarController;
private final NavigationBarView mNavigationBarView;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java
index e576f36..4a93b37 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java
@@ -23,6 +23,7 @@
void setFlashlight(boolean newState);
boolean isAvailable();
boolean isEnabled();
+ void initFlashLight();
public interface FlashlightListener {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightControllerImpl.java
index 41ff9d10..1fd2f47 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightControllerImpl.java
@@ -90,6 +90,12 @@
}
}
+ public synchronized void initFlashLight() {
+ if (mCameraId == null) {
+ tryInitCamera();
+ }
+ }
+
public void setFlashlight(boolean enabled) {
boolean pendingError = false;
synchronized (this) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
index 82ad00a..4bb0d8b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
@@ -22,12 +22,18 @@
import android.annotation.Nullable;
import android.app.Notification;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.database.ContentObserver;
+import android.os.UserHandle;
import android.provider.Settings;
import android.util.ArrayMap;
import android.util.Log;
import android.view.accessibility.AccessibilityManager;
+import android.view.Gravity;
+import android.view.View;
+import android.widget.TextView;
+import android.widget.Toast;
import com.android.internal.logging.MetricsLogger;
import com.android.systemui.Dependency;
@@ -36,6 +42,8 @@
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag;
+import com.android.systemui.SysUIToast;
+
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.HashSet;
@@ -46,7 +54,6 @@
*/
public abstract class HeadsUpManager extends AlertingNotificationManager {
private static final String TAG = "HeadsUpManager";
- private static final String SETTING_HEADS_UP_SNOOZE_LENGTH_MS = "heads_up_snooze_length_ms";
protected final HashSet<OnHeadsUpChangedListener> mListeners = new HashSet<>();
@@ -65,30 +72,25 @@
mAccessibilityMgr = Dependency.get(AccessibilityManagerWrapper.class);
Resources resources = context.getResources();
mMinimumDisplayTime = resources.getInteger(R.integer.heads_up_notification_minimum_time);
- mAutoDismissNotificationDecay = resources.getInteger(R.integer.heads_up_notification_decay);
+ mAutoDismissNotificationDecay = Settings.System.getIntForUser(context.getContentResolver(),
+ Settings.System.HEADS_UP_TIMEOUT,
+ context.getResources().getInteger(R.integer.heads_up_notification_decay),
+ UserHandle.USER_CURRENT);
+ mSnoozeLengthMs = Settings.System.getIntForUser(context.getContentResolver(),
+ Settings.System.HEADS_UP_NOTIFICATION_SNOOZE,
+ context.getResources().getInteger(R.integer.heads_up_default_snooze_length_ms),
+ UserHandle.USER_CURRENT);
mTouchAcceptanceDelay = resources.getInteger(R.integer.touch_acceptance_delay);
mSnoozedPackages = new ArrayMap<>();
- int defaultSnoozeLengthMs =
- resources.getInteger(R.integer.heads_up_default_snooze_length_ms);
-
- mSnoozeLengthMs = Settings.Global.getInt(context.getContentResolver(),
- SETTING_HEADS_UP_SNOOZE_LENGTH_MS, defaultSnoozeLengthMs);
ContentObserver settingsObserver = new ContentObserver(mHandler) {
@Override
public void onChange(boolean selfChange) {
- final int packageSnoozeLengthMs = Settings.Global.getInt(
- context.getContentResolver(), SETTING_HEADS_UP_SNOOZE_LENGTH_MS, -1);
- if (packageSnoozeLengthMs > -1 && packageSnoozeLengthMs != mSnoozeLengthMs) {
- mSnoozeLengthMs = packageSnoozeLengthMs;
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "mSnoozeLengthMs = " + mSnoozeLengthMs);
- }
- }
+ mSnoozedPackages.clear();
}
};
context.getContentResolver().registerContentObserver(
- Settings.Global.getUriFor(SETTING_HEADS_UP_SNOOZE_LENGTH_MS), false,
- settingsObserver);
+ Settings.System.getUriFor(Settings.System.HEADS_UP_NOTIFICATION_SNOOZE), false,
+ settingsObserver, UserHandle.USER_ALL);
}
/**
@@ -209,6 +211,27 @@
String packageName = entry.mEntry.getSbn().getPackageName();
mSnoozedPackages.put(snoozeKey(packageName, mUser),
mClock.currentTimeMillis() + mSnoozeLengthMs);
+ if (mSnoozeLengthMs != 0) {
+ String appName = null;
+ try {
+ appName = (String) mContext.getPackageManager().getApplicationLabel(
+ mContext.getPackageManager().getApplicationInfo(packageName,
+ PackageManager.GET_META_DATA));
+ } catch (PackageManager.NameNotFoundException e) {
+ appName = packageName;
+ }
+ if (mSnoozeLengthMs == 60000) {
+ Toast toast = SysUIToast.makeText(mContext,
+ mContext.getString(R.string.heads_up_snooze_message_one_minute, appName),
+ Toast.LENGTH_LONG);
+ toast.show();
+ } else {
+ Toast toast = SysUIToast.makeText(mContext,
+ mContext.getString(R.string.heads_up_snooze_message, appName,
+ mSnoozeLengthMs / 60 / 1000), Toast.LENGTH_LONG);
+ toast.show();
+ }
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
index 8e8a285..380896e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
@@ -21,7 +21,8 @@
public interface LocationController extends CallbackController<LocationChangeCallback> {
boolean isLocationActive();
boolean isLocationEnabled();
- boolean setLocationEnabled(boolean enabled);
+ boolean setLocationEnabled(int mode);
+ int getCurrentMode();
/**
* A callback for change in location settings (the user has enabled/disabled location).
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
index 3bd33cc..dc0f4c5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
@@ -22,6 +22,7 @@
import android.app.AppOpsManager;
import android.app.StatusBarManager;
import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -114,21 +115,32 @@
*
* @return true if attempt to change setting was successful.
*/
- public boolean setLocationEnabled(boolean enabled) {
+ public boolean setLocationEnabled(int mode) {
// QuickSettings always runs as the owner, so specifically set the settings
// for the current foreground user.
int currentUserId = ActivityManager.getCurrentUser();
if (isUserLocationRestricted(currentUserId)) {
return false;
}
+ final ContentResolver cr = mContext.getContentResolver();
// When enabling location, a user consent dialog will pop up, and the
// setting won't be fully enabled until the user accepts the agreement.
- updateLocationEnabled(mContext, enabled, currentUserId,
- Settings.Secure.LOCATION_CHANGER_QUICK_SETTINGS);
+ Settings.Secure.putIntForUser(cr, Settings.Secure.LOCATION_MODE, mode,
+ currentUserId);
return true;
}
/**
+ * Returns the current location mode.
+ */
+ public int getCurrentMode() {
+ int currentUserId = ActivityManager.getCurrentUser();
+ final ContentResolver cr = mContext.getContentResolver();
+ return Settings.Secure.getIntForUser(cr, Settings.Secure.LOCATION_MODE,
+ Settings.Secure.LOCATION_MODE_OFF, currentUserId);
+ }
+
+ /**
* Returns true if location is enabled in settings. Will return false if
* {@link LocationManager} service has not been completely initialized
*/
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkTraffic.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkTraffic.java
new file mode 100644
index 0000000..a57975f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkTraffic.java
@@ -0,0 +1,469 @@
+/*
+ * Copyright (C) 2019 The PixelDust Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.policy;
+
+import java.text.DecimalFormat;
+
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Resources;
+import android.database.ContentObserver;
+import android.graphics.drawable.Drawable;
+import android.graphics.PorterDuff.Mode;
+import android.graphics.Rect;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.TrafficStats;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.os.Message;
+import android.os.SystemClock;
+import android.provider.Settings;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.View;
+import android.widget.TextView;
+
+import com.android.systemui.R;
+
+/*
+*
+* Seeing how an Integer object in java requires at least 16 Bytes, it seemed awfully wasteful
+* to only use it for a single boolean. 32-bits is plenty of room for what we need it to do.
+*
+*/
+public class NetworkTraffic extends TextView {
+
+ private static final int INTERVAL = 1500; //ms
+ private static final int BOTH = 0;
+ private static final int UP = 1;
+ private static final int DOWN = 2;
+ private static final int COMBINED = 3;
+ private static final int DYNAMIC = 4;
+ private static final int KB = 1024;
+ private static final int MB = KB * KB;
+ private static final int GB = MB * KB;
+ private static final String symbol = "B/s";
+
+ private static DecimalFormat decimalFormat = new DecimalFormat("##0.#");
+ static {
+ decimalFormat.setMaximumIntegerDigits(3);
+ decimalFormat.setMaximumFractionDigits(1);
+ }
+
+ private boolean mIsEnabled;
+ private boolean mAttached;
+ private long totalRxBytes;
+ private long totalTxBytes;
+ private long lastUpdateTime;
+ private int txtSize;
+ private int txtImgPadding;
+ private int mTrafficType;
+ private boolean mShowArrow;
+ private int mAutoHideThreshold;
+ private int mNetTrafSize;
+ private int mTintColor;
+ private boolean mTrafficVisible = false;
+ private boolean mScreenOn = true;
+ private boolean iBytes;
+ private boolean oBytes;
+
+ private boolean mTrafficInHeaderView;
+
+ private Handler mTrafficHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ long timeDelta = SystemClock.elapsedRealtime() - lastUpdateTime;
+
+ if (timeDelta < INTERVAL * .95) {
+ if (msg.what != 1) {
+ // we just updated the view, nothing further to do
+ return;
+ }
+ if (timeDelta < 1) {
+ // Can't div by 0 so make sure the value displayed is minimal
+ timeDelta = Long.MAX_VALUE;
+ }
+ }
+ lastUpdateTime = SystemClock.elapsedRealtime();
+
+ // Calculate the data rate from the change in total bytes and time
+ long newTotalRxBytes = TrafficStats.getTotalRxBytes();
+ long newTotalTxBytes = TrafficStats.getTotalTxBytes();
+ long rxData = newTotalRxBytes - totalRxBytes;
+ long txData = newTotalTxBytes - totalTxBytes;
+
+ iBytes = (rxData <= (mAutoHideThreshold * 1024));
+ oBytes = (txData <= (mAutoHideThreshold * 1024));
+
+ if (shouldHide(rxData, txData, timeDelta)) {
+ setText("");
+ mTrafficVisible = false;
+ } else {
+ String output;
+ if (mTrafficType == UP){
+ output = formatOutput(timeDelta, txData, symbol);
+ } else if (mTrafficType == DOWN){
+ output = formatOutput(timeDelta, rxData, symbol);
+ } else if (mTrafficType == BOTH) {
+ // Get information for uplink ready so the line return can be added
+ output = formatOutput(timeDelta, txData, symbol);
+ // Ensure text size is where it needs to be
+ output += "\n";
+ // Add information for downlink if it's called for
+ output += formatOutput(timeDelta, rxData, symbol);
+ } else if (mTrafficType == DYNAMIC) {
+ if (txData > rxData) {
+ output = formatOutput(timeDelta, txData, symbol);
+ if (!oBytes) {
+ oBytes = false;
+ iBytes = true;
+ } else {
+ oBytes = true;
+ iBytes = true;
+ }
+ } else {
+ output = formatOutput(timeDelta, rxData, symbol);
+ if (!iBytes) {
+ iBytes = false;
+ oBytes = true;
+ } else {
+ iBytes = true;
+ oBytes = true;
+ }
+ }
+ } else {
+ output = formatOutput(timeDelta, rxData + txData, symbol);
+ if (txData > rxData) {
+ if (!oBytes) {
+ oBytes = false;
+ iBytes = true;
+ } else {
+ oBytes = true;
+ iBytes = true;
+ }
+ } else {
+ if (!iBytes) {
+ iBytes = false;
+ oBytes = true;
+ } else {
+ iBytes = true;
+ oBytes = true;
+ }
+ }
+ }
+ // Update view if there's anything new to show
+ if (!output.contentEquals(getText())) {
+ setGravity(Gravity.RIGHT | Gravity.CENTER_VERTICAL);
+ setText(output);
+ }
+ mTrafficVisible = true;
+ }
+ updateVisibility();
+ updateTextSize();
+ if (mShowArrow)
+ updateTrafficDrawable();
+
+ // Post delayed message to refresh in ~1000ms
+ totalRxBytes = newTotalRxBytes;
+ totalTxBytes = newTotalTxBytes;
+ clearHandlerCallbacks();
+ mTrafficHandler.postDelayed(mRunnable, INTERVAL);
+ }
+
+ private String formatOutput(long timeDelta, long data, String symbol) {
+ long speed = (long)(data / (timeDelta / 1000F));
+ if (speed < KB) {
+ return decimalFormat.format(speed) + symbol;
+ } else if (speed < MB) {
+ return decimalFormat.format(speed / (float)KB) + 'K' + symbol;
+ } else if (speed < GB) {
+ return decimalFormat.format(speed / (float)MB) + 'M' + symbol;
+ }
+ return decimalFormat.format(speed / (float)GB) + 'G' + symbol;
+ }
+
+ private boolean shouldHide(long rxData, long txData, long timeDelta) {
+ long speedTxKB = (long)(txData / (timeDelta / 1000f)) / KB;
+ long speedRxKB = (long)(rxData / (timeDelta / 1000f)) / KB;
+ if (mTrafficType == UP) {
+ return !getConnectAvailable() || speedTxKB < mAutoHideThreshold;
+ } else if (mTrafficType == DOWN) {
+ return !getConnectAvailable() || speedRxKB < mAutoHideThreshold;
+ } else {
+ return !getConnectAvailable() ||
+ (speedRxKB < mAutoHideThreshold &&
+ speedTxKB < mAutoHideThreshold);
+ }
+ }
+ };
+
+ private Runnable mRunnable = new Runnable() {
+ @Override
+ public void run() {
+ mTrafficHandler.sendEmptyMessage(0);
+ }
+ };
+
+ class SettingsObserver extends ContentObserver {
+ SettingsObserver(Handler handler) {
+ super(handler);
+ }
+
+ void observe() {
+ ContentResolver resolver = mContext.getContentResolver();
+ resolver.registerContentObserver(Settings.System
+ .getUriFor(Settings.System.NETWORK_TRAFFIC_STATE), false,
+ this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System
+ .getUriFor(Settings.System.NETWORK_TRAFFIC_TYPE), false,
+ this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System
+ .getUriFor(Settings.System.NETWORK_TRAFFIC_AUTOHIDE_THRESHOLD), false,
+ this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System
+ .getUriFor(Settings.System.NETWORK_TRAFFIC_ARROW), false,
+ this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System
+ .getUriFor(Settings.System.NETWORK_TRAFFIC_VIEW_LOCATION), false,
+ this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System
+ .getUriFor(Settings.System.NETWORK_TRAFFIC_FONT_SIZE), false,
+ this, UserHandle.USER_ALL);
+ }
+
+ /*
+ * @hide
+ */
+ @Override
+ public void onChange(boolean selfChange) {
+ setMode();
+ updateSettings();
+ }
+ }
+
+ /*
+ * @hide
+ */
+ public NetworkTraffic(Context context) {
+ this(context, null);
+ }
+
+ /*
+ * @hide
+ */
+ public NetworkTraffic(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ /*
+ * @hide
+ */
+ public NetworkTraffic(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ final Resources resources = getResources();
+ txtSize = (mTrafficType == BOTH)
+ ? resources.getDimensionPixelSize(R.dimen.net_traffic_multi_text_size)
+ : mNetTrafSize;
+ txtImgPadding = resources.getDimensionPixelSize(R.dimen.net_traffic_txt_img_padding);
+ mTintColor = resources.getColor(android.R.color.white);
+ Handler mHandler = new Handler();
+ SettingsObserver settingsObserver = new SettingsObserver(mHandler);
+ settingsObserver.observe();
+ setMode();
+ updateSettings();
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ if (!mAttached) {
+ mAttached = true;
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
+ filter.addAction(Intent.ACTION_SCREEN_OFF);
+ filter.addAction(Intent.ACTION_SCREEN_ON);
+ mContext.registerReceiver(mIntentReceiver, filter, null, getHandler());
+ }
+ updateSettings();
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ if (mAttached) {
+ mContext.unregisterReceiver(mIntentReceiver);
+ mAttached = false;
+ }
+ }
+
+ private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (action == null) return;
+
+ if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION) && mScreenOn) {
+ updateSettings();
+ } else if (action.equals(Intent.ACTION_SCREEN_ON)) {
+ mScreenOn = true;
+ updateSettings();
+ } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
+ mScreenOn = false;
+ clearHandlerCallbacks();
+ }
+ }
+ };
+
+ private boolean getConnectAvailable() {
+ ConnectivityManager connManager =
+ (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkInfo network = (connManager != null) ? connManager.getActiveNetworkInfo() : null;
+ return network != null;
+ }
+
+ private void updateSettings() {
+ final ContentResolver resolver = getContext().getContentResolver();
+ mTrafficInHeaderView = Settings.System.getIntForUser(resolver,
+ Settings.System.NETWORK_TRAFFIC_VIEW_LOCATION, 0,
+ UserHandle.USER_CURRENT) == 1;
+ updateVisibility();
+ updateTextSize();
+ if (mIsEnabled) {
+ if (mAttached) {
+ totalRxBytes = TrafficStats.getTotalRxBytes();
+ lastUpdateTime = SystemClock.elapsedRealtime();
+ mTrafficHandler.sendEmptyMessage(1);
+ }
+ updateTrafficDrawable();
+ return;
+ } else {
+ clearHandlerCallbacks();
+ }
+ }
+
+ private void setMode() {
+ ContentResolver resolver = mContext.getContentResolver();
+ mIsEnabled = Settings.System.getIntForUser(resolver,
+ Settings.System.NETWORK_TRAFFIC_STATE, 0,
+ UserHandle.USER_CURRENT) == 1;
+ mTrafficType = Settings.System.getIntForUser(resolver,
+ Settings.System.NETWORK_TRAFFIC_TYPE, 0,
+ UserHandle.USER_CURRENT);
+ mAutoHideThreshold = Settings.System.getIntForUser(resolver,
+ Settings.System.NETWORK_TRAFFIC_AUTOHIDE_THRESHOLD, 0,
+ UserHandle.USER_CURRENT);
+ mShowArrow = Settings.System.getIntForUser(resolver,
+ Settings.System.NETWORK_TRAFFIC_ARROW, 1,
+ UserHandle.USER_CURRENT) == 1;
+ mTrafficInHeaderView = Settings.System.getIntForUser(resolver,
+ Settings.System.NETWORK_TRAFFIC_VIEW_LOCATION, 0,
+ UserHandle.USER_CURRENT) == 1;
+ mNetTrafSize = Settings.System.getIntForUser(resolver,
+ Settings.System.NETWORK_TRAFFIC_FONT_SIZE, 42,
+ UserHandle.USER_CURRENT);
+ }
+
+ private void clearHandlerCallbacks() {
+ mTrafficHandler.removeCallbacks(mRunnable);
+ mTrafficHandler.removeMessages(0);
+ mTrafficHandler.removeMessages(1);
+ }
+
+ private void updateTrafficDrawable() {
+ int intTrafficDrawable;
+ if (mIsEnabled && mShowArrow) {
+ if (mTrafficType == UP) {
+ if (oBytes) {
+ intTrafficDrawable = R.drawable.stat_sys_network_traffic;
+ } else {
+ intTrafficDrawable = R.drawable.stat_sys_network_traffic_up;
+ }
+ } else if (mTrafficType == DOWN) {
+ if (iBytes) {
+ intTrafficDrawable = R.drawable.stat_sys_network_traffic;
+ } else {
+ intTrafficDrawable = R.drawable.stat_sys_network_traffic_down;
+ }
+ } else if (mTrafficType == DYNAMIC || mTrafficType == COMBINED) {
+ if (iBytes && !oBytes) {
+ intTrafficDrawable = R.drawable.stat_sys_network_traffic_up;
+ } else if (!iBytes && oBytes) {
+ intTrafficDrawable = R.drawable.stat_sys_network_traffic_down;
+ } else {
+ intTrafficDrawable = R.drawable.stat_sys_network_traffic;
+ }
+ } else {
+ if (!iBytes && !oBytes) {
+ intTrafficDrawable = R.drawable.stat_sys_network_traffic_updown;
+ } else if (!oBytes) {
+ intTrafficDrawable = R.drawable.stat_sys_network_traffic_up;
+ } else if (!iBytes) {
+ intTrafficDrawable = R.drawable.stat_sys_network_traffic_down;
+ } else {
+ intTrafficDrawable = R.drawable.stat_sys_network_traffic;
+ }
+ }
+ } else {
+ intTrafficDrawable = 0;
+ }
+ if (intTrafficDrawable != 0 && mShowArrow) {
+ Drawable d = getContext().getDrawable(intTrafficDrawable);
+ d.setColorFilter(mTintColor, Mode.MULTIPLY);
+ setCompoundDrawablePadding(txtImgPadding);
+ setCompoundDrawablesWithIntrinsicBounds(null, null, d, null);
+ } else {
+ setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ }
+ setTextColor(mTintColor);
+ }
+
+ private void updateTextSize() {
+ if (mTrafficType == BOTH) {
+ txtSize = getResources().getDimensionPixelSize(R.dimen.net_traffic_multi_text_size);
+ } else {
+ txtSize = mNetTrafSize;
+ }
+ setTextSize(TypedValue.COMPLEX_UNIT_PX, (float)txtSize);
+ }
+
+ private void updateVisibility() {
+ if (mIsEnabled && mTrafficVisible && mTrafficInHeaderView) {
+ setVisibility(View.VISIBLE);
+ } else {
+ setText("");
+ setVisibility(View.GONE);
+ }
+ }
+
+ public void onDensityOrFontScaleChanged() {
+ final Resources resources = getResources();
+ txtSize = (mTrafficType == BOTH)
+ ? resources.getDimensionPixelSize(R.dimen.net_traffic_multi_text_size)
+ : mNetTrafSize;
+ txtImgPadding = resources.getDimensionPixelSize(R.dimen.net_traffic_txt_img_padding);
+ setTextSize(TypedValue.COMPLEX_UNIT_PX, (float)txtSize);
+ setCompoundDrawablePadding(txtImgPadding);
+ updateTextSize();
+ }
+}
+
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkTrafficSB.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkTrafficSB.java
new file mode 100644
index 0000000..cf6d432
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkTrafficSB.java
@@ -0,0 +1,535 @@
+/*
+ * Copyright (C) 2019 The PixelDust Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.policy;
+
+import static com.android.systemui.statusbar.StatusBarIconView.STATE_DOT;
+import static com.android.systemui.statusbar.StatusBarIconView.STATE_HIDDEN;
+import static com.android.systemui.statusbar.StatusBarIconView.STATE_ICON;
+
+import java.text.DecimalFormat;
+
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Resources;
+import android.database.ContentObserver;
+import android.graphics.drawable.Drawable;
+import android.graphics.PorterDuff.Mode;
+import android.graphics.Rect;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.TrafficStats;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.os.Message;
+import android.os.SystemClock;
+import android.provider.Settings;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.View;
+import android.widget.TextView;
+
+import com.android.systemui.Dependency;
+import com.android.systemui.R;
+import com.android.systemui.plugins.DarkIconDispatcher;
+import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
+import com.android.systemui.statusbar.StatusIconDisplayable;
+
+/*
+*
+* Seeing how an Integer object in java requires at least 16 Bytes, it seemed awfully wasteful
+* to only use it for a single boolean. 32-bits is plenty of room for what we need it to do.
+*
+*/
+public class NetworkTrafficSB extends TextView implements StatusIconDisplayable {
+
+ public static final String SLOT = "networktraffic";
+
+ private static final int INTERVAL = 1500; //ms
+ private static final int BOTH = 0;
+ private static final int UP = 1;
+ private static final int DOWN = 2;
+ private static final int COMBINED = 3;
+ private static final int DYNAMIC = 4;
+ private static final int KB = 1024;
+ private static final int MB = KB * KB;
+ private static final int GB = MB * KB;
+ private static final String symbol = "B/s";
+
+ private static DecimalFormat decimalFormat = new DecimalFormat("##0.#");
+ static {
+ decimalFormat.setMaximumIntegerDigits(3);
+ decimalFormat.setMaximumFractionDigits(1);
+ }
+
+ private boolean mIsEnabled;
+ private boolean mAttached;
+ private boolean mTrafficInHeaderView;
+ private long totalRxBytes;
+ private long totalTxBytes;
+ private long lastUpdateTime;
+ private int txtSize;
+ private int txtImgPadding;
+ private int mTrafficType;
+ private int mAutoHideThreshold;
+ private int mNetTrafSize;
+ private int mTintColor;
+ private int mVisibleState = -1;
+ private boolean mTrafficVisible = false;
+ private boolean mSystemIconVisible = true;
+ private boolean mShowArrow;
+
+ private boolean mScreenOn = true;
+ private boolean iBytes;
+ private boolean oBytes;
+
+ private Handler mTrafficHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ long timeDelta = SystemClock.elapsedRealtime() - lastUpdateTime;
+
+ if (timeDelta < INTERVAL * .95) {
+ if (msg.what != 1) {
+ // we just updated the view, nothing further to do
+ return;
+ }
+ if (timeDelta < 1) {
+ // Can't div by 0 so make sure the value displayed is minimal
+ timeDelta = Long.MAX_VALUE;
+ }
+ }
+ lastUpdateTime = SystemClock.elapsedRealtime();
+
+ // Calculate the data rate from the change in total bytes and time
+ long newTotalRxBytes = TrafficStats.getTotalRxBytes();
+ long newTotalTxBytes = TrafficStats.getTotalTxBytes();
+ long rxData = newTotalRxBytes - totalRxBytes;
+ long txData = newTotalTxBytes - totalTxBytes;
+
+ iBytes = (rxData <= (mAutoHideThreshold * 1024));
+ oBytes = (txData <= (mAutoHideThreshold * 1024));
+
+ if (shouldHide(rxData, txData, timeDelta)) {
+ setText("");
+ mTrafficVisible = false;
+ } else {
+ String output;
+ if (mTrafficType == UP){
+ output = formatOutput(timeDelta, txData, symbol);
+ } else if (mTrafficType == DOWN){
+ output = formatOutput(timeDelta, rxData, symbol);
+ } else if (mTrafficType == BOTH) {
+ // Get information for uplink ready so the line return can be added
+ output = formatOutput(timeDelta, txData, symbol);
+ // Ensure text size is where it needs to be
+ output += "\n";
+ // Add information for downlink if it's called for
+ output += formatOutput(timeDelta, rxData, symbol);
+ } else if (mTrafficType == DYNAMIC) {
+ if (txData > rxData) {
+ output = formatOutput(timeDelta, txData, symbol);
+ if (!oBytes) {
+ oBytes = false;
+ iBytes = true;
+ } else {
+ oBytes = true;
+ iBytes = true;
+ }
+ } else {
+ output = formatOutput(timeDelta, rxData, symbol);
+ if (!iBytes) {
+ iBytes = false;
+ oBytes = true;
+ } else {
+ iBytes = true;
+ oBytes = true;
+ }
+ }
+ } else {
+ output = formatOutput(timeDelta, rxData + txData, symbol);
+ if (txData > rxData) {
+ if (!oBytes) {
+ oBytes = false;
+ iBytes = true;
+ } else {
+ oBytes = true;
+ iBytes = true;
+ }
+ } else {
+ if (!iBytes) {
+ iBytes = false;
+ oBytes = true;
+ } else {
+ iBytes = true;
+ oBytes = true;
+ }
+ }
+ }
+ // Update view if there's anything new to show
+ if (!output.contentEquals(getText())) {
+ setGravity(Gravity.RIGHT | Gravity.CENTER_VERTICAL);
+ setText(output);
+ }
+ mTrafficVisible = true;
+ }
+ updateVisibility();
+ updateTextSize();
+ if (mShowArrow)
+ updateTrafficDrawable();
+
+ // Post delayed message to refresh in ~1000ms
+ totalRxBytes = newTotalRxBytes;
+ totalTxBytes = newTotalTxBytes;
+ clearHandlerCallbacks();
+ mTrafficHandler.postDelayed(mRunnable, INTERVAL);
+ }
+
+ private String formatOutput(long timeDelta, long data, String symbol) {
+ long speed = (long)(data / (timeDelta / 1000F));
+ if (speed < KB) {
+ return decimalFormat.format(speed) + symbol;
+ } else if (speed < MB) {
+ return decimalFormat.format(speed / (float)KB) + 'K' + symbol;
+ } else if (speed < GB) {
+ return decimalFormat.format(speed / (float)MB) + 'M' + symbol;
+ }
+ return decimalFormat.format(speed / (float)GB) + 'G' + symbol;
+ }
+
+ private boolean shouldHide(long rxData, long txData, long timeDelta) {
+ long speedTxKB = (long)(txData / (timeDelta / 1000f)) / KB;
+ long speedRxKB = (long)(rxData / (timeDelta / 1000f)) / KB;
+ if (mTrafficType == UP) {
+ return !getConnectAvailable() || speedTxKB < mAutoHideThreshold;
+ } else if (mTrafficType == DOWN) {
+ return !getConnectAvailable() || speedRxKB < mAutoHideThreshold;
+ } else {
+ return !getConnectAvailable() ||
+ (speedRxKB < mAutoHideThreshold &&
+ speedTxKB < mAutoHideThreshold);
+ }
+ }
+ };
+
+ private Runnable mRunnable = new Runnable() {
+ @Override
+ public void run() {
+ mTrafficHandler.sendEmptyMessage(0);
+ }
+ };
+
+ class SettingsObserver extends ContentObserver {
+ SettingsObserver(Handler handler) {
+ super(handler);
+ }
+
+ void observe() {
+ ContentResolver resolver = mContext.getContentResolver();
+ resolver.registerContentObserver(Settings.System
+ .getUriFor(Settings.System.NETWORK_TRAFFIC_STATE), false,
+ this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System
+ .getUriFor(Settings.System.NETWORK_TRAFFIC_TYPE), false,
+ this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System
+ .getUriFor(Settings.System.NETWORK_TRAFFIC_AUTOHIDE_THRESHOLD), false,
+ this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System
+ .getUriFor(Settings.System.NETWORK_TRAFFIC_ARROW), false,
+ this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System
+ .getUriFor(Settings.System.NETWORK_TRAFFIC_VIEW_LOCATION), false,
+ this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System
+ .getUriFor(Settings.System.NETWORK_TRAFFIC_FONT_SIZE), false,
+ this, UserHandle.USER_ALL);
+ }
+
+ /*
+ * @hide
+ */
+ @Override
+ public void onChange(boolean selfChange) {
+ setMode();
+ updateSettings();
+ }
+ }
+
+ /*
+ * @hide
+ */
+ public NetworkTrafficSB(Context context) {
+ this(context, null);
+ }
+
+ /*
+ * @hide
+ */
+ public NetworkTrafficSB(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ /*
+ * @hide
+ */
+ public NetworkTrafficSB(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ final Resources resources = getResources();
+ txtSize = (mTrafficType == BOTH)
+ ? resources.getDimensionPixelSize(R.dimen.net_traffic_multi_text_size)
+ : mNetTrafSize;
+ txtImgPadding = resources.getDimensionPixelSize(R.dimen.net_traffic_txt_img_padding);
+ mTintColor = resources.getColor(android.R.color.white);
+ Handler mHandler = new Handler();
+ SettingsObserver settingsObserver = new SettingsObserver(mHandler);
+ settingsObserver.observe();
+ setMode();
+ updateSettings();
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ if (!mAttached) {
+ mAttached = true;
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
+ filter.addAction(Intent.ACTION_SCREEN_OFF);
+ filter.addAction(Intent.ACTION_SCREEN_ON);
+ mContext.registerReceiver(mIntentReceiver, filter, null, getHandler());
+ }
+ Dependency.get(DarkIconDispatcher.class).addDarkReceiver(this);
+ updateSettings();
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ if (mAttached) {
+ mContext.unregisterReceiver(mIntentReceiver);
+ mAttached = false;
+ }
+ Dependency.get(DarkIconDispatcher.class).removeDarkReceiver(this);
+ }
+
+ private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (action == null) return;
+
+ if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION) && mScreenOn) {
+ updateSettings();
+ } else if (action.equals(Intent.ACTION_SCREEN_ON)) {
+ mScreenOn = true;
+ updateSettings();
+ } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
+ mScreenOn = false;
+ clearHandlerCallbacks();
+ }
+ }
+ };
+
+ private boolean getConnectAvailable() {
+ ConnectivityManager connManager =
+ (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkInfo network = (connManager != null) ? connManager.getActiveNetworkInfo() : null;
+ return network != null;
+ }
+
+ private void updateSettings() {
+ final ContentResolver resolver = getContext().getContentResolver();
+ mTrafficInHeaderView = Settings.System.getIntForUser(resolver,
+ Settings.System.NETWORK_TRAFFIC_VIEW_LOCATION, 0,
+ UserHandle.USER_CURRENT) == 1;
+ updateVisibility();
+ updateTextSize();
+ if (mIsEnabled) {
+ if (mAttached) {
+ totalRxBytes = TrafficStats.getTotalRxBytes();
+ lastUpdateTime = SystemClock.elapsedRealtime();
+ mTrafficHandler.sendEmptyMessage(1);
+ }
+ updateTrafficDrawable();
+ return;
+ } else {
+ clearHandlerCallbacks();
+ }
+ }
+
+ private void setMode() {
+ ContentResolver resolver = mContext.getContentResolver();
+ mIsEnabled = Settings.System.getIntForUser(resolver,
+ Settings.System.NETWORK_TRAFFIC_STATE, 0,
+ UserHandle.USER_CURRENT) == 1;
+ mTrafficType = Settings.System.getIntForUser(resolver,
+ Settings.System.NETWORK_TRAFFIC_TYPE, 0,
+ UserHandle.USER_CURRENT);
+ mAutoHideThreshold = Settings.System.getIntForUser(resolver,
+ Settings.System.NETWORK_TRAFFIC_AUTOHIDE_THRESHOLD, 0,
+ UserHandle.USER_CURRENT);
+ mShowArrow = Settings.System.getIntForUser(resolver,
+ Settings.System.NETWORK_TRAFFIC_ARROW, 1,
+ UserHandle.USER_CURRENT) == 1;
+ mTrafficInHeaderView = Settings.System.getIntForUser(resolver,
+ Settings.System.NETWORK_TRAFFIC_VIEW_LOCATION, 0,
+ UserHandle.USER_CURRENT) == 1;
+ mNetTrafSize = Settings.System.getIntForUser(resolver,
+ Settings.System.NETWORK_TRAFFIC_FONT_SIZE, 42,
+ UserHandle.USER_CURRENT);
+ }
+
+ private void clearHandlerCallbacks() {
+ mTrafficHandler.removeCallbacks(mRunnable);
+ mTrafficHandler.removeMessages(0);
+ mTrafficHandler.removeMessages(1);
+ }
+
+ private void updateTrafficDrawable() {
+ int intTrafficDrawable;
+ if (mIsEnabled && mShowArrow) {
+ if (mTrafficType == UP) {
+ if (oBytes) {
+ intTrafficDrawable = R.drawable.stat_sys_network_traffic;
+ } else {
+ intTrafficDrawable = R.drawable.stat_sys_network_traffic_up;
+ }
+ } else if (mTrafficType == DOWN) {
+ if (iBytes) {
+ intTrafficDrawable = R.drawable.stat_sys_network_traffic;
+ } else {
+ intTrafficDrawable = R.drawable.stat_sys_network_traffic_down;
+ }
+ } else if (mTrafficType == DYNAMIC || mTrafficType == COMBINED) {
+ if (iBytes && !oBytes) {
+ intTrafficDrawable = R.drawable.stat_sys_network_traffic_up;
+ } else if (!iBytes && oBytes) {
+ intTrafficDrawable = R.drawable.stat_sys_network_traffic_down;
+ } else {
+ intTrafficDrawable = R.drawable.stat_sys_network_traffic;
+ }
+ } else {
+ if (!iBytes && !oBytes) {
+ intTrafficDrawable = R.drawable.stat_sys_network_traffic_updown;
+ } else if (!oBytes) {
+ intTrafficDrawable = R.drawable.stat_sys_network_traffic_up;
+ } else if (!iBytes) {
+ intTrafficDrawable = R.drawable.stat_sys_network_traffic_down;
+ } else {
+ intTrafficDrawable = R.drawable.stat_sys_network_traffic;
+ }
+ }
+ } else {
+ intTrafficDrawable = 0;
+ }
+ if (intTrafficDrawable != 0 && mShowArrow) {
+ Drawable d = getContext().getDrawable(intTrafficDrawable);
+ d.setColorFilter(mTintColor, Mode.MULTIPLY);
+ setCompoundDrawablePadding(txtImgPadding);
+ setCompoundDrawablesWithIntrinsicBounds(null, null, d, null);
+ } else {
+ setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
+ }
+ setTextColor(mTintColor);
+ }
+
+ private void updateTextSize() {
+ if (mTrafficType == BOTH) {
+ txtSize = getResources().getDimensionPixelSize(R.dimen.net_traffic_multi_text_size);
+ } else {
+ txtSize = mNetTrafSize;
+ }
+ setTextSize(TypedValue.COMPLEX_UNIT_PX, (float)txtSize);
+ }
+
+ public void onDensityOrFontScaleChanged() {
+ final Resources resources = getResources();
+ txtSize = (mTrafficType == BOTH)
+ ? resources.getDimensionPixelSize(R.dimen.net_traffic_multi_text_size)
+ : mNetTrafSize;
+ txtImgPadding = resources.getDimensionPixelSize(R.dimen.net_traffic_txt_img_padding);
+ setCompoundDrawablePadding(txtImgPadding);
+ setTextSize(TypedValue.COMPLEX_UNIT_PX, (float)txtSize);
+ setGravity(Gravity.RIGHT);
+ updateTextSize();
+ }
+
+ @Override
+ public void onDarkChanged(Rect area, float darkIntensity, int tint) {
+ mTintColor = DarkIconDispatcher.getTint(area, this, tint);
+ setTextColor(mTintColor);
+ updateTrafficDrawable();
+ }
+
+ @Override
+ public String getSlot() {
+ return SLOT;
+ }
+
+ @Override
+ public boolean isIconVisible() {
+ return mIsEnabled;
+ }
+
+ @Override
+ public int getVisibleState() {
+ return mVisibleState;
+ }
+
+ @Override
+ public void setVisibleState(int state, boolean animate) {
+ if (state == mVisibleState) {
+ return;
+ }
+ mVisibleState = state;
+
+ switch (state) {
+ case STATE_ICON:
+ mSystemIconVisible = true;
+ break;
+ case STATE_DOT:
+ case STATE_HIDDEN:
+ default:
+ mSystemIconVisible = false;
+ break;
+ }
+ updateVisibility();
+ }
+
+ private void updateVisibility() {
+ if (mIsEnabled && mTrafficVisible && mSystemIconVisible && !mTrafficInHeaderView) {
+ setVisibility(View.VISIBLE);
+ } else {
+ setText("");
+ setVisibility(View.GONE);
+ }
+ }
+
+ @Override
+ public void setStaticDrawableColor(int color) {
+ mTintColor = color;
+ setTextColor(mTintColor);
+ updateTrafficDrawable();
+ }
+
+ @Override
+ public void setDecorColor(int color) {
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java
index 0ca6ff6..e90bd99 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java
@@ -119,7 +119,12 @@
mUserInfoTask.cancel(false);
mUserInfoTask = null;
}
- queryForUserInformation();
+
+ try {
+ queryForUserInformation();
+ } catch (Exception e) {
+ Log.e(TAG, "Couldn't query user info", e);
+ }
}
private void queryForUserInformation() {
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 0000000..bc9c438
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/tristate/TriStateUiController.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2019 CypherOS
+ * Copyright 2014-2020 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 0000000..b7f7ec1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/tristate/TriStateUiControllerImpl.java
@@ -0,0 +1,546 @@
+/*
+ * Copyright (C) 2019 CypherOS
+ * Copyright (C) 2020 Paranoid Android
+ * Copyright (C) 2020 crDroid Android 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.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.Color;
+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.ContextThemeWrapper;
+import android.view.Display;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager.LayoutParams;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+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.tuner.TunerService;
+
+public class TriStateUiControllerImpl implements TriStateUiController,
+ ConfigurationController.ConfigurationListener, TunerService.Tunable {
+
+
+ private static String TAG = "TriStateUiControllerImpl";
+
+ public static final String ALERT_SLIDER_NOTIFICATIONS =
+ "system:" + Settings.System.ALERT_SLIDER_NOTIFICATIONS;
+
+ 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 POSITION_TOP = 0;
+ private static final int POSITION_MIDDLE = 1;
+ private static final int POSITION_BOTTOM = 2;
+
+ private static final String EXTRA_SLIDER_POSITION = "position";
+
+ private static final int TRI_STATE_UI_POSITION_LEFT = 0;
+ private static final int TRI_STATE_UI_POSITION_RIGHT = 1;
+
+ private static final long DIALOG_TIMEOUT = 2000;
+ private static final long DIALOG_DELAY = 300;
+
+ private Context mContext;
+ private final VolumeDialogController mVolumeDialogController;
+ private final Callbacks mVolumeDialogCallback = new Callbacks() {
+ @Override
+ public void onShowRequested(int reason) { }
+
+ @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() {
+ mHandler.sendEmptyMessage(MSG_DIALOG_DISMISS);
+ initDialog();
+ }
+ };
+
+ private int mDensity;
+ private Dialog mDialog;
+ private int mDialogPosition;
+ private ViewGroup mDialogView;
+ private final H mHandler;
+ private UserActivityListener mListener;
+ private boolean mShowing = false;
+ private int mBackgroundColor = 0;
+ private ImageView mTriStateIcon;
+ private TextView mTriStateText;
+ private int mTriStateMode = -1;
+ private int mPosition = -1;
+ private Window mWindow;
+ private LayoutParams mWindowLayoutParams;
+ private int mWindowType;
+ private String mIntentAction;
+ private boolean mIntentActionSupported;
+ private boolean mRingModeChanged, mSliderPositionChanged;
+ private boolean mAlertSliderNotification;
+
+ private final BroadcastReceiver mRingerStateReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (!mAlertSliderNotification) {
+ mRingModeChanged = false;
+ mSliderPositionChanged = false;
+ return;
+ }
+
+ String action = intent.getAction();
+ if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) {
+ mHandler.sendEmptyMessage(MSG_DIALOG_DISMISS);
+ mHandler.sendEmptyMessage(MSG_STATE_CHANGE);
+ mRingModeChanged = true;
+ } else if (action.equals(mIntentAction)) {
+ mSliderPositionChanged = true;
+ mPosition = intent.getIntExtra(EXTRA_SLIDER_POSITION, -1);
+ }
+
+ if (mRingModeChanged && mAlertSliderNotification &&
+ (mSliderPositionChanged || !mIntentActionSupported)) {
+ mRingModeChanged = false;
+ mSliderPositionChanged = false;
+ if (mTriStateMode != -1) {
+ mHandler.sendEmptyMessageDelayed(MSG_DIALOG_SHOW, (long) DIALOG_DELAY);
+ }
+ }
+ }
+ };
+
+ 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 =
+ new ContextThemeWrapper(context, R.style.qs_theme);
+ mHandler = new H(this);
+ mVolumeDialogController = (VolumeDialogController) Dependency.get(VolumeDialogController.class);
+ mIntentAction = mContext.getResources().getString(com.android.internal.R.string.config_alertSliderIntent);
+ mIntentActionSupported = mIntentAction != null && !mIntentAction.isEmpty();
+
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
+ if (mIntentActionSupported)
+ filter.addAction(mIntentAction);
+ mContext.registerReceiver(mRingerStateReceiver, filter);
+
+ final TunerService tunerService = Dependency.get(TunerService.class);
+ tunerService.addTunable(this, ALERT_SLIDER_NOTIFICATIONS);
+ }
+
+ @Override
+ public void onTuningChanged(String key, String newValue) {
+ switch (key) {
+ case ALERT_SLIDER_NOTIFICATIONS:
+ mAlertSliderNotification
+ = TunerService.parseIntegerSwitch(newValue, true);
+ mHandler.sendEmptyMessage(MSG_DIALOG_DISMISS);
+ break;
+ default:
+ break;
+ }
+ }
+
+ @Override
+ public void onUiModeChanged() {
+ mContext.getTheme().applyStyle(mContext.getThemeResId(), true);
+ }
+
+ 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, R.style.qs_theme);
+ mShowing = false;
+ mWindow = mDialog.getWindow();
+ mWindow.requestFeature(Window.FEATURE_NO_TITLE);
+ mWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
+ mWindow.clearFlags(LayoutParams.FLAG_DIM_BEHIND
+ | LayoutParams.FLAG_LAYOUT_INSET_DECOR);
+ 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);
+ mWindow.setType(LayoutParams.TYPE_VOLUME_OVERLAY);
+ mWindow.setWindowAnimations(com.android.internal.R.style.Animation_Toast);
+ 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);
+ }
+
+ 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;
+ }
+
+ Display display = DisplayManagerGlobal.getInstance().getRealDisplay(0);
+ int orientationType = -1;
+ if (display != null) {
+ orientationType = display.getRotation();
+ }
+
+ switch (orientationType) {
+ 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 += res.getDimensionPixelSize(R.dimen.tri_state_position_padding_extra);
+ }
+ if (mPosition == POSITION_TOP) {
+ positionX = res.getDimensionPixelSize(R.dimen.tri_state_up_dialog_position_l);
+ } else if (mPosition == POSITION_MIDDLE) {
+ positionX = res.getDimensionPixelSize(R.dimen.tri_state_middle_dialog_position_l);
+ } else if (mPosition == POSITION_BOTTOM) {
+ positionX = res.getDimensionPixelSize(R.dimen.tri_state_down_dialog_position_l);
+ } else 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);
+ positionY = res.getDimensionPixelSize(R.dimen.tri_state_up_dialog_position)
+ + res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
+ if (mPosition >= 0) {
+ if (mPosition != POSITION_TOP) {
+ if (mPosition != POSITION_MIDDLE) {
+ if (mPosition == POSITION_BOTTOM) {
+ positionY = res.getDimensionPixelSize(R.dimen.tri_state_down_dialog_position)
+ + res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
+ }
+ bg = R.drawable.dialog_tri_state_middle_bg;
+ break;
+ }
+ positionY = res.getDimensionPixelSize(R.dimen.tri_state_middle_dialog_position)
+ + res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
+ }
+ } else if (mTriStateMode != MODE_SILENT) {
+ if (mTriStateMode != MODE_VIBRATE) {
+ if (mTriStateMode == MODE_NORMAL) {
+ positionY = res.getDimensionPixelSize(R.dimen.tri_state_down_dialog_position) + res.getDimensionPixelSize(R.dimen.tri_state_position_padding_extra);
+ }
+ bg = R.drawable.dialog_tri_state_middle_bg;
+ break;
+ }
+ positionY = res.getDimensionPixelSize(R.dimen.tri_state_middle_dialog_position) + res.getDimensionPixelSize(R.dimen.tri_state_position_padding_extra);
+ } else {
+ positionY = res.getDimensionPixelSize(R.dimen.tri_state_up_dialog_position) + res.getDimensionPixelSize(R.dimen.tri_state_position_padding_extra);
+ }
+ positionY2 = positionY;
+ bg = R.drawable.dialog_tri_state_middle_bg;
+ 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 += res.getDimensionPixelSize(R.dimen.tri_state_position_padding_extra);
+ }
+ if (mPosition == POSITION_TOP) {
+ positionX = res.getDimensionPixelSize(R.dimen.tri_state_up_dialog_position_l);
+ } else if (mPosition == POSITION_MIDDLE) {
+ positionX = res.getDimensionPixelSize(R.dimen.tri_state_middle_dialog_position_l);
+ } else if (mPosition == POSITION_BOTTOM) {
+ positionX = res.getDimensionPixelSize(R.dimen.tri_state_down_dialog_position_l);
+ } else 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 (mPosition >= 0) {
+ if (mPosition != POSITION_TOP) {
+ if (mPosition != POSITION_MIDDLE) {
+ if (mPosition == POSITION_BOTTOM) {
+ positionY2 = res.getDimensionPixelSize(R.dimen.tri_state_down_dialog_position)
+ + res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
+ bg = isTsKeyRight ? R.drawable.right_dialog_tri_state_down_bg : R.drawable.left_dialog_tri_state_down_bg;
+ break;
+ }
+ }
+ positionY2 = res.getDimensionPixelSize(R.dimen.tri_state_middle_dialog_position)
+ + res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
+ bg = R.drawable.dialog_tri_state_middle_bg;
+ break;
+ }
+ } else if (mTriStateMode != MODE_SILENT) {
+ if (mTriStateMode != MODE_VIBRATE) {
+ if (mTriStateMode == MODE_NORMAL) {
+ positionY2 = res.getDimensionPixelSize(R.dimen.tri_state_down_dialog_position) + res.getDimensionPixelSize(R.dimen.tri_state_position_padding_extra);
+ bg = isTsKeyRight ? R.drawable.right_dialog_tri_state_down_bg : R.drawable.left_dialog_tri_state_down_bg;
+ break;
+ }
+ }
+ positionY2 = res.getDimensionPixelSize(R.dimen.tri_state_middle_dialog_position) + res.getDimensionPixelSize(R.dimen.tri_state_position_padding_extra);
+ bg = R.drawable.dialog_tri_state_middle_bg;
+ break;
+ }
+ positionY2 = res.getDimensionPixelSize(R.dimen.tri_state_up_dialog_position) + res.getDimensionPixelSize(R.dimen.tri_state_position_padding_extra);
+ bg = isTsKeyRight ? R.drawable.right_dialog_tri_state_up_bg : R.drawable.left_dialog_tri_state_up_bg;
+ break;
+ }
+ if (mTriStateMode != -1) {
+ if (mTriStateIcon != null) {
+ mTriStateIcon.setImageResource(iconId);
+ }
+ if (mTriStateText != null) {
+ 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) {
+ mDialogView.setBackgroundDrawable(res.getDrawable(bg));
+ mBackgroundColor = getAttrColor(android.R.attr.colorPrimary);
+ mDialogView.setBackgroundTintList(ColorStateList.valueOf(mBackgroundColor));
+ }
+ 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);
+ mHandler.sendEmptyMessageDelayed(MSG_RESET_SCHEDULE, DIALOG_TIMEOUT);
+ }
+ }
+ }
+
+ private void handleShow() {
+ mHandler.removeMessages(MSG_DIALOG_SHOW);
+ if (!mShowing) {
+ updateTriStateLayout();
+ mShowing = true;
+ mDialog.show();
+ if (mListener != null) {
+ mListener.onTriStateUserActivity();
+ }
+ mHandler.sendEmptyMessageDelayed(MSG_RESET_SCHEDULE, DIALOG_TIMEOUT);
+ }
+ }
+
+ private void handleDismiss() {
+ mHandler.removeMessages(MSG_DIALOG_DISMISS);
+ if (mShowing) {
+ mShowing = false;
+ mDialog.dismiss();
+ }
+ }
+
+ private void handleStateChanged() {
+ mHandler.removeMessages(MSG_STATE_CHANGE);
+ AudioManager am = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+ int ringerMode = am.getRingerModeInternal();
+ if (ringerMode != mTriStateMode) {
+ mTriStateMode = ringerMode;
+ if (mListener != null) {
+ mListener.onTriStateUserActivity();
+ }
+ }
+ }
+
+ public void handleResetTimeout() {
+ mHandler.removeMessages(MSG_RESET_SCHEDULE);
+ mHandler.sendEmptyMessage(MSG_DIALOG_DISMISS);
+ if (mListener != null) {
+ mListener.onTriStateUserActivity();
+ }
+ }
+
+ @Override
+ public void onDensityOrFontScaleChanged() {
+ mHandler.sendEmptyMessage(MSG_DIALOG_DISMISS);
+ initDialog();
+ }
+
+ 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/tuner/ClockPreference.java b/packages/SystemUI/src/com/android/systemui/tuner/ClockPreference.java
deleted file mode 100644
index f7d0c9f..0000000
--- a/packages/SystemUI/src/com/android/systemui/tuner/ClockPreference.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2016 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.tuner;
-
-import android.content.Context;
-import android.text.TextUtils;
-import android.util.ArraySet;
-import android.util.AttributeSet;
-
-import androidx.preference.DropDownPreference;
-
-import com.android.systemui.Dependency;
-import com.android.systemui.statusbar.phone.StatusBarIconController;
-import com.android.systemui.statusbar.policy.Clock;
-
-public class ClockPreference extends DropDownPreference implements TunerService.Tunable {
-
- private static final String SECONDS = "seconds";
- private static final String DEFAULT = "default";
- private static final String DISABLED = "disabled";
-
- private final String mClock;
- private boolean mClockEnabled;
- private boolean mHasSeconds;
- private ArraySet<String> mBlacklist;
- private boolean mHasSetValue;
- private boolean mReceivedSeconds;
- private boolean mReceivedClock;
-
- public ClockPreference(Context context, AttributeSet attrs) {
- super(context, attrs);
- mClock = context.getString(com.android.internal.R.string.status_bar_clock);
- setEntryValues(new CharSequence[] { SECONDS, DEFAULT, DISABLED });
- }
-
- @Override
- public void onAttached() {
- super.onAttached();
- Dependency.get(TunerService.class).addTunable(this, StatusBarIconController.ICON_BLACKLIST,
- Clock.CLOCK_SECONDS);
- }
-
- @Override
- public void onDetached() {
- Dependency.get(TunerService.class).removeTunable(this);
- super.onDetached();
- }
-
- @Override
- public void onTuningChanged(String key, String newValue) {
- if (StatusBarIconController.ICON_BLACKLIST.equals(key)) {
- mReceivedClock = true;
- mBlacklist = StatusBarIconController.getIconBlacklist(getContext(), newValue);
- mClockEnabled = !mBlacklist.contains(mClock);
- } else if (Clock.CLOCK_SECONDS.equals(key)) {
- mReceivedSeconds = true;
- mHasSeconds = newValue != null && Integer.parseInt(newValue) != 0;
- }
- if (!mHasSetValue && mReceivedClock && mReceivedSeconds) {
- // Because of the complicated tri-state it can end up looping and setting state back to
- // what the user didn't choose. To avoid this, just set the state once and rely on the
- // preference to handle updates.
- mHasSetValue = true;
- if (mClockEnabled && mHasSeconds) {
- setValue(SECONDS);
- } else if (mClockEnabled) {
- setValue(DEFAULT);
- } else {
- setValue(DISABLED);
- }
- }
- }
-
- @Override
- protected boolean persistString(String value) {
- Dependency.get(TunerService.class).setValue(Clock.CLOCK_SECONDS, SECONDS.equals(value) ? 1
- : 0);
- if (DISABLED.equals(value)) {
- mBlacklist.add(mClock);
- } else {
- mBlacklist.remove(mClock);
- }
- Dependency.get(TunerService.class).setValue(StatusBarIconController.ICON_BLACKLIST,
- TextUtils.join(",", mBlacklist));
- return true;
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java
index 49ada1a..cbdcc29 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java
@@ -80,10 +80,10 @@
DemoMode.DEMO_MODE_ALLOWED), false, mDemoModeObserver);
contentResolver.registerContentObserver(Settings.Global.getUriFor(DEMO_MODE_ON), false,
mDemoModeObserver);
- setHasOptionsMenu(true);
+ //setHasOptionsMenu(true);
}
- @Override
+ /*@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
@@ -91,7 +91,7 @@
break;
}
return super.onOptionsItemSelected(item);
- }
+ }*/
@Override
public void onResume() {
@@ -215,4 +215,10 @@
updateDemoModeOn();
};
};
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ getActivity().getActionBar().setDisplayHomeAsUpEnabled(true);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/StatusBarTuner.java b/packages/SystemUI/src/com/android/systemui/tuner/StatusBarTuner.java
new file mode 100644
index 0000000..3552ea0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/tuner/StatusBarTuner.java
@@ -0,0 +1,61 @@
+/*
+ * 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.tuner;
+
+import android.os.Bundle;
+import android.view.MenuItem;
+
+import androidx.preference.PreferenceFragment;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.systemui.R;
+
+public class StatusBarTuner extends PreferenceFragment {
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ setHasOptionsMenu(true);
+ getActivity().getActionBar().setDisplayHomeAsUpEnabled(true);
+ }
+
+ @Override
+ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
+ addPreferencesFromResource(R.xml.status_bar_prefs);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ MetricsLogger.visibility(getContext(), MetricsEvent.TUNER, true);
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ MetricsLogger.visibility(getContext(), MetricsEvent.TUNER, false);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (item.getItemId() == android.R.id.home) {
+ getActivity().onBackPressed();
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java
index 453c2f7..96027ab 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java
@@ -59,10 +59,19 @@
if (getFragmentManager().findFragmentByTag(TAG_TUNER) == null) {
final String action = getIntent().getAction();
- boolean showDemoMode = action != null && action.equals(
- "com.android.settings.action.DEMO_MODE");
- final PreferenceFragment fragment = showDemoMode ? new DemoModeFragment()
- : new TunerFragment();
+ final Fragment fragment;
+ if ("com.android.settings.action.DEMO_MODE".equals(action)) {
+ fragment = new DemoModeFragment();
+ } else if ("com.android.settings.action.NAV_BAR_TUNER".equals(action)) {
+ fragment = new NavBarTuner();
+ } else if ("com.android.settings.action.POWER_NOTIF_CONTROLS".equals(action)) {
+ fragment = new PowerNotificationControlsFragment();
+ } else if ("com.android.settings.action.STATUS_BAR_TUNER".equals(action)) {
+ fragment = new StatusBarTuner();
+ } else {
+ fragment = new TunerFragment();
+ }
+
getFragmentManager().beginTransaction().replace(R.id.content_frame,
fragment, TAG_TUNER).commit();
}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
index 0070dcf..d9be7f8 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
@@ -73,22 +73,15 @@
if (!PluginPrefs.hasPlugins(getContext())) {
getPreferenceScreen().removePreference(findPreference(KEY_PLUGINS));
}
- if (!alwaysOnAvailable()) {
+ /*if (!alwaysOnAvailable()) {
getPreferenceScreen().removePreference(findPreference(KEY_DOZE));
- }
- if (!Build.IS_DEBUGGABLE) {
+ }*/
+ /*if (!Build.IS_DEBUGGABLE) {
for (int i = 0; i < DEBUG_ONLY.length; i++) {
Preference preference = findPreference(DEBUG_ONLY[i]);
if (preference != null) getPreferenceScreen().removePreference(preference);
}
- }
-
- if (Settings.Secure.getInt(getContext().getContentResolver(), SETTING_SEEN_TUNER_WARNING,
- 0) == 0) {
- if (getFragmentManager().findFragmentByTag(WARNING_TAG) == null) {
- new TunerWarningFragment().show(getFragmentManager(), WARNING_TAG);
- }
- }
+ }*/
}
private boolean alwaysOnAvailable() {
@@ -135,7 +128,7 @@
return super.onOptionsItemSelected(item);
}
- public static class TunerWarningFragment extends DialogFragment {
+ /*public static class TunerWarningFragment extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getContext())
@@ -149,5 +142,5 @@
}
}).show();
}
- }
+ }*/
}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java
index 338e178..c21d0a7 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java
@@ -98,8 +98,8 @@
// Disable access to tuner.
TunerService.setTunerEnabled(context, false);
// Make them sit through the warning dialog again.
- Settings.Secure.putInt(context.getContentResolver(),
- TunerFragment.SETTING_SEEN_TUNER_WARNING, 0);
+ /*Settings.Secure.putInt(context.getContentResolver(),
+ TunerFragment.SETTING_SEEN_TUNER_WARNING, 0);*/
if (onDisabled != null) {
onDisabled.run();
}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
index 9ad2aa2..65f872e 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
@@ -107,6 +107,7 @@
}
};
mUserTracker.startTracking();
+ setTunerEnabled(mContext, true);
}
@Override
@@ -142,31 +143,82 @@
setValue(TUNER_VERSION, newVersion);
}
+ private boolean isSystem(String key) {
+ return key.startsWith("system:");
+ }
+
+ private boolean isGlobal(String key) {
+ return key.startsWith("global:");
+ }
+
+ private String chomp(String key) {
+ return key.replaceFirst("^(system|global):", "");
+ }
+
@Override
public String getValue(String setting) {
- return Settings.Secure.getStringForUser(mContentResolver, setting, mCurrentUser);
+ if (isSystem(setting)) {
+ return Settings.System.getStringForUser(
+ mContentResolver, chomp(setting), mCurrentUser);
+ } else if (isGlobal(setting)) {
+ return Settings.Global.getStringForUser(
+ mContentResolver, chomp(setting), mCurrentUser);
+ } else {
+ return Settings.Secure.getStringForUser(mContentResolver, setting, mCurrentUser);
+ }
}
@Override
public void setValue(String setting, String value) {
- Settings.Secure.putStringForUser(mContentResolver, setting, value, mCurrentUser);
+ if (isSystem(setting)) {
+ Settings.System.putStringForUser(
+ mContentResolver, chomp(setting), value, mCurrentUser);
+ } else if (isGlobal(setting)) {
+ Settings.Global.putStringForUser(
+ mContentResolver, chomp(setting), value, mCurrentUser);
+ } else {
+ Settings.Secure.putStringForUser(mContentResolver, setting, value, mCurrentUser);
+ }
}
@Override
public int getValue(String setting, int def) {
- return Settings.Secure.getIntForUser(mContentResolver, setting, def, mCurrentUser);
+ if (isSystem(setting)) {
+ return Settings.System.getIntForUser(
+ mContentResolver, chomp(setting), def, mCurrentUser);
+ } else if (isGlobal(setting)) {
+ return Settings.Global.getInt(
+ mContentResolver, chomp(setting), def);
+ } else {
+ return Settings.Secure.getIntForUser(mContentResolver, setting, def, mCurrentUser);
+ }
}
@Override
public String getValue(String setting, String def) {
- String ret = Secure.getStringForUser(mContentResolver, setting, mCurrentUser);
+ String ret;
+ if (isSystem(setting)) {
+ ret = Settings.System.getStringForUser(
+ mContentResolver, chomp(setting), mCurrentUser);
+ } else if (isGlobal(setting)) {
+ ret = Settings.Global.getStringForUser(
+ mContentResolver, chomp(setting), mCurrentUser);
+ } else {
+ ret = Secure.getStringForUser(mContentResolver, setting, mCurrentUser);
+ }
if (ret == null) return def;
return ret;
}
@Override
public void setValue(String setting, int value) {
- Settings.Secure.putIntForUser(mContentResolver, setting, value, mCurrentUser);
+ if (isSystem(setting)) {
+ Settings.System.putIntForUser(mContentResolver, chomp(setting), value, mCurrentUser);
+ } else if (isGlobal(setting)) {
+ Settings.Global.putInt(mContentResolver, chomp(setting), value);
+ } else {
+ Settings.Secure.putIntForUser(mContentResolver, setting, value, mCurrentUser);
+ }
}
@Override
@@ -185,14 +237,20 @@
mTunables.add(tunable);
mLeakDetector.trackCollection(mTunables, "TunerService.mTunables");
}
- Uri uri = Settings.Secure.getUriFor(key);
+ final Uri uri;
+ if (isSystem(key)) {
+ uri = Settings.System.getUriFor(chomp(key));
+ } else if (isGlobal(key)) {
+ uri = Settings.Global.getUriFor(chomp(key));
+ } else {
+ uri = Settings.Secure.getUriFor(key);
+ }
if (!mListeningUris.containsKey(uri)) {
mListeningUris.put(uri, key);
mContentResolver.registerContentObserver(uri, false, mObserver, mCurrentUser);
}
// Send the first state.
- String value = DejankUtils.whitelistIpcs(() -> Settings.Secure
- .getStringForUser(mContentResolver, key, mCurrentUser));
+ String value = DejankUtils.whitelistIpcs(() -> getValue(key));
tunable.onTuningChanged(key, value);
}
@@ -222,18 +280,21 @@
if (tunables == null) {
return;
}
- String value = Settings.Secure.getStringForUser(mContentResolver, key, mCurrentUser);
+ String value = getValue(key);
for (Tunable tunable : tunables) {
- tunable.onTuningChanged(key, value);
+ if (tunable != null) {
+ tunable.onTuningChanged(key, value);
+ }
}
}
private void reloadAll() {
for (String key : mTunableLookup.keySet()) {
- String value = Settings.Secure.getStringForUser(mContentResolver, key,
- mCurrentUser);
+ String value = getValue(key);
for (Tunable tunable : mTunableLookup.get(key)) {
- tunable.onTuningChanged(key, value);
+ if (tunable != null) {
+ tunable.onTuningChanged(key, value);
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
index b36b531..29eaaee 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
@@ -292,6 +292,11 @@
}
private void onPublicVolumeStateChangedInternal(VolumeInfo vol) {
+ // Do not notify for volumes on non-removable disks
+ if (vol.disk.isNonRemovable()) {
+ return;
+ }
+
Log.d(TAG, "Notifying about public volume: " + vol.toString());
// Volume state change event may come from removed user, in this case, mountedUserId will
@@ -367,9 +372,8 @@
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;
}
@@ -411,9 +415,15 @@
mContext.getString(R.string.ext_media_unmount_action),
buildUnmountPendingIntent(vol)))
.setContentIntent(browseIntent)
+ .setOngoing(mContext.getResources().getBoolean(
+ R.bool.config_persistUsbDriveNotification))
.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 1c2a2fa..c310c5c 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
@@ -27,6 +27,8 @@
import com.android.settingslib.applications.InterestingConfigChanges;
import com.android.systemui.Dependency;
+import com.android.systemui.tristate.TriStateUiController;
+import com.android.systemui.tristate.TriStateUiControllerImpl;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.PluginDependencyProvider;
@@ -47,7 +49,7 @@
*/
@Singleton
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";
@@ -59,6 +61,7 @@
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);
@@ -78,6 +81,8 @@
mKeyguardViewMediator = keyguardViewMediator;
mController = volumeDialogController;
mController.setUserActivityListener(this);
+ boolean hasAlertSlider = mContext.getResources().
+ getBoolean(com.android.internal.R.bool.config_hasAlertSlider);
// Allow plugins to reference the VolumeDialogController.
Dependency.get(PluginDependencyProvider.class)
.allowPluginDependency(VolumeDialogController.class);
@@ -90,6 +95,13 @@
}
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();
Dependency.get(TunerService.class).addTunable(this, VOLUME_DOWN_SILENT, VOLUME_UP_SILENT,
@@ -178,6 +190,11 @@
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 06a9227..e19995c 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -66,6 +66,7 @@
import android.util.SparseBooleanArray;
import android.view.ContextThemeWrapper;
import android.view.MotionEvent;
+import android.view.Gravity;
import android.view.View;
import android.view.View.AccessibilityDelegate;
import android.view.ViewGroup;
@@ -165,6 +166,8 @@
private ViewStub mODICaptionsTooltipViewStub;
private View mODICaptionsTooltipView = null;
+ private boolean mLeftVolumeRocker;
+
public VolumeDialogImpl(Context context) {
mContext =
new ContextThemeWrapper(context, R.style.qs_theme);
@@ -176,6 +179,7 @@
mShowActiveStreamOnly = showActiveStreamOnly();
mHasSeenODICaptionsTooltip =
Prefs.getBoolean(context, Prefs.Key.HAS_SEEN_ODI_CAPTIONS_TOOLTIP, false);
+ mLeftVolumeRocker = mContext.getResources().getBoolean(R.bool.config_audioPanelOnLeftSide);
}
@Override
@@ -223,7 +227,11 @@
lp.format = PixelFormat.TRANSLUCENT;
lp.setTitle(VolumeDialogImpl.class.getSimpleName());
lp.windowAnimations = -1;
- lp.gravity = mContext.getResources().getInteger(R.integer.volume_dialog_gravity);
+ if(!isAudioPanelOnLeftSide()){
+ lp.gravity = Gravity.RIGHT | Gravity.CENTER_VERTICAL;
+ } else {
+ lp.gravity = Gravity.LEFT | Gravity.CENTER_VERTICAL;
+ }
mWindow.setAttributes(lp);
mWindow.setLayout(WRAP_CONTENT, WRAP_CONTENT);
@@ -232,7 +240,7 @@
mDialogView.setAlpha(0);
mDialog.setCanceledOnTouchOutside(true);
mDialog.setOnShowListener(dialog -> {
- if (!isLandscape()) mDialogView.setTranslationX(mDialogView.getWidth() / 2.0f);
+ if (!isLandscape()) mDialogView.setTranslationX((mDialogView.getWidth() / 2.0f)*(isAudioPanelOnLeftSide() ? -1 : 1));
mDialogView.setAlpha(0);
mDialogView.animate()
.alpha(1)
@@ -263,6 +271,11 @@
if (mRinger != null) {
mRingerIcon = mRinger.findViewById(R.id.ringer_icon);
mZenIcon = mRinger.findViewById(R.id.dnd_icon);
+ if(!isAudioPanelOnLeftSide()) {
+ mRinger.setForegroundGravity(Gravity.RIGHT);
+ } else {
+ mRinger.setForegroundGravity(Gravity.LEFT);
+ }
}
mODICaptionsView = mDialog.findViewById(R.id.odi_captions);
@@ -273,6 +286,13 @@
if (mHasSeenODICaptionsTooltip && mODICaptionsTooltipViewStub != null) {
mDialogView.removeView(mODICaptionsTooltipViewStub);
mODICaptionsTooltipViewStub = null;
+ }else if (mODICaptionsTooltipViewStub != null){
+ if(!isAudioPanelOnLeftSide()) {
+ mRinger.setForegroundGravity(Gravity.BOTTOM | Gravity.RIGHT);
+ } else {
+ mRinger.setForegroundGravity(Gravity.BOTTOM | Gravity.LEFT);
+ }
+
}
mSettingsView = mDialog.findViewById(R.id.settings_container);
@@ -350,7 +370,11 @@
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()){
+ mDialogRowsView.addView(row.view, 0);
+ } else {
+ mDialogRowsView.addView(row.view);
+ }
mRows.add(row);
}
@@ -360,7 +384,11 @@
final VolumeRow row = mRows.get(i);
initRow(row, row.stream, row.iconRes, row.iconMuteRes, row.important,
row.defaultStream);
- mDialogRowsView.addView(row.view);
+ if(!isAudioPanelOnLeftSide()){
+ mDialogRowsView.addView(row.view, 0);
+ } else {
+ mDialogRowsView.addView(row.view);
+ }
updateVolumeRowH(row);
}
}
@@ -760,7 +788,7 @@
tryToRemoveCaptionsTooltip();
mIsAnimatingDismiss = false;
}, 50));
- if (!isLandscape()) animator.translationX(mDialogView.getWidth() / 2.0f);
+ if (!isLandscape()) animator.translationX((mDialogView.getWidth() / 2.0f)*(isAudioPanelOnLeftSide() ? -1 : 1));
animator.start();
checkODICaptionsTooltip(true);
mController.notifyVisible(false);
@@ -1456,6 +1484,10 @@
}
}
+ private boolean isAudioPanelOnLeftSide() {
+ return mLeftVolumeRocker;
+ }
+
private static class VolumeRow {
private View view;
private TextView header;
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/clock/BubbleClockControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/clock/BubbleClockControllerTest.java
deleted file mode 100644
index b56986e..0000000
--- a/packages/SystemUI/tests/src/com/android/keyguard/clock/BubbleClockControllerTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.keyguard.clock;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.res.Resources;
-import android.graphics.Color;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper.RunWithLooper;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.colorextraction.SysuiColorExtractor;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-@RunWithLooper
-public final class BubbleClockControllerTest extends SysuiTestCase {
-
- private BubbleClockController mClockController;
- @Mock SysuiColorExtractor mMockColorExtractor;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
-
- Resources res = getContext().getResources();
- LayoutInflater layoutInflater = LayoutInflater.from(getContext());
- mClockController = new BubbleClockController(res, layoutInflater, mMockColorExtractor);
- }
-
- @Test
- public void setDarkAmount_AOD() {
- ViewGroup smallClockFrame = (ViewGroup) mClockController.getView();
- View smallClock = smallClockFrame.getChildAt(0);
- // WHEN dark amount is set to AOD
- mClockController.setDarkAmount(1f);
- // THEN small clock should not be shown.
- assertThat(smallClock.getVisibility()).isEqualTo(View.VISIBLE);
- }
-
- @Test
- public void setColorPalette_setDigitalClock() {
- ViewGroup smallClock = (ViewGroup) mClockController.getView();
- // WHEN text color is set
- mClockController.setColorPalette(true, new int[]{Color.RED});
- // THEN child of small clock should have text color set.
- TextView digitalClock = (TextView) smallClock.getChildAt(0);
- assertThat(digitalClock.getCurrentTextColor()).isEqualTo(Color.RED);
- }
-}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockManagerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockManagerTest.java
index 353fe62..a2c0b48 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockManagerTest.java
@@ -59,8 +59,8 @@
@RunWithLooper(setAsMainLooper = true)
public final class ClockManagerTest extends SysuiTestCase {
- private static final String BUBBLE_CLOCK = BubbleClockController.class.getName();
- private static final Class<?> BUBBLE_CLOCK_CLASS = BubbleClockController.class;
+ private static final String ANALOG_CLOCK = AnalogClockController.class.getName();
+ private static final Class<?> ANALOG_CLOCK_CLASS = AnalogClockController.class;
private static final int MAIN_USER_ID = 0;
private static final int SECONDARY_USER_ID = 11;
private static final Uri SETTINGS_URI = null;
@@ -95,7 +95,7 @@
mMockPluginManager, mMockColorExtractor, mMockContentResolver,
mMockCurrentUserObserable, mMockSettingsWrapper, mFakeDockManager);
- mClockManager.addBuiltinClock(() -> new BubbleClockController(
+ mClockManager.addBuiltinClock(() -> new AnalogClockController(
getContext().getResources(), inflater, mMockColorExtractor));
mClockManager.addOnClockChangedListener(mMockListener1);
mClockManager.addOnClockChangedListener(mMockListener2);
@@ -135,39 +135,39 @@
@Test
public void getCurrentClock_customClock() {
- // GIVEN that settings is set to the bubble clock face
- when(mMockSettingsWrapper.getLockScreenCustomClockFace(anyInt())).thenReturn(BUBBLE_CLOCK);
+ // GIVEN that settings is set to the analog clock face
+ when(mMockSettingsWrapper.getLockScreenCustomClockFace(anyInt())).thenReturn(ANALOG_CLOCK);
// WHEN settings change event is fired
mContentObserver.onChange(false, Arrays.asList(SETTINGS_URI), 0, MAIN_USER_ID);
- // THEN the plugin is the bubble clock face.
- assertThat(mClockManager.getCurrentClock()).isInstanceOf(BUBBLE_CLOCK_CLASS);
+ // THEN the plugin is the analog clock face.
+ assertThat(mClockManager.getCurrentClock()).isInstanceOf(ANALOG_CLOCK_CLASS);
}
@Test
public void onClockChanged_customClock() {
- // GIVEN that settings is set to the bubble clock face
- when(mMockSettingsWrapper.getLockScreenCustomClockFace(anyInt())).thenReturn(BUBBLE_CLOCK);
+ // GIVEN that settings is set to the analog clock face
+ when(mMockSettingsWrapper.getLockScreenCustomClockFace(anyInt())).thenReturn(ANALOG_CLOCK);
// WHEN settings change event is fired
mContentObserver.onChange(false, Arrays.asList(SETTINGS_URI), 0, MAIN_USER_ID);
- // THEN the plugin is the bubble clock face.
+ // THEN the plugin is the analog clock face.
ArgumentCaptor<ClockPlugin> captor = ArgumentCaptor.forClass(ClockPlugin.class);
verify(mMockListener1).onClockChanged(captor.capture());
- assertThat(captor.getValue()).isInstanceOf(BUBBLE_CLOCK_CLASS);
+ assertThat(captor.getValue()).isInstanceOf(ANALOG_CLOCK_CLASS);
}
@Test
public void onClockChanged_uniqueInstances() {
- // GIVEN that settings is set to the bubble clock face
- when(mMockSettingsWrapper.getLockScreenCustomClockFace(anyInt())).thenReturn(BUBBLE_CLOCK);
+ // GIVEN that settings is set to the analog clock face
+ when(mMockSettingsWrapper.getLockScreenCustomClockFace(anyInt())).thenReturn(ANALOG_CLOCK);
// WHEN settings change event is fired
mContentObserver.onChange(false, Arrays.asList(SETTINGS_URI), 0, MAIN_USER_ID);
- // THEN the listeners receive separate instances of the Bubble clock plugin.
+ // THEN the listeners receive separate instances of the analog clock plugin.
ArgumentCaptor<ClockPlugin> captor1 = ArgumentCaptor.forClass(ClockPlugin.class);
ArgumentCaptor<ClockPlugin> captor2 = ArgumentCaptor.forClass(ClockPlugin.class);
verify(mMockListener1).onClockChanged(captor1.capture());
verify(mMockListener2).onClockChanged(captor2.capture());
- assertThat(captor1.getValue()).isInstanceOf(BUBBLE_CLOCK_CLASS);
- assertThat(captor2.getValue()).isInstanceOf(BUBBLE_CLOCK_CLASS);
+ assertThat(captor1.getValue()).isInstanceOf(ANALOG_CLOCK_CLASS);
+ assertThat(captor2.getValue()).isInstanceOf(ANALOG_CLOCK_CLASS);
assertThat(captor1.getValue()).isNotSameAs(captor2.getValue());
}
@@ -192,12 +192,12 @@
@Test
public void getCurrentClock_dockedCustomClock() {
- // GIVEN settings is set to the bubble clock face
- when(mMockSettingsWrapper.getDockedClockFace(anyInt())).thenReturn(BUBBLE_CLOCK);
+ // GIVEN settings is set to the analog clock face
+ when(mMockSettingsWrapper.getDockedClockFace(anyInt())).thenReturn(ANALOG_CLOCK);
// WHEN dock event fires
mFakeDockManager.setDockEvent(DockManager.STATE_DOCKED);
- // THEN the plugin is the bubble clock face.
- assertThat(mClockManager.getCurrentClock()).isInstanceOf(BUBBLE_CLOCK_CLASS);
+ // THEN the plugin is the analog clock face.
+ assertThat(mClockManager.getCurrentClock()).isInstanceOf(ANALOG_CLOCK_CLASS);
}
@Test
@@ -213,13 +213,13 @@
@Test
public void getCurrentClock_badDockedSettingsFallback() {
// GIVEN settings contains a value that doesn't correspond to an available clock face, but
- // locked screen settings is set to bubble clock.
+ // locked screen settings is set to analog clock.
when(mMockSettingsWrapper.getDockedClockFace(anyInt())).thenReturn("bad value");
- when(mMockSettingsWrapper.getLockScreenCustomClockFace(anyInt())).thenReturn(BUBBLE_CLOCK);
+ when(mMockSettingsWrapper.getLockScreenCustomClockFace(anyInt())).thenReturn(ANALOG_CLOCK);
// WHEN dock event is fired
mFakeDockManager.setDockEvent(DockManager.STATE_DOCKED);
- // THEN the plugin is the bubble clock face.
- assertThat(mClockManager.getCurrentClock()).isInstanceOf(BUBBLE_CLOCK_CLASS);
+ // THEN the plugin is the analog clock face.
+ assertThat(mClockManager.getCurrentClock()).isInstanceOf(ANALOG_CLOCK_CLASS);
}
@Test
@@ -232,24 +232,24 @@
@Test
public void onUserChanged_customClock() {
- // GIVEN that a second user has selected the bubble clock face
+ // GIVEN that a second user has selected the analog clock face
when(mMockSettingsWrapper.getLockScreenCustomClockFace(SECONDARY_USER_ID)).thenReturn(
- BUBBLE_CLOCK);
+ ANALOG_CLOCK);
// WHEN the user changes
mCurrentUser.setValue(SECONDARY_USER_ID);
- // THEN the plugin is the bubble clock face.
- assertThat(mClockManager.getCurrentClock()).isInstanceOf(BUBBLE_CLOCK_CLASS);
+ // THEN the plugin is the analog clock face.
+ assertThat(mClockManager.getCurrentClock()).isInstanceOf(ANALOG_CLOCK_CLASS);
}
@Test
public void onUserChanged_docked() {
// GIVEN device is docked
mFakeDockManager.setDockEvent(DockManager.STATE_DOCKED);
- // AND the second user as selected the bubble clock for the dock
- when(mMockSettingsWrapper.getDockedClockFace(SECONDARY_USER_ID)).thenReturn(BUBBLE_CLOCK);
+ // AND the second user as selected the analog clock for the dock
+ when(mMockSettingsWrapper.getDockedClockFace(SECONDARY_USER_ID)).thenReturn(ANALOG_CLOCK);
// WHEN the user changes
mCurrentUser.setValue(SECONDARY_USER_ID);
- // THEN the plugin is the bubble clock face.
- assertThat(mClockManager.getCurrentClock()).isInstanceOf(BUBBLE_CLOCK_CLASS);
+ // THEN the plugin is the analog clock face.
+ assertThat(mClockManager.getCurrentClock()).isInstanceOf(ANALOG_CLOCK_CLASS);
}
}
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java b/packages/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
index e1771a5..69efbbd 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
@@ -16,7 +16,6 @@
package com.android.networkstack.tethering;
-import static android.content.Context.TELEPHONY_SERVICE;
import static android.net.ConnectivityManager.TYPE_ETHERNET;
import static android.net.ConnectivityManager.TYPE_MOBILE;
import static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
@@ -29,7 +28,6 @@
import android.net.util.SharedLog;
import android.provider.DeviceConfig;
import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
import android.text.TextUtils;
import com.android.internal.annotations.VisibleForTesting;
@@ -70,7 +68,7 @@
"192.168.48.2", "192.168.48.254", "192.168.49.2", "192.168.49.254",
};
- private static final String[] DEFAULT_IPV4_DNS = {"8.8.4.4", "8.8.8.8"};
+ private final String[] DEFAULT_IPV4_DNS = {"1.0.0.1", "1.1.1.1"};
/**
* Override enabling BPF offload configuration for tethering.
@@ -280,10 +278,7 @@
/** Check whether dun is required. */
public static boolean checkDunRequired(Context ctx) {
- final TelephonyManager tm = (TelephonyManager) ctx.getSystemService(TELEPHONY_SERVICE);
- // TelephonyManager would uses the active data subscription, which should be the one used
- // by tethering.
- return (tm != null) ? tm.isTetheringApnRequired() : false;
+ return false;
}
public int getOffloadPollInterval() {
diff --git a/packages/overlays/AccentColorDeepRedOverlay/Android.mk b/packages/overlays/AccentColorDeepRedOverlay/Android.mk
new file mode 100644
index 0000000..95ad20a
--- /dev/null
+++ b/packages/overlays/AccentColorDeepRedOverlay/Android.mk
@@ -0,0 +1,29 @@
+#
+# Copyright 2018, 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.
+#
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_RRO_THEME := AccentColorDeepRed
+
+LOCAL_PRODUCT_MODULE := true
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_PACKAGE_NAME := AccentColorDeepRedOverlay
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_RRO_PACKAGE)
diff --git a/packages/overlays/AccentColorDeepRedOverlay/AndroidManifest.xml b/packages/overlays/AccentColorDeepRedOverlay/AndroidManifest.xml
new file mode 100644
index 0000000..2a43df2
--- /dev/null
+++ b/packages/overlays/AccentColorDeepRedOverlay/AndroidManifest.xml
@@ -0,0 +1,25 @@
+<!--
+/**
+ * Copyright (c) 2018, 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.
+ */
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.theme.color.deepred"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <overlay android:targetPackage="android" android:category="android.theme.customization.accent_color" android:priority="1"/>
+
+ <application android:label="@string/accent_color_deep_red_overlay" android:hasCode="false"/>
+</manifest>
diff --git a/packages/overlays/AccentColorDeepRedOverlay/res/values/colors_device_defaults.xml b/packages/overlays/AccentColorDeepRedOverlay/res/values/colors_device_defaults.xml
new file mode 100644
index 0000000..f2b57bd
--- /dev/null
+++ b/packages/overlays/AccentColorDeepRedOverlay/res/values/colors_device_defaults.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2018, 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.
+ */
+-->
+<resources>
+ <color name="accent_device_default_light">#850007</color>
+ <color name="accent_device_default_dark">#750006</color>
+</resources>
diff --git a/packages/overlays/AccentColorDeepRedOverlay/res/values/strings.xml b/packages/overlays/AccentColorDeepRedOverlay/res/values/strings.xml
new file mode 100644
index 0000000..bb68df2
--- /dev/null
+++ b/packages/overlays/AccentColorDeepRedOverlay/res/values/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2018, 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.
+ */
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Green accent color name application label. [CHAR LIMIT=50] -->
+ <string name="accent_color_deep_red_overlay" translatable="false">Deep red</string>
+</resources>
+
diff --git a/packages/overlays/AccentColorRedOverlay/Android.mk b/packages/overlays/AccentColorRedOverlay/Android.mk
new file mode 100644
index 0000000..61bfed8
--- /dev/null
+++ b/packages/overlays/AccentColorRedOverlay/Android.mk
@@ -0,0 +1,29 @@
+#
+# Copyright 2018, 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.
+#
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_RRO_THEME := AccentColorRed
+
+LOCAL_PRODUCT_MODULE := true
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_PACKAGE_NAME := AccentColorRedOverlay
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_RRO_PACKAGE)
diff --git a/packages/overlays/AccentColorRedOverlay/AndroidManifest.xml b/packages/overlays/AccentColorRedOverlay/AndroidManifest.xml
new file mode 100644
index 0000000..c7d97c1
--- /dev/null
+++ b/packages/overlays/AccentColorRedOverlay/AndroidManifest.xml
@@ -0,0 +1,25 @@
+<!--
+/**
+ * Copyright (c) 2018, 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.
+ */
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.theme.color.red"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <overlay android:targetPackage="android" android:category="android.theme.customization.accent_color" android:priority="1"/>
+
+ <application android:label="@string/accent_color_red_overlay" android:hasCode="false"/>
+</manifest>
diff --git a/packages/overlays/AccentColorRedOverlay/res/values/colors_device_defaults.xml b/packages/overlays/AccentColorRedOverlay/res/values/colors_device_defaults.xml
new file mode 100644
index 0000000..75bbca6
--- /dev/null
+++ b/packages/overlays/AccentColorRedOverlay/res/values/colors_device_defaults.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2018, 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.
+ */
+-->
+<resources>
+ <color name="accent_device_default_light">#a32800</color>
+ <color name="accent_device_default_dark">#a32800</color>
+</resources>
diff --git a/packages/overlays/AccentColorRedOverlay/res/values/strings.xml b/packages/overlays/AccentColorRedOverlay/res/values/strings.xml
new file mode 100644
index 0000000..8d35df9
--- /dev/null
+++ b/packages/overlays/AccentColorRedOverlay/res/values/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2018, 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.
+ */
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Green accent color name application label. [CHAR LIMIT=50] -->
+ <string name="accent_color_red_overlay" translatable="false">Red</string>
+</resources>
+
diff --git a/packages/overlays/Android.mk b/packages/overlays/Android.mk
index 999ab08..612c860 100644
--- a/packages/overlays/Android.mk
+++ b/packages/overlays/Android.mk
@@ -25,6 +25,8 @@
AccentColorGreenOverlay \
AccentColorPurpleOverlay \
AccentColorPaletteOverlay \
+ AccentColorRedOverlay \
+ AccentColorDeepRedOverlay \
AccentColorCarbonOverlay \
AccentColorSandOverlay \
AccentColorAmethystOverlay \
@@ -35,7 +37,12 @@
DisplayCutoutEmulationHoleOverlay \
DisplayCutoutEmulationTallOverlay \
DisplayCutoutEmulationWaterfallOverlay \
- FontNotoSerifSourceOverlay \
+ FontArbutusSourceOverlay \
+ FontArvoLatoOverlay \
+ FontKaiOverlay \
+ FontRubikRubikOverlay \
+ FontSamOverlay \
+ FontVictorOverlay \
IconPackCircularAndroidOverlay \
IconPackCircularLauncherOverlay \
IconPackCircularSettingsOverlay \
diff --git a/packages/overlays/FontArbutusSourceOverlay/Android.mk b/packages/overlays/FontArbutusSourceOverlay/Android.mk
new file mode 100644
index 0000000..e6a1f14
--- /dev/null
+++ b/packages/overlays/FontArbutusSourceOverlay/Android.mk
@@ -0,0 +1,30 @@
+#
+# Copyright 2018, 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.
+#
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_RRO_THEME := FontArbutusSource
+LOCAL_PRODUCT_MODULE := true
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_PACKAGE_NAME := FontArbutusSourceOverlay
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_RRO_PACKAGE)
diff --git a/packages/overlays/FontArbutusSourceOverlay/AndroidManifest.xml b/packages/overlays/FontArbutusSourceOverlay/AndroidManifest.xml
new file mode 100644
index 0000000..46c06b9
--- /dev/null
+++ b/packages/overlays/FontArbutusSourceOverlay/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<!--
+/**
+ * Copyright (c) 2018, 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.
+ */
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.theme.font.arbutussource"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <overlay android:targetPackage="android"
+ android:category="android.theme.customization.font"
+ android:priority="1"/>
+
+ <application android:label="@string/font_arbutus_source_overlay" android:hasCode="false">
+ <meta-data
+ android:name="android.theme.customization.REQUIRED_SYSTEM_FONTS"
+ android:value="arbutus-slab,source-sans-pro,source-sans-pro-medium" />
+ </application>
+</manifest>
diff --git a/packages/overlays/FontArbutusSourceOverlay/res/values/config.xml b/packages/overlays/FontArbutusSourceOverlay/res/values/config.xml
new file mode 100644
index 0000000..a6aa64c
--- /dev/null
+++ b/packages/overlays/FontArbutusSourceOverlay/res/values/config.xml
@@ -0,0 +1,28 @@
+<!--
+/**
+ * Copyright (c) 2018, 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.
+ */
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Name of a font family to use for body text. -->
+ <string name="config_bodyFontFamily" translatable="false">source-sans-pro</string>
+ <!-- Name of a font family to use for medium body text. -->
+ <string name="config_bodyFontFamilyMedium" translatable="false">source-sans-pro-semi-bold</string>
+ <!-- Name of a font family to use for headlines. If empty, falls back to platform default -->
+ <string name="config_headlineFontFamily" translatable="false">arbutus-slab</string>
+ <!-- Name of the font family used for system surfaces where the font should use medium weight -->
+ <string name="config_headlineFontFamilyMedium" translatable="false">arbutus-slab</string>
+</resources>
+
diff --git a/packages/overlays/FontArbutusSourceOverlay/res/values/strings.xml b/packages/overlays/FontArbutusSourceOverlay/res/values/strings.xml
new file mode 100644
index 0000000..d80eb20
--- /dev/null
+++ b/packages/overlays/FontArbutusSourceOverlay/res/values/strings.xml
@@ -0,0 +1,21 @@
+<!--
+/**
+ * Copyright (c) 2018, 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.
+ */
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Headline / Body font Arbutus Slab / Source Sans Pro overlay -->
+ <string name="font_arbutus_source_overlay" translatable="false">Arbutus Slab / Source Sans Pro</string>
+</resources>
diff --git a/packages/overlays/FontArvoLatoOverlay/Android.mk b/packages/overlays/FontArvoLatoOverlay/Android.mk
new file mode 100644
index 0000000..42fb476
--- /dev/null
+++ b/packages/overlays/FontArvoLatoOverlay/Android.mk
@@ -0,0 +1,30 @@
+#
+# Copyright 2018, 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.
+#
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_RRO_THEME := FontArvoLato
+LOCAL_PRODUCT_MODULE := true
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_PACKAGE_NAME := FontArvoLatoOverlay
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_RRO_PACKAGE)
diff --git a/packages/overlays/FontArvoLatoOverlay/AndroidManifest.xml b/packages/overlays/FontArvoLatoOverlay/AndroidManifest.xml
new file mode 100644
index 0000000..3f2e5de
--- /dev/null
+++ b/packages/overlays/FontArvoLatoOverlay/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<!--
+/**
+ * Copyright (c) 2018, 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.
+ */
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.theme.font.arvolato"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <overlay android:targetPackage="android"
+ android:category="android.theme.customization.font"
+ android:priority="1"/>
+
+ <application android:label="@string/font_arvo_lato_overlay" android:hasCode="false">
+ <meta-data
+ android:name="android.theme.customization.REQUIRED_SYSTEM_FONTS"
+ android:value="arvo,arvo-medium,lato,lato-medium" />
+ </application>
+</manifest>
diff --git a/packages/overlays/FontArvoLatoOverlay/res/values/config.xml b/packages/overlays/FontArvoLatoOverlay/res/values/config.xml
new file mode 100644
index 0000000..4e70d72
--- /dev/null
+++ b/packages/overlays/FontArvoLatoOverlay/res/values/config.xml
@@ -0,0 +1,28 @@
+<!--
+/**
+ * Copyright (c) 2018, 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.
+ */
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Name of a font family to use for body text. -->
+ <string name="config_bodyFontFamily" translatable="false">lato</string>
+ <!-- Name of a font family to use for medium body text. -->
+ <string name="config_bodyFontFamilyMedium" translatable="false">lato-bold</string>
+ <!-- Name of a font family to use for headlines. If empty, falls back to platform default -->
+ <string name="config_headlineFontFamily" translatable="false">arvo</string>
+ <!-- Name of the font family used for system surfaces where the font should use medium weight -->
+ <string name="config_headlineFontFamilyMedium" translatable="false">arvo-bold</string>
+</resources>
+
diff --git a/packages/overlays/FontArvoLatoOverlay/res/values/strings.xml b/packages/overlays/FontArvoLatoOverlay/res/values/strings.xml
new file mode 100644
index 0000000..9ea097f
--- /dev/null
+++ b/packages/overlays/FontArvoLatoOverlay/res/values/strings.xml
@@ -0,0 +1,21 @@
+<!--
+/**
+ * Copyright (c) 2018, 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.
+ */
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Headline / Body font Arvo / Lato overlay -->
+ <string name="font_arvo_lato_overlay" translatable="false">Arvo / Lato</string>
+</resources>
diff --git a/packages/overlays/FontKaiOverlay/AndroidManifest.xml b/packages/overlays/FontKaiOverlay/AndroidManifest.xml
new file mode 100644
index 0000000..5e2ebd9
--- /dev/null
+++ b/packages/overlays/FontKaiOverlay/AndroidManifest.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="no"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.theme.font.kai" android:versionCode="1" android:versionName="1.0">
+ <overlay android:category="android.theme.customization.font" android:priority="1" android:targetPackage="android"/>
+ <application android:extractNativeLibs="false" android:hasCode="false" android:label="@string/font_overlay">
+ <meta-data android:name="android.theme.customization.REQUIRED_SYSTEM_FONTS" android:value="lustria,source-sans-pro,source-sans-pro-medium"/>
+ </application>
+</manifest>
diff --git a/packages/overlays/FontKaiOverlay/res/values/strings.xml b/packages/overlays/FontKaiOverlay/res/values/strings.xml
new file mode 100644
index 0000000..3fc830b
--- /dev/null
+++ b/packages/overlays/FontKaiOverlay/res/values/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="config_bodyFontFamily">source-sans-pro</string>
+ <string name="config_bodyFontFamilyMedium">source-sans-pro-semi-bold</string>
+ <string name="config_headlineFontFamily">@string/config_headlineFontFamilyMedium</string>
+ <string name="config_headlineFontFamilyMedium">lustria</string>
+ <string name="font_overlay">Lustria</string>
+</resources>
diff --git a/packages/overlays/FontNotoSerifSourceOverlay/Android.mk b/packages/overlays/FontNotoSerifSourceOverlay/Android.mk
deleted file mode 100644
index 16a0173..0000000
--- a/packages/overlays/FontNotoSerifSourceOverlay/Android.mk
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-# Copyright 2019, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_RRO_THEME := FontNotoSerifSource
-
-LOCAL_PRODUCT_MODULE := true
-
-LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-
-LOCAL_PACKAGE_NAME := FontNotoSerifSourceOverlay
-LOCAL_SDK_VERSION := current
-
-include $(BUILD_RRO_PACKAGE)
diff --git a/packages/overlays/FontNotoSerifSourceOverlay/AndroidManifest.xml b/packages/overlays/FontNotoSerifSourceOverlay/AndroidManifest.xml
deleted file mode 100644
index 54b8dbf..0000000
--- a/packages/overlays/FontNotoSerifSourceOverlay/AndroidManifest.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.theme.font.notoserifsource"
- android:versionCode="1"
- android:versionName="1.0">
- <overlay android:targetPackage="android"
- android:category="android.theme.customization.font"
- android:priority="1"/>
-
- <application android:label="@string/font_notoserif_source_overlay" android:hasCode="false">
- <meta-data
- android:name="android.theme.customization.REQUIRED_SYSTEM_FONTS"
- android:value="serif,serif-bold,source-sans-pro,source-sans-pro-medium" />
- </application>
-</manifest>
diff --git a/packages/overlays/FontNotoSerifSourceOverlay/res/values/config.xml b/packages/overlays/FontNotoSerifSourceOverlay/res/values/config.xml
deleted file mode 100644
index e63bea0..0000000
--- a/packages/overlays/FontNotoSerifSourceOverlay/res/values/config.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- Name of a font family to use for body text. -->
- <string name="config_bodyFontFamily" translatable="false">source-sans-pro</string>
- <!-- Name of a font family to use for medium body text. -->
- <string name="config_bodyFontFamilyMedium" translatable="false">source-sans-pro-semi-bold</string>
- <!-- Name of a font family to use for headlines. If empty, falls back to platform default -->
- <string name="config_headlineFontFamily" translatable="false">serif</string>
- <!-- Name of the font family used for system surfaces where the font should use medium weight -->
- <string name="config_headlineFontFamilyMedium" translatable="false">serif-bold</string>
-</resources>
-
diff --git a/packages/overlays/FontNotoSerifSourceOverlay/res/values/strings.xml b/packages/overlays/FontNotoSerifSourceOverlay/res/values/strings.xml
deleted file mode 100644
index ab839c2..0000000
--- a/packages/overlays/FontNotoSerifSourceOverlay/res/values/strings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<!--
-/**
- * Copyright (c) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- Headline / Body font Noto Serif / Source Sans Pro overlay -->
- <string name="font_notoserif_source_overlay" translatable="false">Noto Serif / Source Sans Pro</string>
-</resources>
diff --git a/packages/overlays/FontRubikRubikOverlay/Android.mk b/packages/overlays/FontRubikRubikOverlay/Android.mk
new file mode 100644
index 0000000..9d0423c
--- /dev/null
+++ b/packages/overlays/FontRubikRubikOverlay/Android.mk
@@ -0,0 +1,30 @@
+#
+# Copyright 2018, 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.
+#
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_RRO_THEME := FontRubikRubik
+LOCAL_PRODUCT_MODULE := true
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_PACKAGE_NAME := FontRubikRubikOverlay
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_RRO_PACKAGE)
diff --git a/packages/overlays/FontRubikRubikOverlay/AndroidManifest.xml b/packages/overlays/FontRubikRubikOverlay/AndroidManifest.xml
new file mode 100644
index 0000000..1f28d46
--- /dev/null
+++ b/packages/overlays/FontRubikRubikOverlay/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<!--
+/**
+ * Copyright (c) 2018, 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.
+ */
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.theme.font.rubikrubik"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <overlay android:targetPackage="android"
+ android:category="android.theme.customization.font"
+ android:priority="1"/>
+
+ <application android:label="@string/font_rubik_rubik_overlay" android:hasCode="false">
+ <meta-data
+ android:name="android.theme.customization.REQUIRED_SYSTEM_FONTS"
+ android:value="rubik,rubik-medium" />
+ </application>
+</manifest>
diff --git a/packages/overlays/FontRubikRubikOverlay/res/values/config.xml b/packages/overlays/FontRubikRubikOverlay/res/values/config.xml
new file mode 100644
index 0000000..4f90e29
--- /dev/null
+++ b/packages/overlays/FontRubikRubikOverlay/res/values/config.xml
@@ -0,0 +1,28 @@
+<!--
+/**
+ * Copyright (c) 2018, 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.
+ */
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Name of a font family to use for body text. -->
+ <string name="config_bodyFontFamily" translatable="false">rubik</string>
+ <!-- Name of a font family to use for medium body text. -->
+ <string name="config_bodyFontFamilyMedium" translatable="false">rubik-medium</string>
+ <!-- Name of a font family to use for headlines. If empty, falls back to platform default -->
+ <string name="config_headlineFontFamily" translatable="false">rubik</string>
+ <!-- Name of the font family used for system surfaces where the font should use medium weight -->
+ <string name="config_headlineFontFamilyMedium" translatable="false">rubik-medium</string>
+</resources>
+
diff --git a/packages/overlays/FontRubikRubikOverlay/res/values/strings.xml b/packages/overlays/FontRubikRubikOverlay/res/values/strings.xml
new file mode 100644
index 0000000..4bac7da
--- /dev/null
+++ b/packages/overlays/FontRubikRubikOverlay/res/values/strings.xml
@@ -0,0 +1,21 @@
+<!--
+/**
+ * Copyright (c) 2018, 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.
+ */
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Headline / Body font Rubik overlay -->
+ <string name="font_rubik_rubik_overlay" translatable="false">Rubik / Rubik</string>
+</resources>
diff --git a/packages/overlays/FontSamOverlay/AndroidManifest.xml b/packages/overlays/FontSamOverlay/AndroidManifest.xml
new file mode 100644
index 0000000..3c17bea
--- /dev/null
+++ b/packages/overlays/FontSamOverlay/AndroidManifest.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="no"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.theme.font.kai" android:versionCode="1" android:versionName="1.0">
+ <overlay android:category="android.theme.customization.font" android:priority="1" android:targetPackage="android"/>
+ <application android:extractNativeLibs="false" android:hasCode="false" android:label="@string/font_overlay">
+ <meta-data android:name="android.theme.customization.REQUIRED_SYSTEM_FONTS" android:value="fraunces,fraunces-semi-bold,karla,karla-bold"/>
+ </application>
+</manifest>
diff --git a/packages/overlays/FontSamOverlay/res/values/strings.xml b/packages/overlays/FontSamOverlay/res/values/strings.xml
new file mode 100644
index 0000000..8d318a4
--- /dev/null
+++ b/packages/overlays/FontSamOverlay/res/values/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="config_bodyFontFamily">karla</string>
+ <string name="config_bodyFontFamilyMedium">karla-bold</string>
+ <string name="config_headlineFontFamily">fraunces</string>
+ <string name="config_headlineFontFamilyMedium">fraunces-semi-bold</string>
+ <string name="font_overlay">Sam</string>
+</resources>
diff --git a/packages/overlays/FontVictorOverlay/AndroidManifest.xml b/packages/overlays/FontVictorOverlay/AndroidManifest.xml
new file mode 100644
index 0000000..4ff09fe
--- /dev/null
+++ b/packages/overlays/FontVictorOverlay/AndroidManifest.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="no"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.theme.font.kai" android:versionCode="1" android:versionName="1.0">
+ <overlay android:category="android.theme.customization.font" android:priority="1" android:targetPackage="android"/>
+ <application android:extractNativeLibs="false" android:hasCode="false" android:label="@string/font_overlay">
+ <meta-data android:name="android.theme.customization.REQUIRED_SYSTEM_FONTS" android:value="barlow,barlow-medium,big-shoulders-text-bold,big-shoulders-text-extra-bold"/>
+ </application>
+</manifest>
diff --git a/packages/overlays/FontVictorOverlay/res/values/strings.xml b/packages/overlays/FontVictorOverlay/res/values/strings.xml
new file mode 100644
index 0000000..c822ecd7
--- /dev/null
+++ b/packages/overlays/FontVictorOverlay/res/values/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="config_bodyFontFamily">big-shoulders-text-bold</string>
+ <string name="config_bodyFontFamilyMedium">big-shoulders-text-extra-bold</string>
+ <string name="config_headlineFontFamily">barlow</string>
+ <string name="config_headlineFontFamilyMedium">barlow-medium</string>
+ <string name="font_overlay">Victor</string>
+</resources>
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/AndroidManifest.xml b/packages/overlays/IconPackCircularLauncherOverlay/AndroidManifest.xml
index 0b69eca..08bb1f0 100644
--- a/packages/overlays/IconPackCircularLauncherOverlay/AndroidManifest.xml
+++ b/packages/overlays/IconPackCircularLauncherOverlay/AndroidManifest.xml
@@ -19,6 +19,6 @@
package="com.android.theme.icon_pack.circular.launcher"
android:versionCode="1"
android:versionName="1.0">
- <overlay android:targetPackage="com.android.launcher3" android:category="android.theme.customization.icon_pack.launcher" android:priority="1"/>
+ <overlay android:targetPackage="com.google.android.apps.nexuslauncher" android:category="android.theme.customization.icon_pack.launcher" android:priority="1"/>
<application android:label="Circular" android:hasCode="false"/>
</manifest>
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_apps.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_apps.xml
index 228e2cc..95c0867 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_apps.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_apps.xml
@@ -20,30 +20,30 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 6 4 C 7.10456949966 4 8 4.89543050034 8 6 C 8 7.10456949966 7.10456949966 8 6 8 C 4.89543050034 8 4 7.10456949966 4 6 C 4 4.89543050034 4.89543050034 4 6 4 Z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 12 4 C 13.1045694997 4 14 4.89543050034 14 6 C 14 7.10456949966 13.1045694997 8 12 8 C 10.8954305003 8 10 7.10456949966 10 6 C 10 4.89543050034 10.8954305003 4 12 4 Z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 18 4 C 19.1045694997 4 20 4.89543050034 20 6 C 20 7.10456949966 19.1045694997 8 18 8 C 16.8954305003 8 16 7.10456949966 16 6 C 16 4.89543050034 16.8954305003 4 18 4 Z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 6 10 C 7.10456949966 10 8 10.8954305003 8 12 C 8 13.1045694997 7.10456949966 14 6 14 C 4.89543050034 14 4 13.1045694997 4 12 C 4 10.8954305003 4.89543050034 10 6 10 Z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 12 10 C 13.1045694997 10 14 10.8954305003 14 12 C 14 13.1045694997 13.1045694997 14 12 14 C 10.8954305003 14 10 13.1045694997 10 12 C 10 10.8954305003 10.8954305003 10 12 10 Z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 18 10 C 19.1045694997 10 20 10.8954305003 20 12 C 20 13.1045694997 19.1045694997 14 18 14 C 16.8954305003 14 16 13.1045694997 16 12 C 16 10.8954305003 16.8954305003 10 18 10 Z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 6 16 C 7.10456949966 16 8 16.8954305003 8 18 C 8 19.1045694997 7.10456949966 20 6 20 C 4.89543050034 20 4 19.1045694997 4 18 C 4 16.8954305003 4.89543050034 16 6 16 Z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 12 16 C 13.1045694997 16 14 16.8954305003 14 18 C 14 19.1045694997 13.1045694997 20 12 20 C 10.8954305003 20 10 19.1045694997 10 18 C 10 16.8954305003 10.8954305003 16 12 16 Z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 18 16 C 19.1045694997 16 20 16.8954305003 20 18 C 20 19.1045694997 19.1045694997 20 18 20 C 16.8954305003 20 16 19.1045694997 16 18 C 16 16.8954305003 16.8954305003 16 18 16 Z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_devices_other.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_devices_other.xml
index 14898c4..454b2e2 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_devices_other.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_devices_other.xml
@@ -21,12 +21,12 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M7.25,18.25c0-0.41-0.34-0.75-0.75-0.75H3V8.25C3,7.01,4.01,6,5.25,6h16C21.66,6,22,5.66,22,5.25S21.66,4.5,21.25,4.5h-16 C3.18,4.5,1.5,6.18,1.5,8.25V19h5C6.91,19,7.25,18.66,7.25,18.25z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M14,16c0-1.66-1.34-3-3-3s-3,1.34-3,3s1.34,3,3,3S14,17.66,14,16z M9.5,16c0-0.83,0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5 s-0.67,1.5-1.5,1.5S9.5,16.83,9.5,16z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M20,19c1.1,0,2-0.9,2-2v-7c0-1.1-0.9-2-2-2h-3c-1.1,0-2,0.9-2,2v7c0,1.1,0.9,2,2,2H20z M16.5,17v-7 c0-0.28,0.22-0.5,0.5-0.5h3c0.28,0,0.5,0.22,0.5,0.5v7c0,0.28-0.22,0.5-0.5,0.5h-3C16.72,17.5,16.5,17.28,16.5,17z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_help.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_help.xml
index 2fa1520..4e99add 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_help.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_help.xml
@@ -20,12 +20,12 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M12,22c0,0,0.01,0,0.01,0c5.51,0,9.98-4.46,9.99-9.98c0-0.01,0-0.01,0-0.02c0-5.52-4.48-10-10-10S2,6.48,2,12 S6.48,22,12,22z M12,3.5c4.69,0,8.5,3.81,8.5,8.52c-0.01,4.68-3.81,8.48-8.5,8.48c-4.69,0-8.5-3.81-8.5-8.5 C3.5,7.31,7.31,3.5,12,3.5z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M8.57,9.89c0.4,0.1,0.81-0.15,0.9-0.56c0.12-0.5,0.36-0.94,0.71-1.29c1.06-1.06,2.78-1.06,3.84,0 c0.53,0.53,0.79,1.23,0.72,1.92c-0.06,0.62-0.39,1.15-0.92,1.5c-0.17,0.11-0.35,0.19-0.52,0.27c-0.7,0.33-1.67,0.78-1.93,2.37 c-0.07,0.41,0.21,0.8,0.61,0.86C12.02,14.99,12.06,15,12.1,15c0.36,0,0.68-0.26,0.74-0.62c0.14-0.82,0.48-0.98,1.09-1.26 c0.25-0.11,0.49-0.23,0.72-0.38c0.91-0.6,1.48-1.53,1.58-2.61c0.12-1.14-0.31-2.28-1.15-3.13c-1.64-1.64-4.32-1.64-5.96,0 c-0.54,0.54-0.93,1.24-1.11,2C7.92,9.39,8.16,9.8,8.57,9.89z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 12 16.5 C 12.5522847498 16.5 13 16.9477152502 13 17.5 C 13 18.0522847498 12.5522847498 18.5 12 18.5 C 11.4477152502 18.5 11 18.0522847498 11 17.5 C 11 16.9477152502 11.4477152502 16.5 12 16.5 Z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_phone_info.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_phone_info.xml
index efc300ab..1cafbfe 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_phone_info.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_phone_info.xml
@@ -20,12 +20,12 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M15,22c1.66,0,3-1.34,3-3V5c0-1.66-1.34-3-3-3H9C7.34,2,6,3.34,6,5v14c0,1.66,1.34,3,3,3H15z M7.5,6.5h9v11h-9V6.5z M9,3.5 h6c0.83,0,1.5,0.67,1.5,1.5h-9C7.5,4.17,8.17,3.5,9,3.5z M7.5,19h9c0,0.83-0.67,1.5-1.5,1.5H9C8.17,20.5,7.5,19.83,7.5,19z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M12,11.5c-0.41,0-0.75,0.34-0.75,0.75v3c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-3 C12.75,11.84,12.41,11.5,12,11.5z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 12 8 C 12.5522847498 8 13 8.44771525017 13 9 C 13 9.55228474983 12.5522847498 10 12 10 C 11.4477152502 10 11 9.55228474983 11 9 C 11 8.44771525017 11.4477152502 8 12 8 Z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_accessibility.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_accessibility.xml
index 7281477..4c57d8d 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_accessibility.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_accessibility.xml
@@ -20,18 +20,18 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M3.03,5.54c-0.11,0.4,0.13,0.81,0.53,0.92C5.24,6.91,7.07,7.2,9,7.35v8.15v3.75C9,19.66,9.34,20,9.75,20 s0.75-0.34,0.75-0.75V15.5c0-0.83,0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5v3.75c0,0.41,0.34,0.75,0.75,0.75S15,19.66,15,19.25V15.5V7.35 c1.93-0.15,3.76-0.44,5.44-0.89c0.4-0.11,0.64-0.52,0.53-0.92c-0.11-0.4-0.51-0.64-0.92-0.53C17.64,5.66,14.93,5.98,12,5.98 S6.36,5.66,3.94,5.01C3.54,4.9,3.13,5.14,3.03,5.54z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 8 22 C 8.55228474983 22 9 22.4477152502 9 23 C 9 23.5522847498 8.55228474983 24 8 24 C 7.44771525017 24 7 23.5522847498 7 23 C 7 22.4477152502 7.44771525017 22 8 22 Z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 16 22 C 16.5522847498 22 17 22.4477152502 17 23 C 17 23.5522847498 16.5522847498 24 16 24 C 15.4477152502 24 15 23.5522847498 15 23 C 15 22.4477152502 15.4477152502 22 16 22 Z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 12 22 C 12.5522847498 22 13 22.4477152502 13 23 C 13 23.5522847498 12.5522847498 24 12 24 C 11.4477152502 24 11 23.5522847498 11 23 C 11 22.4477152502 11.4477152502 22 12 22 Z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 12 1 C 13.1045694997 1 14 1.89543050034 14 3 C 14 4.10456949966 13.1045694997 5 12 5 C 10.8954305003 5 10 4.10456949966 10 3 C 10 1.89543050034 10.8954305003 1 12 1 Z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_accounts.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_accounts.xml
index 6b5c4e4..c63ec5b 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_accounts.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_accounts.xml
@@ -20,9 +20,9 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M17,3H7C4.79,3,3,4.79,3,7v10c0,2.21,1.79,4,4,4h10c2.21,0,4-1.79,4-4V7C21,4.79,19.21,3,17,3z M17,19.5H7 c-0.93,0-1.73-0.52-2.16-1.27C6.59,16.47,9.11,15.5,12,15.5s5.41,0.97,7.16,2.73C18.73,18.98,17.93,19.5,17,19.5z M19.5,16.51 C17.52,14.89,14.92,14,12,14s-5.52,0.89-7.5,2.51V7c0-1.38,1.12-2.5,2.5-2.5h10c1.38,0,2.5,1.12,2.5,2.5V16.51z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M12,6c-1.93,0-3.5,1.57-3.5,3.5S10.07,13,12,13s3.5-1.57,3.5-3.5S13.93,6,12,6z M12,11.5c-1.1,0-2-0.9-2-2 c0-1.1,0.9-2,2-2c1.1,0,2,0.9,2,2C14,10.6,13.1,11.5,12,11.5z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_battery_white.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_battery_white.xml
index d91afad..780fa2e 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_battery_white.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_battery_white.xml
@@ -20,6 +20,6 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M14,4c0-0.55-0.45-1-1-1h-2c-0.55,0-1,0.45-1,1H9C7.34,4,6,5.34,6,7v12c0,1.66,1.34,3,3,3h6c1.66,0,3-1.34,3-3V7 c0-1.66-1.34-3-3-3H14z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_display_white.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_display_white.xml
index f526534..8dabc53 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_display_white.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_display_white.xml
@@ -20,9 +20,9 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M17,12c0-2.76-2.24-5-5-5v10C14.76,17,17,14.76,17,12z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M4,15.31V18c0,1.1,0.9,2,2,2h2.69l1.9,1.9c0.39,0.39,0.9,0.59,1.41,0.59s1.02-0.2,1.41-0.59l1.9-1.9H18c1.1,0,2-0.9,2-2 v-2.69l1.9-1.9c0.78-0.78,0.78-2.05,0-2.83L20,8.69V6c0-1.1-0.9-2-2-2h-2.69l-1.9-1.9c-0.39-0.39-0.9-0.59-1.41-0.59 s-1.02,0.2-1.41,0.59L8.69,4H6C4.9,4,4,4.9,4,6v2.69l-1.9,1.9c-0.78,0.78-0.78,2.05,0,2.83L4,15.31z M3.16,11.65l1.9-1.9L5.5,9.31 V8.69V6c0-0.28,0.22-0.5,0.5-0.5h2.69h0.62l0.44-0.44l1.9-1.9c0.13-0.13,0.28-0.15,0.35-0.15c0.08,0,0.23,0.02,0.35,0.15l1.9,1.9 l0.44,0.44h0.62H18c0.28,0,0.5,0.22,0.5,0.5v2.69v0.62l0.44,0.44l1.9,1.9c0.13,0.13,0.15,0.28,0.15,0.35s-0.02,0.23-0.15,0.35 l-1.9,1.9l-0.44,0.44v0.62V18c0,0.28-0.22,0.5-0.5,0.5h-2.69h-0.62l-0.44,0.44l-1.9,1.9c-0.13,0.13-0.28,0.15-0.35,0.15 c-0.08,0-0.23-0.02-0.35-0.15l-1.9-1.9L9.31,18.5H8.69H6c-0.28,0-0.5-0.22-0.5-0.5v-2.69v-0.62l-0.44-0.44l-1.9-1.9 C3.04,12.23,3.02,12.08,3.02,12S3.04,11.77,3.16,11.65z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_location.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_location.xml
index 213b01b..32234a1 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_location.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_location.xml
@@ -20,9 +20,9 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M12,21.5c0,0,7-5.34,7-11.25c0-4-3.13-7.25-7-7.25c-3.87,0-7,3.25-7,7.25C5,16.16,12,21.5,12,21.5z M12,4.5 c3.03,0,5.5,2.58,5.5,5.75c0,3.91-3.74,7.72-5.51,9.29C9.9,17.68,6.5,13.89,6.5,10.25C6.5,7.08,8.97,4.5,12,4.5z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M15,10c0-1.66-1.34-3-3-3c-1.66,0-3,1.34-3,3c0,1.66,1.34,3,3,3C13.66,13,15,11.66,15,10z M10.5,10 c0-0.83,0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5s-0.67,1.5-1.5,1.5S10.5,10.83,10.5,10z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_privacy.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_privacy.xml
index ce4c1a4..86b9a1d 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_privacy.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_privacy.xml
@@ -20,12 +20,12 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M12,16.5c-3.74,0-6.89-1.9-8.37-5c1.47-3.1,4.62-5,8.37-5c3.53,0,6.52,1.71,8.08,4.5h1.7C20.09,7.3,16.35,5,12,5 C7.45,5,3.57,7.51,2,11.5C3.57,15.49,7.45,18,12,18c1.41,0,2.76-0.24,4-0.7v-1.62C14.79,16.21,13.44,16.5,12,16.5z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M12,8c-1.93,0-3.5,1.57-3.5,3.5S10.07,15,12,15s3.5-1.57,3.5-3.5S13.93,8,12,8z M12,13.5c-1.1,0-2-0.9-2-2s0.9-2,2-2 c1.1,0,2,0.9,2,2S13.1,13.5,12,13.5z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M22,14c0-1.1-0.9-2-2-2c-1.1,0-2,0.9-2,2c0,0.37,0,0.7,0,1h-1v4c0,0.55,0.45,1,1,1h4c0.55,0,1-0.45,1-1v-4h-1 C22,14.65,22,14.28,22,14z M19,14c0-0.55,0.45-1,1-1s1,0.45,1,1v1h-2V14z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_security_white.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_security_white.xml
index 6126115..6fc58fa 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_security_white.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_security_white.xml
@@ -20,9 +20,9 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M11.25,14.79v1.46c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-1.46c0.45-0.26,0.75-0.74,0.75-1.29 c0-0.83-0.67-1.5-1.5-1.5s-1.5,0.67-1.5,1.5C10.5,14.05,10.8,14.53,11.25,14.79z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M19,2.5c1.35,0,2.5,1.18,2.5,2.57c0,0.41,0.34,0.75,0.75,0.75S23,5.48,23,5.07C23,2.86,21.17,1,19,1s-4,1.86-4,4.07V8H5v10 c0,1.66,1.34,3,3,3h8c1.66,0,3-1.34,3-3V8h-2.5V5.07C16.5,3.68,17.65,2.5,19,2.5z M17.5,18c0,0.83-0.67,1.5-1.5,1.5H8 c-0.83,0-1.5-0.67-1.5-1.5V9.5h11V18z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml
index 4adc9ce..67ddf46 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml
@@ -20,12 +20,12 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M11.99,2C6.47,2,2,6.48,2,12c0,5.52,4.47,10,9.99,10C17.52,22,22,17.52,22,12C22,6.48,17.52,2,11.99,2z M11.99,20.5 c-4.68,0-8.49-3.81-8.49-8.5c0-4.69,3.81-8.5,8.49-8.5c4.69,0,8.51,3.81,8.51,8.5C20.5,16.69,16.68,20.5,11.99,20.5z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M12,10.5c-0.41,0-0.75,0.34-0.75,0.75v5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-5 C12.75,10.84,12.41,10.5,12,10.5z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_wireless.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_wireless.xml
index d9203d2..91670fc 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_wireless.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_wireless.xml
@@ -21,15 +21,15 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 12 17 C 12.8284271247 17 13.5 17.6715728753 13.5 18.5 C 13.5 19.3284271247 12.8284271247 20 12 20 C 11.1715728753 20 10.5 19.3284271247 10.5 18.5 C 10.5 17.6715728753 11.1715728753 17 12 17 Z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M19.42,11.84c-0.19,0-0.38-0.07-0.53-0.22C17.05,9.77,14.6,8.75,12,8.75s-5.05,1.02-6.89,2.86 c-0.29,0.29-0.77,0.29-1.06,0c-0.29-0.29-0.29-0.77,0-1.06C6.17,8.43,9,7.25,12,7.25s5.83,1.17,7.95,3.3 c0.29,0.29,0.29,0.77,0,1.06C19.8,11.76,19.61,11.84,19.42,11.84z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M22.61,8.65c-0.19,0-0.38-0.07-0.53-0.22C19.38,5.74,15.81,4.25,12,4.25S4.62,5.74,1.92,8.43c-0.29,0.29-0.77,0.29-1.06,0 s-0.29-0.77,0-1.06C3.84,4.39,7.79,2.75,12,2.75s8.16,1.64,11.14,4.61c0.29,0.29,0.29,0.77,0,1.06 C22.99,8.57,22.8,8.65,22.61,8.65z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M16.25,15c-0.19,0-0.38-0.07-0.53-0.22c-1-0.99-2.32-1.53-3.73-1.53s-2.73,0.54-3.73,1.53c-0.29,0.29-0.77,0.29-1.06-0.01 s-0.29-0.77,0.01-1.06c1.28-1.27,2.98-1.96,4.78-1.96s3.5,0.7,4.78,1.96c0.29,0.29,0.3,0.77,0.01,1.06 C16.64,14.93,16.45,15,16.25,15z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_storage_white.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_storage_white.xml
index cf9db68..807c3bf 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_storage_white.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_storage_white.xml
@@ -20,21 +20,21 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M21,17c0-1.1-0.9-2-2-2H5c-1.1,0-2,0.9-2,2v3h18V17z M19.5,18.5h-15V17c0-0.28,0.22-0.5,0.5-0.5h14 c0.28,0,0.5,0.22,0.5,0.5V18.5z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M21,5c0-1.1-0.9-2-2-2H5C3.9,3,3,3.9,3,5v3h18V5z M19.5,6.5h-15V5c0-0.28,0.22-0.5,0.5-0.5h14c0.28,0,0.5,0.22,0.5,0.5V6.5 z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M21,11c0-1.1-0.9-2-2-2H5c-1.1,0-2,0.9-2,2v3h18V11z M19.5,12.5h-15V11c0-0.28,0.22-0.5,0.5-0.5h14 c0.28,0,0.5,0.22,0.5,0.5V12.5z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 6.01 4.75 C 6.42421356237 4.75 6.76 5.08578643763 6.76 5.5 C 6.76 5.91421356237 6.42421356237 6.25 6.01 6.25 C 5.59578643763 6.25 5.26 5.91421356237 5.26 5.5 C 5.26 5.08578643763 5.59578643763 4.75 6.01 4.75 Z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 6.01 10.75 C 6.42421356237 10.75 6.76 11.0857864376 6.76 11.5 C 6.76 11.9142135624 6.42421356237 12.25 6.01 12.25 C 5.59578643763 12.25 5.26 11.9142135624 5.26 11.5 C 5.26 11.0857864376 5.59578643763 10.75 6.01 10.75 Z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 6.01 16.75 C 6.42421356237 16.75 6.76 17.0857864376 6.76 17.5 C 6.76 17.9142135624 6.42421356237 18.25 6.01 18.25 C 5.59578643763 18.25 5.26 17.9142135624 5.26 17.5 C 5.26 17.0857864376 5.59578643763 16.75 6.01 16.75 Z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_volume_up_24dp.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_volume_up_24dp.xml
index ace87e0..1a06137 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_volume_up_24dp.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_volume_up_24dp.xml
@@ -20,12 +20,12 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M14.44,13.56c-0.38,0.17-0.54,0.62-0.37,0.99c0.13,0.28,0.4,0.44,0.68,0.44c0.1,0,0.21-0.02,0.31-0.07 C16.26,14.37,17,13.25,17,12c0-1.25-0.74-2.37-1.93-2.93c-0.37-0.17-0.82-0.01-1,0.37c-0.17,0.38-0.01,0.82,0.36,1 c0.66,0.3,1.07,0.9,1.07,1.57S15.09,13.26,14.44,13.56z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M14.59,17.42c-0.4,0.09-0.66,0.49-0.57,0.9c0.08,0.35,0.39,0.59,0.73,0.59c0.05,0,0.11-0.01,0.16-0.02 c3.29-0.74,5.59-3.57,5.59-6.89s-2.3-6.15-5.59-6.89c-0.41-0.08-0.81,0.17-0.9,0.57s0.16,0.8,0.57,0.9C17.19,7.16,19,9.39,19,12 S17.19,16.84,14.59,17.42z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M7,15l4.15,4.15c0.1,0.1,0.23,0.15,0.35,0.15c0.26,0,0.5-0.2,0.5-0.5V5.21c0-0.3-0.25-0.5-0.5-0.5 c-0.12,0-0.25,0.05-0.35,0.15L7,9H5c-1.1,0-2,0.9-2,2v2c0,1.1,0.9,2,2,2H7z M4.5,13v-2c0-0.28,0.22-0.5,0.5-0.5h2.62l2.88-2.88 v8.76L7.62,13.5H5C4.72,13.5,4.5,13.28,4.5,13z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/AndroidManifest.xml b/packages/overlays/IconPackFilledLauncherOverlay/AndroidManifest.xml
index 0b9f636..eaa57e7 100644
--- a/packages/overlays/IconPackFilledLauncherOverlay/AndroidManifest.xml
+++ b/packages/overlays/IconPackFilledLauncherOverlay/AndroidManifest.xml
@@ -19,6 +19,6 @@
package="com.android.theme.icon_pack.filled.launcher"
android:versionCode="1"
android:versionName="1.0">
- <overlay android:targetPackage="com.android.launcher3" android:category="android.theme.customization.icon_pack.launcher" android:priority="1"/>
+ <overlay android:targetPackage="com.google.android.apps.nexuslauncher" android:category="android.theme.customization.icon_pack.launcher" android:priority="1"/>
<application android:label="Filled" android:hasCode="false"/>
</manifest>
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_apps.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_apps.xml
index 60b5116..74b13fd 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_apps.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_apps.xml
@@ -20,30 +20,30 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M7.5,4h-3C4.22,4,4,4.22,4,4.5v3C4,7.78,4.22,8,4.5,8h3C7.78,8,8,7.78,8,7.5v-3C8,4.22,7.78,4,7.5,4z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M13.5,4h-3C10.22,4,10,4.22,10,4.5v3C10,7.78,10.22,8,10.5,8h3C13.78,8,14,7.78,14,7.5v-3C14,4.22,13.78,4,13.5,4z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M19.5,4h-3C16.22,4,16,4.22,16,4.5v3C16,7.78,16.22,8,16.5,8h3C19.78,8,20,7.78,20,7.5v-3C20,4.22,19.78,4,19.5,4z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M7.5,10h-3C4.22,10,4,10.22,4,10.5v3C4,13.78,4.22,14,4.5,14h3C7.78,14,8,13.78,8,13.5v-3C8,10.22,7.78,10,7.5,10z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M13.5,10h-3c-0.28,0-0.5,0.22-0.5,0.5v3c0,0.28,0.22,0.5,0.5,0.5h3c0.28,0,0.5-0.22,0.5-0.5v-3C14,10.22,13.78,10,13.5,10 z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M19.5,10h-3c-0.28,0-0.5,0.22-0.5,0.5v3c0,0.28,0.22,0.5,0.5,0.5h3c0.28,0,0.5-0.22,0.5-0.5v-3C20,10.22,19.78,10,19.5,10 z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M7.5,16h-3C4.22,16,4,16.22,4,16.5v3C4,19.78,4.22,20,4.5,20h3C7.78,20,8,19.78,8,19.5v-3C8,16.22,7.78,16,7.5,16z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M13.5,16h-3c-0.28,0-0.5,0.22-0.5,0.5v3c0,0.28,0.22,0.5,0.5,0.5h3c0.28,0,0.5-0.22,0.5-0.5v-3C14,16.22,13.78,16,13.5,16 z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M19.5,16h-3c-0.28,0-0.5,0.22-0.5,0.5v3c0,0.28,0.22,0.5,0.5,0.5h3c0.28,0,0.5-0.22,0.5-0.5v-3C20,16.22,19.78,16,19.5,16 z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_devices_other.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_devices_other.xml
index a451ef8..33a4b29 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_devices_other.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_devices_other.xml
@@ -21,12 +21,12 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M6,18H3V6h17c0.55,0,1-0.45,1-1s-0.45-1-1-1H3C1.9,4,1,4.9,1,6v12c0,1.1,0.9,2,2,2h3c0.55,0,1-0.45,1-1S6.55,18,6,18z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M13,12H9v1.78C8.39,14.33,8,15.11,8,16s0.39,1.67,1,2.22V20h4v-1.78c0.61-0.55,1-1.34,1-2.22s-0.39-1.67-1-2.22V12z M11,17.5c-0.83,0-1.5-0.67-1.5-1.5c0-0.83,0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5C12.5,16.83,11.83,17.5,11,17.5z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M22,8h-6c-0.5,0-1,0.5-1,1v10c0,0.5,0.5,1,1,1h6c0.5,0,1-0.5,1-1V9C23,8.5,22.5,8,22,8z M21,18h-4v-8h4V18z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_help.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_help.xml
index 25bb103..42854a4 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_help.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_help.xml
@@ -20,6 +20,6 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M12,22c5.52,0,10-4.48,10-10c0-5.52-4.48-10-10-10S2,6.48,2,12C2,17.52,6.48,22,12,22z M12,18.96 c-0.69,0-1.25-0.56-1.25-1.25c0-0.69,0.56-1.25,1.25-1.25s1.25,0.56,1.25,1.25C13.25,18.4,12.69,18.96,12,18.96z M8.16,7.92 c0.63-2.25,2.91-3.38,5.05-2.74c1.71,0.51,2.84,2.16,2.78,3.95c-0.07,2.44-2.49,2.61-2.92,5.06c-0.09,0.52-0.59,0.87-1.13,0.79 c-0.57-0.08-0.94-0.66-0.83-1.23c0.52-2.61,2.66-2.84,2.87-4.5c0.12-0.96-0.42-1.87-1.34-2.17c-1.04-0.33-2.21,0.16-2.55,1.37 C9.97,8.9,9.57,9.19,9.12,9.19C8.46,9.19,7.99,8.56,8.16,7.92z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_phone_info.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_phone_info.xml
index 6821259..e932b9b 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_phone_info.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_phone_info.xml
@@ -20,12 +20,12 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M17,1.01L7,1C5.9,1,5,1.9,5,3v18c0,1.1,0.9,2,2,2h10c1.1,0,2-0.9,2-2V3C19,1.9,18.1,1.01,17,1.01z M17,19H7V5h10V19z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 12 7 C 12.6903559373 7 13.25 7.55964406271 13.25 8.25 C 13.25 8.94035593729 12.6903559373 9.5 12 9.5 C 11.3096440627 9.5 10.75 8.94035593729 10.75 8.25 C 10.75 7.55964406271 11.3096440627 7 12 7 Z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M12,11c-0.55,0-1,0.4-1,0.9v4.21c0,0.5,0.45,0.9,1,0.9s1-0.4,1-0.9V11.9C13,11.4,12.55,11,12,11z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_accessibility.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_accessibility.xml
index 762b7d4..db45638 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_accessibility.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_accessibility.xml
@@ -20,18 +20,18 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M20.76,5.02l-0.02-0.06c-0.13-0.53-0.67-0.85-1.2-0.73C17.16,4.77,14.49,5,12,5S6.84,4.77,4.46,4.24 c-0.54-0.12-1.07,0.19-1.2,0.73L3.24,5.02C3.11,5.56,3.43,6.12,3.97,6.24C5.59,6.61,7.34,6.86,9,7v12c0,0.55,0.45,1,1,1 s1-0.45,1-1v-5h2v5c0,0.55,0.45,1,1,1s1-0.45,1-1V7c1.66-0.14,3.41-0.39,5.03-0.76C20.57,6.12,20.89,5.56,20.76,5.02z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 12 0 C 13.1045694997 0 14 0.895430500338 14 2 C 14 3.10456949966 13.1045694997 4 12 4 C 10.8954305003 4 10 3.10456949966 10 2 C 10 0.895430500338 10.8954305003 0 12 0 Z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 12 22 C 12.5522847498 22 13 22.4477152502 13 23 C 13 23.5522847498 12.5522847498 24 12 24 C 11.4477152502 24 11 23.5522847498 11 23 C 11 22.4477152502 11.4477152502 22 12 22 Z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 16 22 C 16.5522847498 22 17 22.4477152502 17 23 C 17 23.5522847498 16.5522847498 24 16 24 C 15.4477152502 24 15 23.5522847498 15 23 C 15 22.4477152502 15.4477152502 22 16 22 Z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 8 22 C 8.55228474983 22 9 22.4477152502 9 23 C 9 23.5522847498 8.55228474983 24 8 24 C 7.44771525017 24 7 23.5522847498 7 23 C 7 22.4477152502 7.44771525017 22 8 22 Z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_accounts.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_accounts.xml
index 5409d0d..0d4a244 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_accounts.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_accounts.xml
@@ -20,6 +20,6 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M19,3H5C3.9,3,3,3.9,3,5v14c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2V5C21,3.9,20.1,3,19,3z M12,6c1.93,0,3.5,1.57,3.5,3.5 S13.93,13,12,13s-3.5-1.57-3.5-3.5S10.07,6,12,6z M19,19H5v-1.36c0-0.74,0.41-1.44,1.07-1.77C7.24,15.28,9.3,14.5,12,14.5 s4.76,0.78,5.93,1.37C18.59,16.2,19,16.9,19,17.64V19z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_battery_white.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_battery_white.xml
index 0fea7ae..bb11388 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_battery_white.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_battery_white.xml
@@ -20,6 +20,6 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M10,2v2H8.33C7.6,4,7,4.6,7,5.33v15.33C7,21.4,7.6,22,8.33,22h7.33C16.4,22,17,21.4,17,20.67V5.33C17,4.6,16.4,4,15.67,4 H14V2H10z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_display_white.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_display_white.xml
index b75787b..2c931e4 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_display_white.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_display_white.xml
@@ -20,6 +20,6 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M4,15.3V19c0,0.55,0.45,1,1,1h3.69l2.6,2.6c0.39,0.39,1.02,0.39,1.41,0l2.6-2.6H19c0.55,0,1-0.45,1-1v-3.69l2.6-2.6 c0.39-0.39,0.39-1.02,0-1.41L20,8.69V5c0-0.55-0.45-1-1-1h-3.69l-2.6-2.6c-0.39-0.39-1.02-0.39-1.41,0L8.69,4H5C4.45,4,4,4.45,4,5 v3.69l-2.6,2.6c-0.39,0.39-0.39,1.02,0,1.41L4,15.3z M12,6c3.31,0,6,2.69,6,6s-2.69,6-6,6V6z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_location.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_location.xml
index ecab3a3..8732ea5 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_location.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_location.xml
@@ -20,6 +20,6 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M12.77,21.11C14.58,18.92,19,13.17,19,9c0-3.87-3.13-7-7-7S5,5.13,5,9c0,4.17,4.42,9.92,6.24,12.11 C11.64,21.59,12.37,21.59,12.77,21.11z M9.5,9c0-1.38,1.12-2.5,2.5-2.5s2.5,1.12,2.5,2.5c0,1.38-1.12,2.5-2.5,2.5S9.5,10.38,9.5,9z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_privacy.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_privacy.xml
index 4404530..2ebdc8f 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_privacy.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_privacy.xml
@@ -20,12 +20,12 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M16.48,11.7c0.74-0.44,1.6-0.7,2.52-0.7h3.78C20.93,6.88,16.81,4,12,4C7,4,2.73,7.11,1,11.5C2.73,15.89,7,19,12,19 c0.68,0,1.35-0.06,2-0.17V16c0-0.18,0.03-0.34,0.05-0.51C13.43,15.8,12.74,16,12,16c-2.49,0-4.5-2.01-4.5-4.5 C7.5,9.01,9.51,7,12,7s4.5,2.01,4.5,4.5C16.5,11.57,16.48,11.64,16.48,11.7z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 12 9 C 13.3807118746 9 14.5 10.1192881254 14.5 11.5 C 14.5 12.8807118746 13.3807118746 14 12 14 C 10.6192881254 14 9.5 12.8807118746 9.5 11.5 C 9.5 10.1192881254 10.6192881254 9 12 9 Z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M22,16v-0.5c0-1.4-1.1-2.5-2.5-2.5S17,14.1,17,15.5V16c-0.5,0-1,0.5-1,1v4c0,0.5,0.5,1,1,1h5c0.5,0,1-0.5,1-1v-4 C23,16.5,22.5,16,22,16z M20.5,16h-2v-0.5c0-0.53,0.47-1,1-1s1,0.47,1,1V16z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_security_white.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_security_white.xml
index 86147c2..ecaed01 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_security_white.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_security_white.xml
@@ -20,6 +20,6 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M18,1c-2.21,0-4,1.79-4,4v3H6c-1.1,0-2,0.9-2,2v10c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2V10c0-1.1-0.9-2-2-2h-2V5 c0-1.1,0.9-2,2-2s2,0.9,2,2c0,0.55,0.45,1,1,1s1-0.45,1-1C22,2.79,20.21,1,18,1z M12,17c-1.1,0-2-0.9-2-2c0-1.1,0.9-2,2-2 s2,0.9,2,2C14,16.1,13.1,17,12,17z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml
index ce233b7..659a926 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml
@@ -20,6 +20,6 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M12,2C6.48,2,2,6.48,2,12c0,5.52,4.48,10,10,10s10-4.48,10-10C22,6.48,17.52,2,12,2z M13,17c0,0.55-0.45,1-1,1s-1-0.45-1-1 v-5c0-0.55,0.45-1,1-1s1,0.45,1,1V17z M12,9.25c-0.69,0-1.25-0.56-1.25-1.25S11.31,6.75,12,6.75S13.25,7.31,13.25,8 S12.69,9.25,12,9.25z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_wireless.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_wireless.xml
index 92dbd29..6e80d13 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_wireless.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_wireless.xml
@@ -21,12 +21,12 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M11.29,19.29c0.39,0.39,1.03,0.4,1.42,0L14,18c0.47-0.47,0.38-1.28-0.22-1.58C13.25,16.15,12.64,16,12,16 c-0.64,0-1.24,0.15-1.77,0.41c-0.59,0.29-0.69,1.11-0.22,1.58L11.29,19.29z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M17.6,14.39l0.71-0.71c0.42-0.42,0.39-1.12-0.08-1.5C16.52,10.82,14.35,10,12,10c-2.34,0-4.5,0.81-6.21,2.17 c-0.47,0.37-0.51,1.07-0.09,1.49l0.71,0.71c0.35,0.36,0.92,0.39,1.32,0.08C8.91,13.54,10.39,13,12,13c1.61,0,3.1,0.55,4.29,1.47 C16.69,14.78,17.25,14.75,17.6,14.39z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M21.83,10.16l0.71-0.71c0.42-0.42,0.38-1.09-0.06-1.48C19.68,5.5,16.01,4,12,4C8.01,4,4.36,5.49,1.56,7.94 C1.12,8.33,1.08,9,1.49,9.41l0.71,0.71c0.37,0.37,0.96,0.4,1.35,0.06C5.81,8.2,8.77,7,12,7c3.25,0,6.22,1.22,8.49,3.22 C20.88,10.56,21.47,10.53,21.83,10.16z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_storage_white.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_storage_white.xml
index 03780db..9eb336c 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_storage_white.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_storage_white.xml
@@ -20,12 +20,12 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M19,10H5c-1.1,0-2,0.9-2,2c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2C21,10.9,20.1,10,19,10z M6,13.1c-0.61,0-1.1-0.49-1.1-1.1 s0.49-1.1,1.1-1.1s1.1,0.49,1.1,1.1S6.61,13.1,6,13.1z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M21,18c0-1.1-0.9-2-2-2H5c-1.1,0-2,0.9-2,2c0,1.1,0.9,2,2,2h14C20.1,20,21,19.1,21,18z M6,19.1c-0.61,0-1.1-0.49-1.1-1.1 s0.49-1.1,1.1-1.1s1.1,0.49,1.1,1.1S6.61,19.1,6,19.1z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M19,4H5C3.9,4,3,4.9,3,6c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2C21,4.9,20.1,4,19,4z M6,7.1C5.39,7.1,4.9,6.61,4.9,6 S5.39,4.9,6,4.9S7.1,5.39,7.1,6S6.61,7.1,6,7.1z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_volume_up_24dp.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_volume_up_24dp.xml
index 863df71..b940351 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_volume_up_24dp.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_volume_up_24dp.xml
@@ -20,12 +20,12 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M20.4,8.78c-0.91-2.39-2.8-4.27-5.18-5.18C14.63,3.37,14,3.83,14,4.46v0.19c0,0.38,0.25,0.71,0.61,0.85 C17.18,6.54,19,9.06,19,12s-1.82,5.46-4.39,6.5C14.25,18.64,14,18.97,14,19.35v0.19c0,0.63,0.63,1.08,1.22,0.86 C19.86,18.62,22.18,13.42,20.4,8.78z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M16.5,12c0-1.71-0.97-3.27-2.5-4.03v8.05C15.48,15.29,16.5,13.77,16.5,12z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M10.29,5.7L7,9H4c-0.55,0-1,0.45-1,1v4c0,0.55,0.45,1,1,1h3l3.29,3.29c0.63,0.63,1.71,0.18,1.71-0.71V6.41 C12,5.52,10.92,5.07,10.29,5.7z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_apps.xml b/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_apps.xml
index 58999d0..5b1850f 100644
--- a/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_apps.xml
+++ b/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_apps.xml
@@ -14,13 +14,13 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M 6 4 C 7.10456949966 4 8 4.89543050034 8 6 C 8 7.10456949966 7.10456949966 8 6 8 C 4.89543050034 8 4 7.10456949966 4 6 C 4 4.89543050034 4.89543050034 4 6 4 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 12 4 C 13.1045694997 4 14 4.89543050034 14 6 C 14 7.10456949966 13.1045694997 8 12 8 C 10.8954305003 8 10 7.10456949966 10 6 C 10 4.89543050034 10.8954305003 4 12 4 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 18 4 C 19.1045694997 4 20 4.89543050034 20 6 C 20 7.10456949966 19.1045694997 8 18 8 C 16.8954305003 8 16 7.10456949966 16 6 C 16 4.89543050034 16.8954305003 4 18 4 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 6 10 C 7.10456949966 10 8 10.8954305003 8 12 C 8 13.1045694997 7.10456949966 14 6 14 C 4.89543050034 14 4 13.1045694997 4 12 C 4 10.8954305003 4.89543050034 10 6 10 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 12 10 C 13.1045694997 10 14 10.8954305003 14 12 C 14 13.1045694997 13.1045694997 14 12 14 C 10.8954305003 14 10 13.1045694997 10 12 C 10 10.8954305003 10.8954305003 10 12 10 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 18 10 C 19.1045694997 10 20 10.8954305003 20 12 C 20 13.1045694997 19.1045694997 14 18 14 C 16.8954305003 14 16 13.1045694997 16 12 C 16 10.8954305003 16.8954305003 10 18 10 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 6 16 C 7.10456949966 16 8 16.8954305003 8 18 C 8 19.1045694997 7.10456949966 20 6 20 C 4.89543050034 20 4 19.1045694997 4 18 C 4 16.8954305003 4.89543050034 16 6 16 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 12 16 C 13.1045694997 16 14 16.8954305003 14 18 C 14 19.1045694997 13.1045694997 20 12 20 C 10.8954305003 20 10 19.1045694997 10 18 C 10 16.8954305003 10.8954305003 16 12 16 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 18 16 C 19.1045694997 16 20 16.8954305003 20 18 C 20 19.1045694997 19.1045694997 20 18 20 C 16.8954305003 20 16 19.1045694997 16 18 C 16 16.8954305003 16.8954305003 16 18 16 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 6 4 C 7.10456949966 4 8 4.89543050034 8 6 C 8 7.10456949966 7.10456949966 8 6 8 C 4.89543050034 8 4 7.10456949966 4 6 C 4 4.89543050034 4.89543050034 4 6 4 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 12 4 C 13.1045694997 4 14 4.89543050034 14 6 C 14 7.10456949966 13.1045694997 8 12 8 C 10.8954305003 8 10 7.10456949966 10 6 C 10 4.89543050034 10.8954305003 4 12 4 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 18 4 C 19.1045694997 4 20 4.89543050034 20 6 C 20 7.10456949966 19.1045694997 8 18 8 C 16.8954305003 8 16 7.10456949966 16 6 C 16 4.89543050034 16.8954305003 4 18 4 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 6 10 C 7.10456949966 10 8 10.8954305003 8 12 C 8 13.1045694997 7.10456949966 14 6 14 C 4.89543050034 14 4 13.1045694997 4 12 C 4 10.8954305003 4.89543050034 10 6 10 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 12 10 C 13.1045694997 10 14 10.8954305003 14 12 C 14 13.1045694997 13.1045694997 14 12 14 C 10.8954305003 14 10 13.1045694997 10 12 C 10 10.8954305003 10.8954305003 10 12 10 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 18 10 C 19.1045694997 10 20 10.8954305003 20 12 C 20 13.1045694997 19.1045694997 14 18 14 C 16.8954305003 14 16 13.1045694997 16 12 C 16 10.8954305003 16.8954305003 10 18 10 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 6 16 C 7.10456949966 16 8 16.8954305003 8 18 C 8 19.1045694997 7.10456949966 20 6 20 C 4.89543050034 20 4 19.1045694997 4 18 C 4 16.8954305003 4.89543050034 16 6 16 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 12 16 C 13.1045694997 16 14 16.8954305003 14 18 C 14 19.1045694997 13.1045694997 20 12 20 C 10.8954305003 20 10 19.1045694997 10 18 C 10 16.8954305003 10.8954305003 16 12 16 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 18 16 C 19.1045694997 16 20 16.8954305003 20 18 C 20 19.1045694997 19.1045694997 20 18 20 C 16.8954305003 20 16 19.1045694997 16 18 C 16 16.8954305003 16.8954305003 16 18 16 Z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_devices_other.xml b/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_devices_other.xml
index fa91107..954ff32 100644
--- a/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_devices_other.xml
+++ b/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_devices_other.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
<vector android:autoMirrored="true" android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M2.51,17.74V6.27c0-0.41,0.34-0.75,0.75-0.75H21v-1.5H3.26c-1.24,0-2.25,1.01-2.25,2.25v11.46c0,1.24,1.01,2.25,2.25,2.25 H7v-1.5H3.26C2.85,18.49,2.51,18.15,2.51,17.74z"/>
- <path android:fillColor="@android:color/white" android:pathData="M20.75,8h-3.5C16.01,8,15,9.01,15,10.25v7.5c0,1.24,1.01,2.25,2.25,2.25h3.5c1.24,0,2.25-1.01,2.25-2.25v-7.5 C23,9.01,21.99,8,20.75,8z M21.5,17.75c0,0.41-0.34,0.75-0.75,0.75h-3.5c-0.41,0-0.75-0.34-0.75-0.75v-7.5 c0-0.41,0.34-0.75,0.75-0.75h3.5c0.41,0,0.75,0.34,0.75,0.75V17.75z"/>
- <path android:fillColor="@android:color/white" android:pathData="M13,13.84v-1.09c0-0.41-0.34-0.75-0.75-0.75h-2.5C9.34,12,9,12.34,9,12.75v1.09C8.54,14.25,8.18,14.92,8.18,16 c0,1.09,0.36,1.75,0.82,2.16v1.09C9,19.66,9.34,20,9.75,20h2.5c0.41,0,0.75-0.34,0.75-0.75v-1.09c0.46-0.41,0.82-1.08,0.82-2.16 C13.82,14.91,13.46,14.25,13,13.84z M11,17.25C10.03,17.26,9.75,16.9,9.75,16c0-0.9,0.3-1.25,1.25-1.25 c0.95-0.01,1.25,0.33,1.25,1.25C12.25,16.84,11.98,17.25,11,17.25z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M2.51,17.74V6.27c0-0.41,0.34-0.75,0.75-0.75H21v-1.5H3.26c-1.24,0-2.25,1.01-2.25,2.25v11.46c0,1.24,1.01,2.25,2.25,2.25 H7v-1.5H3.26C2.85,18.49,2.51,18.15,2.51,17.74z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M20.75,8h-3.5C16.01,8,15,9.01,15,10.25v7.5c0,1.24,1.01,2.25,2.25,2.25h3.5c1.24,0,2.25-1.01,2.25-2.25v-7.5 C23,9.01,21.99,8,20.75,8z M21.5,17.75c0,0.41-0.34,0.75-0.75,0.75h-3.5c-0.41,0-0.75-0.34-0.75-0.75v-7.5 c0-0.41,0.34-0.75,0.75-0.75h3.5c0.41,0,0.75,0.34,0.75,0.75V17.75z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M13,13.84v-1.09c0-0.41-0.34-0.75-0.75-0.75h-2.5C9.34,12,9,12.34,9,12.75v1.09C8.54,14.25,8.18,14.92,8.18,16 c0,1.09,0.36,1.75,0.82,2.16v1.09C9,19.66,9.34,20,9.75,20h2.5c0.41,0,0.75-0.34,0.75-0.75v-1.09c0.46-0.41,0.82-1.08,0.82-2.16 C13.82,14.91,13.46,14.25,13,13.84z M11,17.25C10.03,17.26,9.75,16.9,9.75,16c0-0.9,0.3-1.25,1.25-1.25 c0.95-0.01,1.25,0.33,1.25,1.25C12.25,16.84,11.98,17.25,11,17.25z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_help.xml b/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_help.xml
index 8ab01a6..89b8031 100644
--- a/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_help.xml
+++ b/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_help.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M13.73,6.41c-0.51-0.27-1.09-0.4-1.74-0.4c-0.87,0-1.58,0.24-2.13,0.73C9.31,7.22,8.91,7.78,8.67,8.42l1.29,0.54 c0.16-0.46,0.41-0.84,0.73-1.16c0.32-0.31,0.76-0.47,1.3-0.47c0.6,0,1.07,0.16,1.41,0.48c0.34,0.32,0.51,0.75,0.51,1.27 c0,0.39-0.1,0.73-0.29,1.01c-0.19,0.28-0.51,0.61-0.94,1.01c-0.54,0.5-0.91,0.93-1.11,1.29c-0.21,0.36-0.31,0.81-0.31,1.36v0.79 h1.43v-0.69c0-0.39,0.08-0.74,0.25-1.03c0.16-0.29,0.43-0.61,0.79-0.93c0.47-0.43,0.85-0.85,1.15-1.27 c0.3-0.42,0.45-0.93,0.45-1.53c0-0.58-0.14-1.1-0.42-1.57C14.63,7.05,14.24,6.68,13.73,6.41z"/>
- <path android:fillColor="@android:color/white" android:pathData="M11.98,15.96c-0.03,0-1-0.06-1,1c0,1.06,0.96,1,1,1c0.03,0,1,0.06,1-1C12.98,15.9,12.02,15.96,11.98,15.96z"/>
- <path android:fillColor="@android:color/white" android:pathData="M12,2C4.41,2,2,6.9,2,12c0,5.09,2.35,10,10,10c7.59,0,10-4.9,10-10C22,6.91,19.65,2,12,2z M12,20.5 c-2.64,0.05-8.5-0.59-8.5-8.5c0-7.91,5.88-8.55,8.5-8.5c2.64-0.05,8.5,0.59,8.5,8.5C20.5,19.91,14.62,20.55,12,20.5z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M13.73,6.41c-0.51-0.27-1.09-0.4-1.74-0.4c-0.87,0-1.58,0.24-2.13,0.73C9.31,7.22,8.91,7.78,8.67,8.42l1.29,0.54 c0.16-0.46,0.41-0.84,0.73-1.16c0.32-0.31,0.76-0.47,1.3-0.47c0.6,0,1.07,0.16,1.41,0.48c0.34,0.32,0.51,0.75,0.51,1.27 c0,0.39-0.1,0.73-0.29,1.01c-0.19,0.28-0.51,0.61-0.94,1.01c-0.54,0.5-0.91,0.93-1.11,1.29c-0.21,0.36-0.31,0.81-0.31,1.36v0.79 h1.43v-0.69c0-0.39,0.08-0.74,0.25-1.03c0.16-0.29,0.43-0.61,0.79-0.93c0.47-0.43,0.85-0.85,1.15-1.27 c0.3-0.42,0.45-0.93,0.45-1.53c0-0.58-0.14-1.1-0.42-1.57C14.63,7.05,14.24,6.68,13.73,6.41z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M11.98,15.96c-0.03,0-1-0.06-1,1c0,1.06,0.96,1,1,1c0.03,0,1,0.06,1-1C12.98,15.9,12.02,15.96,11.98,15.96z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M12,2C4.41,2,2,6.9,2,12c0,5.09,2.35,10,10,10c7.59,0,10-4.9,10-10C22,6.91,19.65,2,12,2z M12,20.5 c-2.64,0.05-8.5-0.59-8.5-8.5c0-7.91,5.88-8.55,8.5-8.5c2.64-0.05,8.5,0.59,8.5,8.5C20.5,19.91,14.62,20.55,12,20.5z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_phone_info.xml b/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_phone_info.xml
index 2edda9c..e2246ce 100644
--- a/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_phone_info.xml
+++ b/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_phone_info.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M16.75,1h-9.5C6.01,1,5,2.01,5,3.25v17.5C5,21.99,6.01,23,7.25,23h9.5c1.24,0,2.25-1.01,2.25-2.25V3.25 C19,2.01,17.99,1,16.75,1z M7.25,2.5h9.5c0.41,0,0.75,0.34,0.75,0.75v1h-11v-1C6.5,2.84,6.84,2.5,7.25,2.5z M17.5,5.75v12.5h-11 V5.75H17.5z M16.75,21.5h-9.5c-0.41,0-0.75-0.34-0.75-0.75v-1h11v1C17.5,21.16,17.16,21.5,16.75,21.5z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 11.25 11 H 12.75 V 16 H 11.25 V 11 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 12 8 C 12.4142135624 8 12.75 8.33578643763 12.75 8.75 C 12.75 9.16421356237 12.4142135624 9.5 12 9.5 C 11.5857864376 9.5 11.25 9.16421356237 11.25 8.75 C 11.25 8.33578643763 11.5857864376 8 12 8 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M16.75,1h-9.5C6.01,1,5,2.01,5,3.25v17.5C5,21.99,6.01,23,7.25,23h9.5c1.24,0,2.25-1.01,2.25-2.25V3.25 C19,2.01,17.99,1,16.75,1z M7.25,2.5h9.5c0.41,0,0.75,0.34,0.75,0.75v1h-11v-1C6.5,2.84,6.84,2.5,7.25,2.5z M17.5,5.75v12.5h-11 V5.75H17.5z M16.75,21.5h-9.5c-0.41,0-0.75-0.34-0.75-0.75v-1h11v1C17.5,21.16,17.16,21.5,16.75,21.5z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 11.25 11 H 12.75 V 16 H 11.25 V 11 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 12 8 C 12.4142135624 8 12.75 8.33578643763 12.75 8.75 C 12.75 9.16421356237 12.4142135624 9.5 12 9.5 C 11.5857864376 9.5 11.25 9.16421356237 11.25 8.75 C 11.25 8.33578643763 11.5857864376 8 12 8 Z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_settings_accessibility.xml b/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_settings_accessibility.xml
index 900a3a6..a92595b 100644
--- a/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_settings_accessibility.xml
+++ b/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_settings_accessibility.xml
@@ -14,9 +14,9 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M 8 22 C 8.55228474983 22 9 22.4477152502 9 23 C 9 23.5522847498 8.55228474983 24 8 24 C 7.44771525017 24 7 23.5522847498 7 23 C 7 22.4477152502 7.44771525017 22 8 22 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 12 22 C 12.5522847498 22 13 22.4477152502 13 23 C 13 23.5522847498 12.5522847498 24 12 24 C 11.4477152502 24 11 23.5522847498 11 23 C 11 22.4477152502 11.4477152502 22 12 22 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 16 22 C 16.5522847498 22 17 22.4477152502 17 23 C 17 23.5522847498 16.5522847498 24 16 24 C 15.4477152502 24 15 23.5522847498 15 23 C 15 22.4477152502 15.4477152502 22 16 22 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 12 0 C 13.1045694997 0 14 0.895430500338 14 2 C 14 3.10456949966 13.1045694997 4 12 4 C 10.8954305003 4 10 3.10456949966 10 2 C 10 0.895430500338 10.8954305003 0 12 0 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M15,20V7c2-0.17,4.14-0.5,6-1l-0.5-2c-2.61,0.7-5.67,1-8.5,1S6.11,4.7,3.5,4L3,6c1.86,0.5,4,0.83,6,1v13h2v-6h2v6H15z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 8 22 C 8.55228474983 22 9 22.4477152502 9 23 C 9 23.5522847498 8.55228474983 24 8 24 C 7.44771525017 24 7 23.5522847498 7 23 C 7 22.4477152502 7.44771525017 22 8 22 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 12 22 C 12.5522847498 22 13 22.4477152502 13 23 C 13 23.5522847498 12.5522847498 24 12 24 C 11.4477152502 24 11 23.5522847498 11 23 C 11 22.4477152502 11.4477152502 22 12 22 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 16 22 C 16.5522847498 22 17 22.4477152502 17 23 C 17 23.5522847498 16.5522847498 24 16 24 C 15.4477152502 24 15 23.5522847498 15 23 C 15 22.4477152502 15.4477152502 22 16 22 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 12 0 C 13.1045694997 0 14 0.895430500338 14 2 C 14 3.10456949966 13.1045694997 4 12 4 C 10.8954305003 4 10 3.10456949966 10 2 C 10 0.895430500338 10.8954305003 0 12 0 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M15,20V7c2-0.17,4.14-0.5,6-1l-0.5-2c-2.61,0.7-5.67,1-8.5,1S6.11,4.7,3.5,4L3,6c1.86,0.5,4,0.83,6,1v13h2v-6h2v6H15z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_settings_accounts.xml b/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_settings_accounts.xml
index 0a7ec3f..b17efd1 100644
--- a/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_settings_accounts.xml
+++ b/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_settings_accounts.xml
@@ -14,6 +14,6 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M18.75,3H5.25C4.01,3,3,4.01,3,5.25v13.5C3,19.99,4.01,21,5.25,21h13.5c1.24,0,2.25-1.01,2.25-2.25V5.25 C21,4.01,19.99,3,18.75,3z M18.75,19.5H5.25c-0.35,0-0.64-0.25-0.72-0.58C4.9,18.6,7.23,16.4,12,16.51 c4.77-0.11,7.11,2.1,7.47,2.41C19.39,19.25,19.1,19.5,18.75,19.5z M19.5,17.03c-3.24-2.22-7.05-2.02-7.5-2.02 c-0.46,0-4.27-0.19-7.5,2.02V5.25c0-0.41,0.34-0.75,0.75-0.75h13.5c0.41,0,0.75,0.34,0.75,0.75V17.03z"/>
- <path android:fillColor="@android:color/white" android:pathData="M12,6C9.33,6,8.5,7.73,8.5,9.5c0,1.78,0.83,3.5,3.5,3.5c2.67,0,3.5-1.73,3.5-3.5C15.5,7.72,14.67,6,12,6z M12,11.5 c-0.43,0.01-2,0.13-2-2c0-2.14,1.58-2,2-2c0.43-0.01,2-0.13,2,2C14,11.64,12.42,11.5,12,11.5z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M18.75,3H5.25C4.01,3,3,4.01,3,5.25v13.5C3,19.99,4.01,21,5.25,21h13.5c1.24,0,2.25-1.01,2.25-2.25V5.25 C21,4.01,19.99,3,18.75,3z M18.75,19.5H5.25c-0.35,0-0.64-0.25-0.72-0.58C4.9,18.6,7.23,16.4,12,16.51 c4.77-0.11,7.11,2.1,7.47,2.41C19.39,19.25,19.1,19.5,18.75,19.5z M19.5,17.03c-3.24-2.22-7.05-2.02-7.5-2.02 c-0.46,0-4.27-0.19-7.5,2.02V5.25c0-0.41,0.34-0.75,0.75-0.75h13.5c0.41,0,0.75,0.34,0.75,0.75V17.03z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M12,6C9.33,6,8.5,7.73,8.5,9.5c0,1.78,0.83,3.5,3.5,3.5c2.67,0,3.5-1.73,3.5-3.5C15.5,7.72,14.67,6,12,6z M12,11.5 c-0.43,0.01-2,0.13-2-2c0-2.14,1.58-2,2-2c0.43-0.01,2-0.13,2,2C14,11.64,12.42,11.5,12,11.5z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_settings_battery_white.xml b/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_settings_battery_white.xml
index cc80eb7..4af4806 100644
--- a/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_settings_battery_white.xml
+++ b/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_settings_battery_white.xml
@@ -14,5 +14,5 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M16,4h-1V2.5C15,2.22,14.78,2,14.5,2h-5C9.22,2,9,2.22,9,2.5V4H8C6.9,4,6,4.9,6,6v12c0,2.21,1.79,4,4,4h4 c2.21,0,4-1.79,4-4V6C18,4.9,17.1,4,16,4z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M16,4h-1V2.5C15,2.22,14.78,2,14.5,2h-5C9.22,2,9,2.22,9,2.5V4H8C6.9,4,6,4.9,6,6v12c0,2.21,1.79,4,4,4h4 c2.21,0,4-1.79,4-4V6C18,4.9,17.1,4,16,4z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_settings_display_white.xml b/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_settings_display_white.xml
index d4d4174..9eb8a0b 100644
--- a/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_settings_display_white.xml
+++ b/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_settings_display_white.xml
@@ -14,6 +14,6 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M12,7V17c0.17,0,5,0.31,5-5C17,6.7,12.22,7,12,7z"/>
- <path android:fillColor="@android:color/white" android:pathData="M22.78,11.47L20,8.69V4.75C20,4.34,19.66,4,19.25,4h-3.94l-2.78-2.78c-0.29-0.29-0.77-0.29-1.06,0L8.69,4H4.75 C4.34,4,4,4.34,4,4.75v3.94l-2.78,2.78c-0.29,0.29-0.29,0.77,0,1.06L4,15.31v3.94C4,19.66,4.34,20,4.75,20h3.94l2.78,2.78 C11.62,22.93,11.81,23,12,23s0.38-0.07,0.53-0.22L15.31,20h3.94c0.41,0,0.75-0.34,0.75-0.75v-3.94l2.78-2.78 C23.07,12.24,23.07,11.76,22.78,11.47z M18.72,14.47C18.58,14.61,18.5,14.8,18.5,15v3.5H15c-0.2,0-0.39,0.08-0.53,0.22L12,21.19 l-2.47-2.47C9.39,18.58,9.2,18.5,9,18.5H5.5V15c0-0.2-0.08-0.39-0.22-0.53L2.81,12l2.47-2.47C5.42,9.39,5.5,9.2,5.5,9V5.5H9 c0.2,0,0.39-0.08,0.53-0.22L12,2.81l2.47,2.47C14.61,5.42,14.8,5.5,15,5.5h3.5V9c0,0.2,0.08,0.39,0.22,0.53L21.19,12L18.72,14.47z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M12,7V17c0.17,0,5,0.31,5-5C17,6.7,12.22,7,12,7z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M22.78,11.47L20,8.69V4.75C20,4.34,19.66,4,19.25,4h-3.94l-2.78-2.78c-0.29-0.29-0.77-0.29-1.06,0L8.69,4H4.75 C4.34,4,4,4.34,4,4.75v3.94l-2.78,2.78c-0.29,0.29-0.29,0.77,0,1.06L4,15.31v3.94C4,19.66,4.34,20,4.75,20h3.94l2.78,2.78 C11.62,22.93,11.81,23,12,23s0.38-0.07,0.53-0.22L15.31,20h3.94c0.41,0,0.75-0.34,0.75-0.75v-3.94l2.78-2.78 C23.07,12.24,23.07,11.76,22.78,11.47z M18.72,14.47C18.58,14.61,18.5,14.8,18.5,15v3.5H15c-0.2,0-0.39,0.08-0.53,0.22L12,21.19 l-2.47-2.47C9.39,18.58,9.2,18.5,9,18.5H5.5V15c0-0.2-0.08-0.39-0.22-0.53L2.81,12l2.47-2.47C5.42,9.39,5.5,9.2,5.5,9V5.5H9 c0.2,0,0.39-0.08,0.53-0.22L12,2.81l2.47,2.47C14.61,5.42,14.8,5.5,15,5.5h3.5V9c0,0.2,0.08,0.39,0.22,0.53L21.19,12L18.72,14.47z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_settings_location.xml b/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_settings_location.xml
index 2d1de94..d437035 100644
--- a/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_settings_location.xml
+++ b/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_settings_location.xml
@@ -14,6 +14,6 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M12,6c-1.88,0-3,1.04-3,3c0,1.91,1.06,3,3,3c1.89,0,3-1.05,3-3C15,7.08,13.93,6,12,6z M12,10.5 c-1.15,0.01-1.5-0.47-1.5-1.5c0-1.06,0.37-1.5,1.5-1.5c1.15-0.01,1.5,0.47,1.5,1.5C13.5,10.09,13.1,10.5,12,10.5z"/>
- <path android:fillColor="@android:color/white" android:pathData="M11.99,2C9.69,1.94,5,2.93,5,9c0,6.88,6.23,12.56,6.5,12.8c0.14,0.13,0.32,0.2,0.5,0.2s0.36-0.06,0.5-0.2 C12.77,21.56,19,15.88,19,9C19,2.87,14.3,1.96,11.99,2z M12,20.2C10.55,18.7,6.5,14.12,6.5,9c0-4.91,3.63-5.55,5.44-5.5 C16.9,3.34,17.5,7.14,17.5,9C17.5,14.13,13.45,18.7,12,20.2z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M12,6c-1.88,0-3,1.04-3,3c0,1.91,1.06,3,3,3c1.89,0,3-1.05,3-3C15,7.08,13.93,6,12,6z M12,10.5 c-1.15,0.01-1.5-0.47-1.5-1.5c0-1.06,0.37-1.5,1.5-1.5c1.15-0.01,1.5,0.47,1.5,1.5C13.5,10.09,13.1,10.5,12,10.5z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M11.99,2C9.69,1.94,5,2.93,5,9c0,6.88,6.23,12.56,6.5,12.8c0.14,0.13,0.32,0.2,0.5,0.2s0.36-0.06,0.5-0.2 C12.77,21.56,19,15.88,19,9C19,2.87,14.3,1.96,11.99,2z M12,20.2C10.55,18.7,6.5,14.12,6.5,9c0-4.91,3.63-5.55,5.44-5.5 C16.9,3.34,17.5,7.14,17.5,9C17.5,14.13,13.45,18.7,12,20.2z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_settings_privacy.xml b/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_settings_privacy.xml
index b8e5a7d..28d111d 100644
--- a/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_settings_privacy.xml
+++ b/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_settings_privacy.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M22.74,11.4C20.87,7.33,16.77,4.5,12,4.5S3.13,7.33,1.26,11.4c-0.17,0.38-0.17,0.83,0,1.21c1.87,4.07,5.97,6.9,10.74,6.9 c0.68,0,1.35-0.06,2-0.18v-1.55C13.35,17.91,12.68,18,12,18c-4.02,0-7.7-2.36-9.38-5.98C4.3,8.36,7.98,6,12,6s7.7,2.36,9.38,5.98 c-0.08,0.17-0.19,0.33-0.28,0.5c0.47,0.22,0.9,0.51,1.27,0.85c0.13-0.24,0.25-0.48,0.37-0.73C22.92,12.22,22.92,11.78,22.74,11.4 z"/>
- <path android:fillColor="@android:color/white" android:pathData="M16.5,12c0-2.3-1.06-4.5-4.5-4.5c-3.43,0-4.5,2.22-4.5,4.5c0,2.3,1.06,4.5,4.5,4.5c0.83,0,1.52-0.14,2.09-0.36 c0.26-1.46,1.14-2.69,2.37-3.42C16.48,12.48,16.5,12.24,16.5,12z M12,15c-3.05,0.04-3-2.35-3-3c0-0.63-0.04-3.06,3-3 c3.05-0.04,3,2.35,3,3C15,12.63,15.04,15.06,12,15z"/>
- <path android:fillColor="@android:color/white" android:pathData="M21,17v-1c0-1.1-0.9-2-2-2s-2,0.9-2,2v1c-0.55,0-1,0.45-1,1v3c0,0.55,0.45,1,1,1h4c0.55,0,1-0.45,1-1v-3 C22,17.45,21.55,17,21,17z M18.5,16c0-0.28,0.22-0.5,0.5-0.5s0.5,0.22,0.5,0.5v1h-1V16z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M22.74,11.4C20.87,7.33,16.77,4.5,12,4.5S3.13,7.33,1.26,11.4c-0.17,0.38-0.17,0.83,0,1.21c1.87,4.07,5.97,6.9,10.74,6.9 c0.68,0,1.35-0.06,2-0.18v-1.55C13.35,17.91,12.68,18,12,18c-4.02,0-7.7-2.36-9.38-5.98C4.3,8.36,7.98,6,12,6s7.7,2.36,9.38,5.98 c-0.08,0.17-0.19,0.33-0.28,0.5c0.47,0.22,0.9,0.51,1.27,0.85c0.13-0.24,0.25-0.48,0.37-0.73C22.92,12.22,22.92,11.78,22.74,11.4 z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M16.5,12c0-2.3-1.06-4.5-4.5-4.5c-3.43,0-4.5,2.22-4.5,4.5c0,2.3,1.06,4.5,4.5,4.5c0.83,0,1.52-0.14,2.09-0.36 c0.26-1.46,1.14-2.69,2.37-3.42C16.48,12.48,16.5,12.24,16.5,12z M12,15c-3.05,0.04-3-2.35-3-3c0-0.63-0.04-3.06,3-3 c3.05-0.04,3,2.35,3,3C15,12.63,15.04,15.06,12,15z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M21,17v-1c0-1.1-0.9-2-2-2s-2,0.9-2,2v1c-0.55,0-1,0.45-1,1v3c0,0.55,0.45,1,1,1h4c0.55,0,1-0.45,1-1v-3 C22,17.45,21.55,17,21,17z M18.5,16c0-0.28,0.22-0.5,0.5-0.5s0.5,0.22,0.5,0.5v1h-1V16z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_settings_security_white.xml b/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_settings_security_white.xml
index 0475e33..7f654c1 100644
--- a/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_settings_security_white.xml
+++ b/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_settings_security_white.xml
@@ -14,6 +14,6 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M18.5,1C17.03,0.96,14,1.62,14,5.5v2.49H6.25C5.01,7.99,4,9,4,10.24v9.51C4,20.99,5.01,22,6.25,22h11.5 c1.24,0,2.25-1.01,2.25-2.25v-9.51c0-1.24-1.01-2.25-2.25-2.25H15.5V5.5c0-2.77,2-3.01,3.05-3c1.02-0.02,2.96,0.28,2.96,3V6H23 V5.5C23,1.6,19.97,0.96,18.5,1z M17.75,9.49c0.41,0,0.75,0.34,0.75,0.75v9.51c0,0.41-0.34,0.75-0.75,0.75H6.25 c-0.41,0-0.75-0.34-0.75-0.75v-9.51c0-0.41,0.34-0.75,0.75-0.75H17.75z"/>
- <path android:fillColor="@android:color/white" android:pathData="M12,17.74c0.13,0,2.75,0.06,2.75-2.75c0-2.34-1.85-2.77-2.74-2.75c-0.89-0.02-2.76,0.4-2.76,2.75 C9.25,17.41,11.19,17.74,12,17.74z M12.03,13.74c1.32-0.06,1.22,1.22,1.22,1.25c0,0.89-0.42,1.26-1.25,1.25 c-0.81,0.01-1.25-0.34-1.25-1.25C10.75,14.15,11.12,13.73,12.03,13.74z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M18.5,1C17.03,0.96,14,1.62,14,5.5v2.49H6.25C5.01,7.99,4,9,4,10.24v9.51C4,20.99,5.01,22,6.25,22h11.5 c1.24,0,2.25-1.01,2.25-2.25v-9.51c0-1.24-1.01-2.25-2.25-2.25H15.5V5.5c0-2.77,2-3.01,3.05-3c1.02-0.02,2.96,0.28,2.96,3V6H23 V5.5C23,1.6,19.97,0.96,18.5,1z M17.75,9.49c0.41,0,0.75,0.34,0.75,0.75v9.51c0,0.41-0.34,0.75-0.75,0.75H6.25 c-0.41,0-0.75-0.34-0.75-0.75v-9.51c0-0.41,0.34-0.75,0.75-0.75H17.75z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M12,17.74c0.13,0,2.75,0.06,2.75-2.75c0-2.34-1.85-2.77-2.74-2.75c-0.89-0.02-2.76,0.4-2.76,2.75 C9.25,17.41,11.19,17.74,12,17.74z M12.03,13.74c1.32-0.06,1.22,1.22,1.22,1.25c0,0.89-0.42,1.26-1.25,1.25 c-0.81,0.01-1.25-0.34-1.25-1.25C10.75,14.15,11.12,13.73,12.03,13.74z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml b/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml
index 0c0a682..70d3628 100644
--- a/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml
+++ b/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M 11.25 10 H 12.75 V 17 H 11.25 V 10 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 12 7 C 12.4142135624 7 12.75 7.33578643763 12.75 7.75 C 12.75 8.16421356237 12.4142135624 8.5 12 8.5 C 11.5857864376 8.5 11.25 8.16421356237 11.25 7.75 C 11.25 7.33578643763 11.5857864376 7 12 7 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M12,2C4.41,2,2,6.9,2,12c0,5.09,2.35,10,10,10c7.59,0,10-4.9,10-10C22,6.91,19.65,2,12,2z M12,20.5 c-2.64,0.05-8.5-0.59-8.5-8.5c0-7.91,5.88-8.55,8.5-8.5c2.64-0.05,8.5,0.59,8.5,8.5C20.5,19.91,14.62,20.55,12,20.5z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 11.25 10 H 12.75 V 17 H 11.25 V 10 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 12 7 C 12.4142135624 7 12.75 7.33578643763 12.75 7.75 C 12.75 8.16421356237 12.4142135624 8.5 12 8.5 C 11.5857864376 8.5 11.25 8.16421356237 11.25 7.75 C 11.25 7.33578643763 11.5857864376 7 12 7 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M12,2C4.41,2,2,6.9,2,12c0,5.09,2.35,10,10,10c7.59,0,10-4.9,10-10C22,6.91,19.65,2,12,2z M12,20.5 c-2.64,0.05-8.5-0.59-8.5-8.5c0-7.91,5.88-8.55,8.5-8.5c2.64-0.05,8.5,0.59,8.5,8.5C20.5,19.91,14.62,20.55,12,20.5z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_settings_wireless.xml b/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_settings_wireless.xml
index 2899c7f..63346a4 100644
--- a/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_settings_wireless.xml
+++ b/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_settings_wireless.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
<vector android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M12.14,6c4.29,0.06,7.79,2.34,9.81,4.05l1.07-1.07c-2.26-1.94-6.06-4.41-10.86-4.48C8.32,4.46,4.57,5.96,1,9l1.07,1.07 C5.33,7.32,8.72,5.95,12.14,6z"/>
- <path android:fillColor="@android:color/white" android:pathData="M11.97,11.5c0.04,0,0.08,0,0.12,0c2.54,0.04,4.67,1.25,6.07,2.34l1.08-1.08c-1.6-1.28-4.07-2.71-7.13-2.76 c-2.54-0.03-4.99,0.91-7.33,2.78l1.07,1.07C7.84,12.3,9.89,11.5,11.97,11.5z"/>
- <path android:fillColor="@android:color/white" android:pathData="M11.98,17.5c0.02,0,0.04,0,0.05,0c0.73,0.01,1.38,0.24,1.93,0.53l1.1-1.1c-0.79-0.49-1.81-0.92-3.01-0.93 c-1.07-0.01-2.12,0.31-3.12,0.94l1.1,1.1C10.68,17.69,11.33,17.5,11.98,17.5z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M12.14,6c4.29,0.06,7.79,2.34,9.81,4.05l1.07-1.07c-2.26-1.94-6.06-4.41-10.86-4.48C8.32,4.46,4.57,5.96,1,9l1.07,1.07 C5.33,7.32,8.72,5.95,12.14,6z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M11.97,11.5c0.04,0,0.08,0,0.12,0c2.54,0.04,4.67,1.25,6.07,2.34l1.08-1.08c-1.6-1.28-4.07-2.71-7.13-2.76 c-2.54-0.03-4.99,0.91-7.33,2.78l1.07,1.07C7.84,12.3,9.89,11.5,11.97,11.5z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M11.98,17.5c0.02,0,0.04,0,0.05,0c0.73,0.01,1.38,0.24,1.93,0.53l1.1-1.1c-0.79-0.49-1.81-0.92-3.01-0.93 c-1.07-0.01-2.12,0.31-3.12,0.94l1.1,1.1C10.68,17.69,11.33,17.5,11.98,17.5z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_storage_white.xml b/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_storage_white.xml
index 7b5d946..0ef8a7c 100644
--- a/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_storage_white.xml
+++ b/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_storage_white.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M20,4H4C3.45,4,3,4.45,3,5v2c0,0.55,0.45,1,1,1h16c0.55,0,1-0.45,1-1V5C21,4.45,20.55,4,20,4z M6,7C5.96,7,5,7.06,5,6 c0-1.06,0.97-1,1-1c0.04,0,1-0.06,1,1C7,7.06,6.03,7,6,7z"/>
- <path android:fillColor="@android:color/white" android:pathData="M20,10H4c-0.55,0-1,0.45-1,1v2c0,0.55,0.45,1,1,1h16c0.55,0,1-0.45,1-1v-2C21,10.45,20.55,10,20,10z M6,13 c-0.04,0-1,0.06-1-1c0-1.06,0.97-1,1-1c0.04,0,1-0.06,1,1C7,13.06,6.03,13,6,13z"/>
- <path android:fillColor="@android:color/white" android:pathData="M20,16H4c-0.55,0-1,0.45-1,1v2c0,0.55,0.45,1,1,1h16c0.55,0,1-0.45,1-1v-2C21,16.45,20.55,16,20,16z M6,19 c-0.04,0-1,0.06-1-1c0-1.06,0.97-1,1-1c0.04,0,1-0.06,1,1C7,19.06,6.03,19,6,19z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M20,4H4C3.45,4,3,4.45,3,5v2c0,0.55,0.45,1,1,1h16c0.55,0,1-0.45,1-1V5C21,4.45,20.55,4,20,4z M6,7C5.96,7,5,7.06,5,6 c0-1.06,0.97-1,1-1c0.04,0,1-0.06,1,1C7,7.06,6.03,7,6,7z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M20,10H4c-0.55,0-1,0.45-1,1v2c0,0.55,0.45,1,1,1h16c0.55,0,1-0.45,1-1v-2C21,10.45,20.55,10,20,10z M6,13 c-0.04,0-1,0.06-1-1c0-1.06,0.97-1,1-1c0.04,0,1-0.06,1,1C7,13.06,6.03,13,6,13z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M20,16H4c-0.55,0-1,0.45-1,1v2c0,0.55,0.45,1,1,1h16c0.55,0,1-0.45,1-1v-2C21,16.45,20.55,16,20,16z M6,19 c-0.04,0-1,0.06-1-1c0-1.06,0.97-1,1-1c0.04,0,1-0.06,1,1C7,19.06,6.03,19,6,19z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_volume_up_24dp.xml b/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_volume_up_24dp.xml
index 019fed9..b9753f5 100644
--- a/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_volume_up_24dp.xml
+++ b/packages/overlays/IconPackKaiSettingsOverlay/res/drawable/ic_volume_up_24dp.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M14,3.3v1.58c2.35,0.89,5.55,3.95,5.5,7.18c-0.06,3.65-3.79,6.41-5.5,7.05v1.58c1.12-0.33,6.92-3.18,7-8.61 C21.07,7.39,16.32,3.99,14,3.3z"/>
- <path android:fillColor="@android:color/white" android:pathData="M16.5,12.05c0.01-0.53-0.02-2.55-2.5-4.54v9C15.72,15.12,16.48,13.52,16.5,12.05z"/>
- <path android:fillColor="@android:color/white" android:pathData="M9.86,6.08L6.95,9H6c-2.56,0-3.02,2.02-3,2.99C2.97,12.96,3.44,15,6,15h0.95l2.91,2.92C10.69,18.75,12,18.1,12,17.04V6.96 C12,5.85,10.65,5.29,9.86,6.08z M10.5,16.43l-2.7-2.71c-0.14-0.14-0.33-0.22-0.53-0.22H6c-1.42,0-1.51-0.99-1.5-1.54 C4.47,10.73,5.29,10.5,6,10.5h1.26c0.2,0,0.39-0.08,0.53-0.22l2.7-2.71V16.43z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M14,3.3v1.58c2.35,0.89,5.55,3.95,5.5,7.18c-0.06,3.65-3.79,6.41-5.5,7.05v1.58c1.12-0.33,6.92-3.18,7-8.61 C21.07,7.39,16.32,3.99,14,3.3z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M16.5,12.05c0.01-0.53-0.02-2.55-2.5-4.54v9C15.72,15.12,16.48,13.52,16.5,12.05z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M9.86,6.08L6.95,9H6c-2.56,0-3.02,2.02-3,2.99C2.97,12.96,3.44,15,6,15h0.95l2.91,2.92C10.69,18.75,12,18.1,12,17.04V6.96 C12,5.85,10.65,5.29,9.86,6.08z M10.5,16.43l-2.7-2.71c-0.14-0.14-0.33-0.22-0.53-0.22H6c-1.42,0-1.51-0.99-1.5-1.54 C4.47,10.73,5.29,10.5,6,10.5h1.26c0.2,0,0.39-0.08,0.53-0.22l2.7-2.71V16.43z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/AndroidManifest.xml b/packages/overlays/IconPackRoundedLauncherOverlay/AndroidManifest.xml
index 8406f42..8219b29 100644
--- a/packages/overlays/IconPackRoundedLauncherOverlay/AndroidManifest.xml
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/AndroidManifest.xml
@@ -19,6 +19,6 @@
package="com.android.theme.icon_pack.rounded.launcher"
android:versionCode="1"
android:versionName="1.0">
- <overlay android:targetPackage="com.android.launcher3" android:category="android.theme.customization.icon_pack.launcher" android:priority="1"/>
+ <overlay android:targetPackage="com.google.android.apps.nexuslauncher" android:category="android.theme.customization.icon_pack.launcher" android:priority="1"/>
<application android:label="Rounded" android:hasCode="false"/>
</manifest>
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_apps.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_apps.xml
index fd71322..8db613d 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_apps.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_apps.xml
@@ -20,30 +20,30 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M6.5,4h-1C4.67,4,4,4.67,4,5.5v1C4,7.33,4.67,8,5.5,8h1C7.33,8,8,7.33,8,6.5v-1C8,4.67,7.33,4,6.5,4z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M12.5,4h-1C10.67,4,10,4.67,10,5.5v1C10,7.33,10.67,8,11.5,8h1C13.33,8,14,7.33,14,6.5v-1C14,4.67,13.33,4,12.5,4z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M18.5,4h-1C16.67,4,16,4.67,16,5.5v1C16,7.33,16.67,8,17.5,8h1C19.33,8,20,7.33,20,6.5v-1C20,4.67,19.33,4,18.5,4z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M6.5,10h-1C4.67,10,4,10.67,4,11.5v1C4,13.33,4.67,14,5.5,14h1C7.33,14,8,13.33,8,12.5v-1C8,10.67,7.33,10,6.5,10z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M12.5,10h-1c-0.83,0-1.5,0.67-1.5,1.5v1c0,0.83,0.67,1.5,1.5,1.5h1c0.83,0,1.5-0.67,1.5-1.5v-1C14,10.67,13.33,10,12.5,10 z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M18.5,10h-1c-0.83,0-1.5,0.67-1.5,1.5v1c0,0.83,0.67,1.5,1.5,1.5h1c0.83,0,1.5-0.67,1.5-1.5v-1C20,10.67,19.33,10,18.5,10 z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M6.5,16h-1C4.67,16,4,16.67,4,17.5v1C4,19.33,4.67,20,5.5,20h1C7.33,20,8,19.33,8,18.5v-1C8,16.67,7.33,16,6.5,16z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M12.5,16h-1c-0.83,0-1.5,0.67-1.5,1.5v1c0,0.83,0.67,1.5,1.5,1.5h1c0.83,0,1.5-0.67,1.5-1.5v-1C14,16.67,13.33,16,12.5,16 z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M18.5,16h-1c-0.83,0-1.5,0.67-1.5,1.5v1c0,0.83,0.67,1.5,1.5,1.5h1c0.83,0,1.5-0.67,1.5-1.5v-1C20,16.67,19.33,16,18.5,16 z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_devices_other.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_devices_other.xml
index 463525d..1b4ec92 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_devices_other.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_devices_other.xml
@@ -21,12 +21,12 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M5.25,18H3.5V5.5h17.75C21.66,5.5,22,5.16,22,4.75S21.66,4,21.25,4H3.5C2.67,4,2,4.67,2,5.5V18c0,0.83,0.67,1.5,1.5,1.5 h1.75C5.66,19.5,6,19.16,6,18.75S5.66,18,5.25,18z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M10.5,14.5C9.12,14.5,8,15.62,8,17s1.12,2.5,2.5,2.5S13,18.38,13,17S11.88,14.5,10.5,14.5z M10.5,18c-0.55,0-1-0.45-1-1 s0.45-1,1-1s1,0.45,1,1S11.05,18,10.5,18z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M20.5,8.5h-4C15.67,8.5,15,9.17,15,10v8c0,0.83,0.67,1.5,1.5,1.5h4c0.83,0,1.5-0.67,1.5-1.5v-8 C22,9.17,21.33,8.5,20.5,8.5z M20.5,18h-4v-8h4V18z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_help.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_help.xml
index fce8140..d062e65 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_help.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_help.xml
@@ -20,12 +20,12 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M12,22c0,0,0.01,0,0.01,0c5.5,0,9.98-4.47,9.99-9.98V12c0-5.51-4.49-10-10-10S2,6.49,2,12S6.49,22,12,22z M12,3.5 c4.69,0,8.5,3.81,8.5,8.5v0.02c0,4.68-3.81,8.48-8.49,8.48c0,0-0.01,0-0.01,0c-4.69,0-8.5-3.81-8.5-8.5S7.31,3.5,12,3.5z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M8.67,9.98c0.4,0.1,0.81-0.15,0.9-0.56c0.11-0.47,0.33-0.86,0.65-1.19c0.94-0.94,2.59-0.94,3.54,0 c0.49,0.49,0.73,1.13,0.67,1.76c-0.06,0.57-0.36,1.06-0.84,1.38c-0.13,0.08-0.26,0.16-0.4,0.24c-0.7,0.4-1.67,0.94-1.93,2.51 c-0.07,0.41,0.21,0.8,0.61,0.86C11.92,15,11.96,15,12,15c0.36,0,0.68-0.26,0.74-0.62c0.15-0.87,0.58-1.12,1.19-1.46 c0.17-0.09,0.33-0.19,0.49-0.29c0.87-0.58,1.41-1.46,1.51-2.48c0.11-1.08-0.29-2.17-1.1-2.97c-1.51-1.51-4.15-1.51-5.66,0 c-0.52,0.51-0.88,1.17-1.05,1.9C8.02,9.48,8.27,9.88,8.67,9.98z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 12 16 C 12.5522847498 16 13 16.4477152502 13 17 C 13 17.5522847498 12.5522847498 18 12 18 C 11.4477152502 18 11 17.5522847498 11 17 C 11 16.4477152502 11.4477152502 16 12 16 Z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_phone_info.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_phone_info.xml
index 0983f9f..f41f7a0 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_phone_info.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_phone_info.xml
@@ -20,12 +20,12 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M8,1C6.34,1,5,2.34,5,4v16c0,1.66,1.34,3,3,3h8c1.66,0,3-1.34,3-3V4c0-1.66-1.34-3-3-3H8z M16,21.5H8 c-0.83,0-1.5-0.67-1.5-1.5h11C17.5,20.83,16.83,21.5,16,21.5z M17.5,18.5h-11v-13h11V18.5z M17.5,4h-11c0-0.83,0.67-1.5,1.5-1.5h8 C16.83,2.5,17.5,3.17,17.5,4z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M12,10.5c-0.41,0-0.75,0.34-0.75,0.75v5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-5 C12.75,10.84,12.41,10.5,12,10.5z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_accessibility.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_accessibility.xml
index bfffc30..f17b5b9 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_accessibility.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_accessibility.xml
@@ -20,18 +20,18 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 12 0.5 C 13.1045694997 0.5 14 1.39543050034 14 2.5 C 14 3.60456949966 13.1045694997 4.5 12 4.5 C 10.8954305003 4.5 10 3.60456949966 10 2.5 C 10 1.39543050034 10.8954305003 0.5 12 0.5 Z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M20.72,5.28c-0.12-0.4-0.54-0.62-0.94-0.5C19.75,4.79,16.55,5.75,12,5.75c-4.53,0-7.75-0.96-7.78-0.97 c-0.39-0.12-0.81,0.1-0.94,0.5c-0.12,0.4,0.1,0.81,0.5,0.94C3.89,6.25,5.89,6.85,9,7.12v12.13C9,19.66,9.34,20,9.75,20 s0.75-0.34,0.75-0.75V14h3v5.25c0,0.41,0.34,0.75,0.75,0.75S15,19.66,15,19.25V7.12c3.11-0.27,5.11-0.87,5.22-0.9 C20.61,6.1,20.84,5.68,20.72,5.28z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 8 22 C 8.55228474983 22 9 22.4477152502 9 23 C 9 23.5522847498 8.55228474983 24 8 24 C 7.44771525017 24 7 23.5522847498 7 23 C 7 22.4477152502 7.44771525017 22 8 22 Z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 12 22 C 12.5522847498 22 13 22.4477152502 13 23 C 13 23.5522847498 12.5522847498 24 12 24 C 11.4477152502 24 11 23.5522847498 11 23 C 11 22.4477152502 11.4477152502 22 12 22 Z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 16 22 C 16.5522847498 22 17 22.4477152502 17 23 C 17 23.5522847498 16.5522847498 24 16 24 C 15.4477152502 24 15 23.5522847498 15 23 C 15 22.4477152502 15.4477152502 22 16 22 Z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_accounts.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_accounts.xml
index f213bc4..f02da58 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_accounts.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_accounts.xml
@@ -20,9 +20,9 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M12,6c-1.65,0-3,1.35-3,3v0.01C9,10.66,10.35,12,11.99,12c0,0,0,0,0.01,0c1.65,0,3-1.35,3-3S13.65,6,12,6z M12,10.5 C12,10.5,12,10.5,12,10.5c-0.83,0-1.5-0.67-1.5-1.49V9c0-0.83,0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5S12.83,10.5,12,10.5z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M19.25,3.25H4.75c-0.83,0-1.5,0.67-1.5,1.5v14.5c0,0.83,0.67,1.5,1.5,1.5h14.5c0.83,0,1.5-0.67,1.5-1.5V4.75 C20.75,3.92,20.08,3.25,19.25,3.25z M16.5,19.25h-9v-3.5C7.5,15.34,7.84,15,8.25,15h7.5c0.41,0,0.75,0.34,0.75,0.75V19.25z M19.25,19.25H18v-3.5c0-1.24-1.01-2.25-2.25-2.25h-7.5C7.01,13.5,6,14.51,6,15.75v3.5H4.75V4.75h14.5L19.25,19.25z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_battery_white.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_battery_white.xml
index 4ed698c..e27cb8d 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_battery_white.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_battery_white.xml
@@ -20,6 +20,6 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M13,2.49h-2c-0.55,0-1,0.45-1,1V4H7C6.45,4,6,4.45,6,5v16c0,0.55,0.45,1,1,1h10c0.55,0,1-0.45,1-1V5c0-0.55-0.45-1-1-1h-3 V3.49C14,2.94,13.55,2.49,13,2.49z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_display_white.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_display_white.xml
index 2e66268..19acd6a 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_display_white.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_display_white.xml
@@ -20,9 +20,9 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M21.25,11.25h-2.8A6.46,6.46,0,0,0,17.09,8l2-2A0.75 0.75 ,0,0,0,18,4.93l-2,2a6.46,6.46,0,0,0-3.28-1.36V2.75a0.75 0.75 ,0,0,0-1.5,0v2.8A6.46,6.46,0,0,0,8,6.91l-2-2A0.75 0.75 ,0,0,0,4.93,6l2,2a6.46,6.46,0,0,0-1.36,3.28H2.75a0.75 0.75 ,0,0,0,0,1.5h2.8A6.46,6.46,0,0,0,6.91,16l-2,2A0.75 0.75 ,0,0,0,6,19.07l2-2a6.46,6.46,0,0,0,3.28,1.36v2.8a0.75 0.75 ,0,0,0,1.5,0v-2.8A6.46,6.46,0,0,0,16,17.09l2,2A0.75 0.75 ,0,0,0,19.07,18l-2-2a6.46,6.46,0,0,0,1.36-3.28h2.8a0.75 0.75 ,0,0,0,0-1.5ZM12,17a5,5,0,1,1,5-5A5,5,0,0,1,12,17Z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M12,15.5a3.5,3.5,0,0,0,0-7Z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_location.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_location.xml
index a00c85f..762d67d 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_location.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_location.xml
@@ -20,9 +20,9 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M12,7c-1.66,0-3,1.34-3,3s1.34,3,3,3s3-1.34,3-3S13.66,7,12,7z M12,11.5c-0.83,0-1.5-0.67-1.5-1.5s0.67-1.5,1.5-1.5 s1.5,0.67,1.5,1.5S12.83,11.5,12,11.5z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M12,2.01c-4.5,0-8,3.49-8,8c0,5.49,5.48,10.24,7.37,11.76c0.19,0.15,0.41,0.22,0.63,0.22c0.22,0,0.44-0.07,0.62-0.22 C14.5,20.26,20,15.5,20,10C20,5.72,16.5,2.01,12,2.01z M12,20.34c-2.18-1.8-6.5-5.94-6.5-10.34c0-3.64,2.86-6.5,6.5-6.5 c3.58,0,6.5,2.91,6.5,6.49C18.5,14.4,14.19,18.53,12,20.34z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_privacy.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_privacy.xml
index 69cd1a4..12a82f2 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_privacy.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_privacy.xml
@@ -20,12 +20,12 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M12,8c-2.21,0-4,1.79-4,4s1.79,4,4,4c0.76,0,1.46-0.22,2.06-0.59c0.16-1.38,0.88-2.59,1.94-3.39c0-0.01,0-0.02,0-0.02 C16,9.79,14.21,8,12,8z M12,14.5c-1.38,0-2.5-1.12-2.5-2.5s1.12-2.5,2.5-2.5c1.38,0,2.5,1.12,2.5,2.5S13.38,14.5,12,14.5z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M3.09,12C3.73,10.81,6.43,6.5,12,6.5c4.53,0,7.14,2.79,8.31,4.5h1.77C21.1,9.28,18.05,5,12,5c-7.4,0-10.32,6.42-10.44,6.7 c-0.09,0.19-0.09,0.41,0,0.61C1.68,12.58,4.61,19,12,19c0.71,0,1.37-0.07,2-0.18V17.3c-0.62,0.13-1.28,0.2-2,0.2 C6.39,17.5,3.73,13.21,3.09,12z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M21,16c0-0.35,0-0.72,0-1c0-1.1-0.9-2-2-2c-1.1,0-2,0.9-2,2c0,0.37,0,0.7,0,1c-0.55,0-1,0.45-1,1v3c0,0.55,0.45,1,1,1h4 c0.55,0,1-0.45,1-1v-3C22,16.45,21.55,16,21,16z M20,16h-2v-1c0-0.55,0.45-1,1-1s1,0.45,1,1V16z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_security_white.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_security_white.xml
index c499596..e93e63f 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_security_white.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_security_white.xml
@@ -20,9 +20,9 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 12 13.5 C 12.8284271247 13.5 13.5 14.1715728753 13.5 15 C 13.5 15.8284271247 12.8284271247 16.5 12 16.5 C 11.1715728753 16.5 10.5 15.8284271247 10.5 15 C 10.5 14.1715728753 11.1715728753 13.5 12 13.5 Z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M18.51,1.46c-2.19-0.06-3.98,1.61-4.01,3.68V8.5h-9C4.67,8.5,4,9.17,4,10v10c0,0.83,0.67,1.5,1.5,1.5h13 c0.83,0,1.5-0.67,1.5-1.5V10c0-0.83-0.67-1.5-1.5-1.5H16V5.15c0.02-1.23,1.14-2.23,2.51-2.19C19.9,2.93,20.98,3.92,21,5.15 c0.01,0.41,0.36,0.71,0.76,0.74c0.41-0.01,0.74-0.35,0.74-0.76C22.46,3.07,20.7,1.39,18.51,1.46z M18.5,10v10h-13V10H18.5z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml
index fe9c578..9ec3ffc 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml
@@ -20,12 +20,12 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M4.92,4.94c-3.9,3.91-3.9,10.24,0.01,14.14s10.24,3.9,14.14-0.01C20.95,17.2,22,14.65,22,12c0-2.65-1.06-5.19-2.93-7.07 C15.16,1.03,8.83,1.03,4.92,4.94z M18,18c-1.6,1.59-3.76,2.48-6.02,2.48c-4.69-0.01-8.49-3.83-8.48-8.52 c0.01-4.69,3.83-8.49,8.52-8.48c4.69,0.01,8.49,3.83,8.48,8.52C20.49,14.25,19.6,16.41,18,18z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M12,10.5c-0.41,0-0.75,0.34-0.75,0.75v5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-5 C12.75,10.84,12.41,10.5,12,10.5z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_wireless.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_wireless.xml
index be66878..c8c8abc 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_wireless.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_wireless.xml
@@ -21,15 +21,15 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M12,2.75C7.95,2.69,4.05,4.3,1.22,7.2C0.96,7.5,0.97,7.95,1.24,8.23C1.53,8.53,2,8.54,2.3,8.25c2.55-2.61,6.05-4.06,9.7-4 c3.65-0.06,7.17,1.4,9.72,4.02c0.28,0.27,0.73,0.28,1.03,0.01c0.31-0.28,0.33-0.75,0.05-1.06C19.96,4.32,16.06,2.69,12,2.75z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M15.78,14.82c0.05,0.06,0.1,0.11,0.17,0.15c0.34,0.23,0.81,0.14,1.04-0.21s0.14-0.81-0.21-1.04 c-2.64-2.64-6.91-2.64-9.55,0c-0.27,0.29-0.27,0.73,0,1.02c0.28,0.3,0.76,0.32,1.06,0.04h0.03c0,0,0,0,0.01-0.01 c2.05-2.05,5.37-2.04,7.42,0.01C15.75,14.8,15.76,14.81,15.78,14.82z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 12 17 C 12.8284271247 17 13.5 17.6715728753 13.5 18.5 C 13.5 19.3284271247 12.8284271247 20 12 20 C 11.1715728753 20 10.5 19.3284271247 10.5 18.5 C 10.5 17.6715728753 11.1715728753 17 12 17 Z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M20.03,11.79c0.3-0.29,0.3-0.77,0.01-1.06h-0.01c-2.12-2.18-5.01-3.44-8.04-3.5c-3.04,0.06-5.93,1.32-8.05,3.5 c-0.29,0.3-0.28,0.77,0.01,1.06c0.3,0.29,0.77,0.28,1.06-0.01c1.85-1.88,4.36-2.96,7-3c2.62,0.05,5.11,1.13,6.95,3 C19.25,12.07,19.73,12.08,20.03,11.79z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_storage_white.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_storage_white.xml
index e80df4f..355ee3b 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_storage_white.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_storage_white.xml
@@ -20,21 +20,21 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M20.25,2H3.75C3.34,2,3,2.34,3,2.75v4.5C3,7.66,3.34,8,3.75,8h16.5C20.66,8,21,7.66,21,7.25v-4.5C21,2.34,20.66,2,20.25,2 z M19.5,6.5h-15v-3h15V6.5z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 5.25 4.25 H 6.75 V 5.75 H 5.25 V 4.25 Z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M20.25,9H3.75C3.34,9,3,9.34,3,9.75v4.5C3,14.66,3.34,15,3.75,15h16.5c0.41,0,0.75-0.34,0.75-0.75v-4.5 C21,9.34,20.66,9,20.25,9z M19.5,13.5h-15v-3h15V13.5z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 5.25 11.25 H 6.75 V 12.75 H 5.25 V 11.25 Z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M20.25,16H3.75C3.34,16,3,16.34,3,16.75v4.5C3,21.66,3.34,22,3.75,22h16.5c0.41,0,0.75-0.34,0.75-0.75v-4.5 C21,16.34,20.66,16,20.25,16z M19.5,20.5h-15v-3h15V20.5z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M 5.25 18.25 H 6.75 V 19.75 H 5.25 V 18.25 Z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_volume_up_24dp.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_volume_up_24dp.xml
index 9370151..25f81b7 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_volume_up_24dp.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_volume_up_24dp.xml
@@ -20,12 +20,12 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M5.69,16l5.03,5.03c0.14,0.14,0.34,0.22,0.53,0.22c0.1,0,0.19-0.02,0.29-0.06C11.82,21.08,12,20.8,12,20.5v-17 c0-0.3-0.18-0.58-0.46-0.69c-0.28-0.11-0.6-0.05-0.82,0.16L5.69,8H3.49C2.68,8.01,2.01,8.68,2,9.5v5C2,15.33,2.67,16,3.5,16H5.69z M3.5,9.5H6c0.2,0,0.39-0.08,0.53-0.22l3.97-3.97v13.38l-3.97-3.97C6.39,14.58,6.2,14.5,6,14.5H3.5V9.5z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M13.52,20.64c0.09,0.34,0.39,0.56,0.72,0.56c0.06,0,0.13-0.01,0.19-0.02c3.29-0.87,5.88-3.46,6.75-6.75 c1.34-5.06-1.69-10.26-6.75-11.59c-0.4-0.11-0.81,0.13-0.92,0.53c-0.11,0.4,0.13,0.81,0.53,0.92c4.26,1.13,6.8,5.5,5.68,9.76 c-0.73,2.77-2.91,4.95-5.68,5.68C13.66,19.83,13.42,20.24,13.52,20.64z" />
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:attr/colorPrimary"
android:pathData="M13.85,14.96c-0.35,0.22-0.46,0.68-0.24,1.03c0.14,0.23,0.39,0.35,0.64,0.35c0.14,0,0.27-0.04,0.4-0.11 c1.13-0.7,1.92-1.81,2.22-3.1c0.3-1.3,0.08-2.64-0.62-3.77c-0.4-0.65-0.96-1.2-1.6-1.6C14.29,7.54,13.83,7.65,13.61,8 c-0.22,0.35-0.11,0.81,0.24,1.03c0.45,0.28,0.84,0.67,1.12,1.12c0.49,0.79,0.65,1.73,0.44,2.64C15.2,13.7,14.65,14.47,13.85,14.96z" />
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedThemePickerOverlay/AndroidManifest.xml b/packages/overlays/IconPackRoundedThemePickerOverlay/AndroidManifest.xml
index 9a90a05..fd5b339 100644
--- a/packages/overlays/IconPackRoundedThemePickerOverlay/AndroidManifest.xml
+++ b/packages/overlays/IconPackRoundedThemePickerOverlay/AndroidManifest.xml
@@ -19,6 +19,6 @@
package="com.android.theme.icon_pack.rounded.themepicker"
android:versionCode="1"
android:versionName="1.0">
- <overlay android:targetPackage="com.android.wallpaper" android:category="android.theme.customization.icon_pack.themepicker" android:priority="1"/>
+ <overlay android:targetPackage="com.google.android.apps.wallpaper" android:category="android.theme.customization.icon_pack.themepicker" android:priority="1"/>
<application android:label="Rounded" android:hasCode="false"/>
</manifest>
diff --git a/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_apps.xml b/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_apps.xml
index ff34995..69835c0 100644
--- a/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_apps.xml
+++ b/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_apps.xml
@@ -14,13 +14,13 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M 6 10 C 7.10456949966 10 8 10.8954305003 8 12 C 8 13.1045694997 7.10456949966 14 6 14 C 4.89543050034 14 4 13.1045694997 4 12 C 4 10.8954305003 4.89543050034 10 6 10 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 6 4 C 7.10456949966 4 8 4.89543050034 8 6 C 8 7.10456949966 7.10456949966 8 6 8 C 4.89543050034 8 4 7.10456949966 4 6 C 4 4.89543050034 4.89543050034 4 6 4 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 18 4 C 19.1045694997 4 20 4.89543050034 20 6 C 20 7.10456949966 19.1045694997 8 18 8 C 16.8954305003 8 16 7.10456949966 16 6 C 16 4.89543050034 16.8954305003 4 18 4 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 6 16 C 7.10456949966 16 8 16.8954305003 8 18 C 8 19.1045694997 7.10456949966 20 6 20 C 4.89543050034 20 4 19.1045694997 4 18 C 4 16.8954305003 4.89543050034 16 6 16 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 12 16 C 13.1045694997 16 14 16.8954305003 14 18 C 14 19.1045694997 13.1045694997 20 12 20 C 10.8954305003 20 10 19.1045694997 10 18 C 10 16.8954305003 10.8954305003 16 12 16 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 18 10 C 19.1045694997 10 20 10.8954305003 20 12 C 20 13.1045694997 19.1045694997 14 18 14 C 16.8954305003 14 16 13.1045694997 16 12 C 16 10.8954305003 16.8954305003 10 18 10 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 18 16 C 19.1045694997 16 20 16.8954305003 20 18 C 20 19.1045694997 19.1045694997 20 18 20 C 16.8954305003 20 16 19.1045694997 16 18 C 16 16.8954305003 16.8954305003 16 18 16 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 12 10 C 13.1045694997 10 14 10.8954305003 14 12 C 14 13.1045694997 13.1045694997 14 12 14 C 10.8954305003 14 10 13.1045694997 10 12 C 10 10.8954305003 10.8954305003 10 12 10 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 12 4 C 13.1045694997 4 14 4.89543050034 14 6 C 14 7.10456949966 13.1045694997 8 12 8 C 10.8954305003 8 10 7.10456949966 10 6 C 10 4.89543050034 10.8954305003 4 12 4 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 6 10 C 7.10456949966 10 8 10.8954305003 8 12 C 8 13.1045694997 7.10456949966 14 6 14 C 4.89543050034 14 4 13.1045694997 4 12 C 4 10.8954305003 4.89543050034 10 6 10 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 6 4 C 7.10456949966 4 8 4.89543050034 8 6 C 8 7.10456949966 7.10456949966 8 6 8 C 4.89543050034 8 4 7.10456949966 4 6 C 4 4.89543050034 4.89543050034 4 6 4 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 18 4 C 19.1045694997 4 20 4.89543050034 20 6 C 20 7.10456949966 19.1045694997 8 18 8 C 16.8954305003 8 16 7.10456949966 16 6 C 16 4.89543050034 16.8954305003 4 18 4 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 6 16 C 7.10456949966 16 8 16.8954305003 8 18 C 8 19.1045694997 7.10456949966 20 6 20 C 4.89543050034 20 4 19.1045694997 4 18 C 4 16.8954305003 4.89543050034 16 6 16 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 12 16 C 13.1045694997 16 14 16.8954305003 14 18 C 14 19.1045694997 13.1045694997 20 12 20 C 10.8954305003 20 10 19.1045694997 10 18 C 10 16.8954305003 10.8954305003 16 12 16 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 18 10 C 19.1045694997 10 20 10.8954305003 20 12 C 20 13.1045694997 19.1045694997 14 18 14 C 16.8954305003 14 16 13.1045694997 16 12 C 16 10.8954305003 16.8954305003 10 18 10 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 18 16 C 19.1045694997 16 20 16.8954305003 20 18 C 20 19.1045694997 19.1045694997 20 18 20 C 16.8954305003 20 16 19.1045694997 16 18 C 16 16.8954305003 16.8954305003 16 18 16 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 12 10 C 13.1045694997 10 14 10.8954305003 14 12 C 14 13.1045694997 13.1045694997 14 12 14 C 10.8954305003 14 10 13.1045694997 10 12 C 10 10.8954305003 10.8954305003 10 12 10 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 12 4 C 13.1045694997 4 14 4.89543050034 14 6 C 14 7.10456949966 13.1045694997 8 12 8 C 10.8954305003 8 10 7.10456949966 10 6 C 10 4.89543050034 10.8954305003 4 12 4 Z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_devices_other.xml b/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_devices_other.xml
index 733fe7f..c692eeb 100644
--- a/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_devices_other.xml
+++ b/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_devices_other.xml
@@ -14,5 +14,5 @@
limitations under the License.
-->
<vector android:autoMirrored="true" android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M3,7c0-0.55,0.45-1,1-1h16c0.55,0,1-0.45,1-1v0c0-0.55-0.45-1-1-1H4C2.35,4,1,5.35,1,7v10c0,1.65,1.35,3,3,3h2 c0.55,0,1-0.45,1-1v0c0-0.55-0.45-1-1-1H4c-0.55,0-1-0.45-1-1V7z M12,12h-2c-0.55,0-1,0.45-1,1v0.78C8.39,14.33,8,15.11,8,16 c0,0.89,0.39,1.67,1,2.22V19c0,0.55,0.45,1,1,1h2c0.55,0,1-0.45,1-1v-0.78c0.61-0.55,1-1.34,1-2.22c0-0.88-0.39-1.67-1-2.22V13 C13,12.45,12.55,12,12,12z M11,17.5c-0.83,0-1.5-0.67-1.5-1.5s0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5S11.83,17.5,11,17.5 M17,8 c-1.1,0-2,0.9-2,2v8c0,1.1,0.9,2,2,2h4c1.1,0,2-0.9,2-2v-8c0-1.1-0.9-2-2-2H17z M21,18h-4v-8h4V18z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M3,7c0-0.55,0.45-1,1-1h16c0.55,0,1-0.45,1-1v0c0-0.55-0.45-1-1-1H4C2.35,4,1,5.35,1,7v10c0,1.65,1.35,3,3,3h2 c0.55,0,1-0.45,1-1v0c0-0.55-0.45-1-1-1H4c-0.55,0-1-0.45-1-1V7z M12,12h-2c-0.55,0-1,0.45-1,1v0.78C8.39,14.33,8,15.11,8,16 c0,0.89,0.39,1.67,1,2.22V19c0,0.55,0.45,1,1,1h2c0.55,0,1-0.45,1-1v-0.78c0.61-0.55,1-1.34,1-2.22c0-0.88-0.39-1.67-1-2.22V13 C13,12.45,12.55,12,12,12z M11,17.5c-0.83,0-1.5-0.67-1.5-1.5s0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5S11.83,17.5,11,17.5 M17,8 c-1.1,0-2,0.9-2,2v8c0,1.1,0.9,2,2,2h4c1.1,0,2-0.9,2-2v-8c0-1.1-0.9-2-2-2H17z M21,18h-4v-8h4V18z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_help.xml b/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_help.xml
index 4650a72..5a8185a 100644
--- a/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_help.xml
+++ b/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_help.xml
@@ -14,5 +14,5 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2,2,6.48,2,12c0,5.52,4.48,10,10,10s10-4.48,10-10C22,6.48,17.52,2,12,2z M12,18c-0.55,0-1-0.45-1-1 c0-0.55,0.45-1,1-1s1,0.45,1,1C13,17.55,12.55,18,12,18z M13.1,14.32C12.98,14.71,12.65,15,12.24,15h-0.15 c-0.62,0-1.11-0.6-0.93-1.2c0.61-1.97,2.71-2.08,2.83-3.66c0.07-0.97-0.62-1.9-1.57-2.1c-1.04-0.22-1.98,0.39-2.3,1.28 C9.98,9.71,9.65,10,9.24,10H9.07C8.45,10,8,9.4,8.18,8.81C8.68,7.18,10.2,6,12,6c2.21,0,4,1.79,4,4 C16,12.22,13.63,12.67,13.1,14.32z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M12,2C6.48,2,2,6.48,2,12c0,5.52,4.48,10,10,10s10-4.48,10-10C22,6.48,17.52,2,12,2z M12,18c-0.55,0-1-0.45-1-1 c0-0.55,0.45-1,1-1s1,0.45,1,1C13,17.55,12.55,18,12,18z M13.1,14.32C12.98,14.71,12.65,15,12.24,15h-0.15 c-0.62,0-1.11-0.6-0.93-1.2c0.61-1.97,2.71-2.08,2.83-3.66c0.07-0.97-0.62-1.9-1.57-2.1c-1.04-0.22-1.98,0.39-2.3,1.28 C9.98,9.71,9.65,10,9.24,10H9.07C8.45,10,8,9.4,8.18,8.81C8.68,7.18,10.2,6,12,6c2.21,0,4,1.79,4,4 C16,12.22,13.63,12.67,13.1,14.32z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_phone_info.xml b/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_phone_info.xml
index dac1deef..54336d0 100644
--- a/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_phone_info.xml
+++ b/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_phone_info.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M12,11L12,11c0.55,0,1,0.45,1,1v4c0,0.55-0.45,1-1,1c-0.55,0-1-0.45-1-1v-4C11,11.45,11.45,11,12,11"/>
- <path android:fillColor="@android:color/white" android:pathData="M16,1H8C6.34,1,5,2.34,5,4v16c0,1.65,1.35,3,3,3h8c1.65,0,3-1.35,3-3V4C19,2.34,17.66,1,16,1 M17,18H7V6h10V18z"/>
- <path android:fillColor="@android:color/white" android:pathData="M13,8c0,0.55-0.45,1-1,1c-0.55,0-1-0.45-1-1c0-0.55,0.45-1,1-1C12.55,7,13,7.45,13,8"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M12,11L12,11c0.55,0,1,0.45,1,1v4c0,0.55-0.45,1-1,1c-0.55,0-1-0.45-1-1v-4C11,11.45,11.45,11,12,11"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M16,1H8C6.34,1,5,2.34,5,4v16c0,1.65,1.35,3,3,3h8c1.65,0,3-1.35,3-3V4C19,2.34,17.66,1,16,1 M17,18H7V6h10V18z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M13,8c0,0.55-0.45,1-1,1c-0.55,0-1-0.45-1-1c0-0.55,0.45-1,1-1C12.55,7,13,7.45,13,8"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_settings_accessibility.xml b/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_settings_accessibility.xml
index 3be42b3..4a4baf9 100644
--- a/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_settings_accessibility.xml
+++ b/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_settings_accessibility.xml
@@ -14,9 +14,9 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M20.75,4.99c-0.14-0.55-0.69-0.87-1.24-0.75C17.13,4.77,14.48,5,12,5S6.87,4.77,4.49,4.24c-0.55-0.12-1.1,0.2-1.24,0.75 c-0.14,0.56,0.2,1.13,0.75,1.26C5.61,6.61,7.35,6.86,9,7v12c0,0.55,0.45,1,1,1s1-0.45,1-1v-4c0-0.55,0.45-1,1-1s1,0.45,1,1v4 c0,0.55,0.45,1,1,1s1-0.45,1-1V7c1.65-0.14,3.39-0.39,4.99-0.75C20.55,6.12,20.89,5.55,20.75,4.99z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 12 0 C 13.1045694997 0 14 0.895430500338 14 2 C 14 3.10456949966 13.1045694997 4 12 4 C 10.8954305003 4 10 3.10456949966 10 2 C 10 0.895430500338 10.8954305003 0 12 0 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 8 22 C 8.55228474983 22 9 22.4477152502 9 23 C 9 23.5522847498 8.55228474983 24 8 24 C 7.44771525017 24 7 23.5522847498 7 23 C 7 22.4477152502 7.44771525017 22 8 22 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 12 22 C 12.5522847498 22 13 22.4477152502 13 23 C 13 23.5522847498 12.5522847498 24 12 24 C 11.4477152502 24 11 23.5522847498 11 23 C 11 22.4477152502 11.4477152502 22 12 22 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 16 22 C 16.5522847498 22 17 22.4477152502 17 23 C 17 23.5522847498 16.5522847498 24 16 24 C 15.4477152502 24 15 23.5522847498 15 23 C 15 22.4477152502 15.4477152502 22 16 22 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M20.75,4.99c-0.14-0.55-0.69-0.87-1.24-0.75C17.13,4.77,14.48,5,12,5S6.87,4.77,4.49,4.24c-0.55-0.12-1.1,0.2-1.24,0.75 c-0.14,0.56,0.2,1.13,0.75,1.26C5.61,6.61,7.35,6.86,9,7v12c0,0.55,0.45,1,1,1s1-0.45,1-1v-4c0-0.55,0.45-1,1-1s1,0.45,1,1v4 c0,0.55,0.45,1,1,1s1-0.45,1-1V7c1.65-0.14,3.39-0.39,4.99-0.75C20.55,6.12,20.89,5.55,20.75,4.99z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 12 0 C 13.1045694997 0 14 0.895430500338 14 2 C 14 3.10456949966 13.1045694997 4 12 4 C 10.8954305003 4 10 3.10456949966 10 2 C 10 0.895430500338 10.8954305003 0 12 0 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 8 22 C 8.55228474983 22 9 22.4477152502 9 23 C 9 23.5522847498 8.55228474983 24 8 24 C 7.44771525017 24 7 23.5522847498 7 23 C 7 22.4477152502 7.44771525017 22 8 22 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 12 22 C 12.5522847498 22 13 22.4477152502 13 23 C 13 23.5522847498 12.5522847498 24 12 24 C 11.4477152502 24 11 23.5522847498 11 23 C 11 22.4477152502 11.4477152502 22 12 22 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 16 22 C 16.5522847498 22 17 22.4477152502 17 23 C 17 23.5522847498 16.5522847498 24 16 24 C 15.4477152502 24 15 23.5522847498 15 23 C 15 22.4477152502 15.4477152502 22 16 22 Z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_settings_accounts.xml b/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_settings_accounts.xml
index a9bf036..334b2b7 100644
--- a/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_settings_accounts.xml
+++ b/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_settings_accounts.xml
@@ -14,6 +14,6 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M6,3C4.34,3,3,4.34,3,6v12c0,1.66,1.34,3,3,3h12c1.65,0,3-1.35,3-3V6c0-1.66-1.34-3-3-3H6z M19,6v9.79 C16.52,14.37,13.23,14,12,14s-4.52,0.37-7,1.79V6c0-0.55,0.45-1,1-1h12C18.55,5,19,5.45,19,6z"/>
- <path android:fillColor="@android:color/white" android:pathData="M12,13c1.94,0,3.5-1.56,3.5-3.5S13.94,6,12,6S8.5,7.56,8.5,9.5S10.06,13,12,13"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M6,3C4.34,3,3,4.34,3,6v12c0,1.66,1.34,3,3,3h12c1.65,0,3-1.35,3-3V6c0-1.66-1.34-3-3-3H6z M19,6v9.79 C16.52,14.37,13.23,14,12,14s-4.52,0.37-7,1.79V6c0-0.55,0.45-1,1-1h12C18.55,5,19,5.45,19,6z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M12,13c1.94,0,3.5-1.56,3.5-3.5S13.94,6,12,6S8.5,7.56,8.5,9.5S10.06,13,12,13"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_settings_battery_white.xml b/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_settings_battery_white.xml
index d616ad6..fff56ce 100644
--- a/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_settings_battery_white.xml
+++ b/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_settings_battery_white.xml
@@ -14,5 +14,5 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M15,4h-1c0-1.1-0.9-2-2-2s-2,0.9-2,2H9C7.35,4,6,5.35,6,7v12c0,1.65,1.35,3,3,3h6c1.65,0,3-1.35,3-3V7 C18,5.35,16.65,4,15,4z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M15,4h-1c0-1.1-0.9-2-2-2s-2,0.9-2,2H9C7.35,4,6,5.35,6,7v12c0,1.65,1.35,3,3,3h6c1.65,0,3-1.35,3-3V7 C18,5.35,16.65,4,15,4z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_settings_display_white.xml b/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_settings_display_white.xml
index cf4af6f..723c36c 100644
--- a/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_settings_display_white.xml
+++ b/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_settings_display_white.xml
@@ -14,6 +14,6 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M13.25,7.16C12.62,6.99,12,7.48,12,8.13v7.74c0,0.65,0.62,1.14,1.25,0.97C15.41,16.29,17,14.33,17,12 S15.41,7.71,13.25,7.16z"/>
- <path android:fillColor="@android:color/white" android:pathData="M21.19,9.88l-0.9-0.9C20.1,8.8,20,8.54,20,8.28V7c0-1.66-1.34-3-3-3h-1.28c-0.27,0-0.52-0.11-0.71-0.29l-0.9-0.9 c-1.17-1.17-3.07-1.17-4.24,0l-0.9,0.9C8.79,3.89,8.54,4,8.28,4H7C5.34,4,4,5.34,4,7v1.28C4,8.54,3.89,8.8,3.71,8.98l-0.9,0.9 c-1.17,1.17-1.17,3.07,0,4.24l0.9,0.9C3.89,15.2,4,15.46,4,15.72V17c0,1.66,1.34,3,3,3h1.28c0.27,0,0.52,0.11,0.71,0.29l0.9,0.9 c1.17,1.17,3.07,1.17,4.24,0l0.9-0.9C15.2,20.11,15.46,20,15.72,20H17c1.66,0,3-1.34,3-3v-1.28c0-0.27,0.11-0.52,0.29-0.71 l0.9-0.9C22.36,12.95,22.36,11.05,21.19,9.88z M19.77,12.71l-1.48,1.48C18.11,14.37,18,14.63,18,14.89V17c0,0.55-0.45,1-1,1h-2.11 c-0.27,0-0.52,0.11-0.71,0.29l-1.48,1.48c-0.39,0.39-1.02,0.39-1.41,0l-1.48-1.48C9.63,18.1,9.37,18,9.11,18H7c-0.55,0-1-0.45-1-1 v-2.1c0-0.27-0.11-0.52-0.29-0.71l-1.48-1.48c-0.39-0.39-0.39-1.02,0-1.41l1.48-1.48C5.9,9.63,6,9.37,6,9.11V7c0-0.55,0.45-1,1-1 h2.11c0.27,0,0.52-0.11,0.71-0.29l1.48-1.48c0.39-0.39,1.02-0.39,1.41,0l1.48,1.48C14.38,5.89,14.63,6,14.89,6H17 c0.55,0,1,0.45,1,1v2.11c0,0.27,0.11,0.52,0.29,0.71l1.48,1.48C20.16,11.68,20.16,12.32,19.77,12.71z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M13.25,7.16C12.62,6.99,12,7.48,12,8.13v7.74c0,0.65,0.62,1.14,1.25,0.97C15.41,16.29,17,14.33,17,12 S15.41,7.71,13.25,7.16z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M21.19,9.88l-0.9-0.9C20.1,8.8,20,8.54,20,8.28V7c0-1.66-1.34-3-3-3h-1.28c-0.27,0-0.52-0.11-0.71-0.29l-0.9-0.9 c-1.17-1.17-3.07-1.17-4.24,0l-0.9,0.9C8.79,3.89,8.54,4,8.28,4H7C5.34,4,4,5.34,4,7v1.28C4,8.54,3.89,8.8,3.71,8.98l-0.9,0.9 c-1.17,1.17-1.17,3.07,0,4.24l0.9,0.9C3.89,15.2,4,15.46,4,15.72V17c0,1.66,1.34,3,3,3h1.28c0.27,0,0.52,0.11,0.71,0.29l0.9,0.9 c1.17,1.17,3.07,1.17,4.24,0l0.9-0.9C15.2,20.11,15.46,20,15.72,20H17c1.66,0,3-1.34,3-3v-1.28c0-0.27,0.11-0.52,0.29-0.71 l0.9-0.9C22.36,12.95,22.36,11.05,21.19,9.88z M19.77,12.71l-1.48,1.48C18.11,14.37,18,14.63,18,14.89V17c0,0.55-0.45,1-1,1h-2.11 c-0.27,0-0.52,0.11-0.71,0.29l-1.48,1.48c-0.39,0.39-1.02,0.39-1.41,0l-1.48-1.48C9.63,18.1,9.37,18,9.11,18H7c-0.55,0-1-0.45-1-1 v-2.1c0-0.27-0.11-0.52-0.29-0.71l-1.48-1.48c-0.39-0.39-0.39-1.02,0-1.41l1.48-1.48C5.9,9.63,6,9.37,6,9.11V7c0-0.55,0.45-1,1-1 h2.11c0.27,0,0.52-0.11,0.71-0.29l1.48-1.48c0.39-0.39,1.02-0.39,1.41,0l1.48,1.48C14.38,5.89,14.63,6,14.89,6H17 c0.55,0,1,0.45,1,1v2.11c0,0.27,0.11,0.52,0.29,0.71l1.48,1.48C20.16,11.68,20.16,12.32,19.77,12.71z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_settings_location.xml b/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_settings_location.xml
index a802bee..9230e3e 100644
--- a/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_settings_location.xml
+++ b/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_settings_location.xml
@@ -14,5 +14,5 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M12,3c-3.87,0-7,3.13-7,7c0,3.18,2.56,7.05,4.59,9.78c1.2,1.62,3.62,1.62,4.82,0C16.44,17.05,19,13.18,19,10 C19,6.13,15.87,3,12,3 M12,12.5c-1.38,0-2.5-1.12-2.5-2.5s1.12-2.5,2.5-2.5s2.5,1.12,2.5,2.5S13.38,12.5,12,12.5"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M12,3c-3.87,0-7,3.13-7,7c0,3.18,2.56,7.05,4.59,9.78c1.2,1.62,3.62,1.62,4.82,0C16.44,17.05,19,13.18,19,10 C19,6.13,15.87,3,12,3 M12,12.5c-1.38,0-2.5-1.12-2.5-2.5s1.12-2.5,2.5-2.5s2.5,1.12,2.5,2.5S13.38,12.5,12,12.5"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_settings_privacy.xml b/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_settings_privacy.xml
index 10c059f..4392c12 100644
--- a/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_settings_privacy.xml
+++ b/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_settings_privacy.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M14.14,15.43C13.5,15.78,12.78,16,12,16c-2.48,0-4.5-2.02-4.5-4.5C7.5,9.02,9.52,7,12,7c2.48,0,4.5,2.02,4.5,4.5 c0,0.37-0.06,0.72-0.14,1.07C17,12.22,17.72,12,18.5,12c1.38,0,2.59,0.63,3.42,1.6c0.15-0.23,0.29-0.46,0.42-0.69 c0.48-0.87,0.48-1.95,0-2.81C20.32,6.46,16.45,4,12,4C7.55,4,3.68,6.46,1.66,10.09c-0.48,0.87-0.48,1.95,0,2.81 C3.68,16.54,7.55,19,12,19c0.68,0,1.35-0.06,2-0.18V16.5C14,16.13,14.06,15.78,14.14,15.43z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 12 8.8 C 13.4911688245 8.8 14.7 10.0088311755 14.7 11.5 C 14.7 12.9911688245 13.4911688245 14.2 12 14.2 C 10.5088311755 14.2 9.3 12.9911688245 9.3 11.5 C 9.3 10.0088311755 10.5088311755 8.8 12 8.8 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M21,17v-1c0-1.1-0.9-2-2-2s-2,0.9-2,2v1c-0.55,0-1,0.45-1,1v3c0,0.55,0.45,1,1,1h4c0.55,0,1-0.45,1-1v-3 C22,17.45,21.55,17,21,17z M18.5,16c0-0.28,0.22-0.5,0.5-0.5s0.5,0.22,0.5,0.5v1h-1V16z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M14.14,15.43C13.5,15.78,12.78,16,12,16c-2.48,0-4.5-2.02-4.5-4.5C7.5,9.02,9.52,7,12,7c2.48,0,4.5,2.02,4.5,4.5 c0,0.37-0.06,0.72-0.14,1.07C17,12.22,17.72,12,18.5,12c1.38,0,2.59,0.63,3.42,1.6c0.15-0.23,0.29-0.46,0.42-0.69 c0.48-0.87,0.48-1.95,0-2.81C20.32,6.46,16.45,4,12,4C7.55,4,3.68,6.46,1.66,10.09c-0.48,0.87-0.48,1.95,0,2.81 C3.68,16.54,7.55,19,12,19c0.68,0,1.35-0.06,2-0.18V16.5C14,16.13,14.06,15.78,14.14,15.43z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 12 8.8 C 13.4911688245 8.8 14.7 10.0088311755 14.7 11.5 C 14.7 12.9911688245 13.4911688245 14.2 12 14.2 C 10.5088311755 14.2 9.3 12.9911688245 9.3 11.5 C 9.3 10.0088311755 10.5088311755 8.8 12 8.8 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M21,17v-1c0-1.1-0.9-2-2-2s-2,0.9-2,2v1c-0.55,0-1,0.45-1,1v3c0,0.55,0.45,1,1,1h4c0.55,0,1-0.45,1-1v-3 C22,17.45,21.55,17,21,17z M18.5,16c0-0.28,0.22-0.5,0.5-0.5s0.5,0.22,0.5,0.5v1h-1V16z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_settings_security_white.xml b/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_settings_security_white.xml
index 8ca2dd6..baa6a0a 100644
--- a/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_settings_security_white.xml
+++ b/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_settings_security_white.xml
@@ -14,5 +14,5 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M18.5,1C16.01,1,14,3.01,14,5.5V8H7c-1.65,0-3,1.35-3,3v8c0,1.65,1.35,3,3,3h10c1.65,0,3-1.35,3-3v-8c0-1.65-1.35-3-3-3h-1 V5.64c0-1.31,0.94-2.5,2.24-2.63c0.52-0.05,2.3,0.02,2.69,2.12C21.02,5.63,21.42,6,21.92,6c0.6,0,1.09-0.53,0.99-1.13 C22.47,2.3,20.55,1,18.5,1z M12,17c-1.1,0-2-0.9-2-2s0.9-2,2-2s2,0.9,2,2S13.1,17,12,17z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M18.5,1C16.01,1,14,3.01,14,5.5V8H7c-1.65,0-3,1.35-3,3v8c0,1.65,1.35,3,3,3h10c1.65,0,3-1.35,3-3v-8c0-1.65-1.35-3-3-3h-1 V5.64c0-1.31,0.94-2.5,2.24-2.63c0.52-0.05,2.3,0.02,2.69,2.12C21.02,5.63,21.42,6,21.92,6c0.6,0,1.09-0.53,0.99-1.13 C22.47,2.3,20.55,1,18.5,1z M12,17c-1.1,0-2-0.9-2-2s0.9-2,2-2s2,0.9,2,2S13.1,17,12,17z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml b/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml
index 437afcc..54aa6ce 100644
--- a/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml
+++ b/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml
@@ -14,5 +14,5 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2,2,6.48,2,12c0,5.52,4.48,10,10,10s10-4.48,10-10C22,6.48,17.52,2,12,2z M13,16c0,0.55-0.45,1-1,1s-1-0.45-1-1 v-4c0-0.55,0.45-1,1-1s1,0.45,1,1V16z M12,9c-0.55,0-1-0.45-1-1c0-0.55,0.45-1,1-1s1,0.45,1,1C13,8.55,12.55,9,12,9z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M12,2C6.48,2,2,6.48,2,12c0,5.52,4.48,10,10,10s10-4.48,10-10C22,6.48,17.52,2,12,2z M13,16c0,0.55-0.45,1-1,1s-1-0.45-1-1 v-4c0-0.55,0.45-1,1-1s1,0.45,1,1V16z M12,9c-0.55,0-1-0.45-1-1c0-0.55,0.45-1,1-1s1,0.45,1,1C13,8.55,12.55,9,12,9z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_settings_wireless.xml b/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_settings_wireless.xml
index 145886a..c40f314 100644
--- a/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_settings_wireless.xml
+++ b/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_settings_wireless.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
<vector android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M17.79,11.97c-3.7-2.67-8.4-2.29-11.58,0c-0.69,0.5-0.73,1.51-0.13,2.11l0.01,0.01c0.49,0.49,1.26,0.54,1.83,0.13 c2.6-1.84,5.88-1.61,8.16,0c0.57,0.4,1.34,0.36,1.83-0.13l0.01-0.01C18.52,13.48,18.48,12.47,17.79,11.97z"/>
- <path android:fillColor="@android:color/white" android:pathData="M21.84,7.95c-5.71-4.68-13.97-4.67-19.69,0c-0.65,0.53-0.69,1.51-0.1,2.1c0.51,0.51,1.33,0.55,1.89,0.09 c3.45-2.83,10.36-4.72,16.11,0c0.56,0.46,1.38,0.42,1.89-0.09C22.54,9.46,22.49,8.48,21.84,7.95z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 12 15 C 13.1045694997 15 14 15.8954305003 14 17 C 14 18.1045694997 13.1045694997 19 12 19 C 10.8954305003 19 10 18.1045694997 10 17 C 10 15.8954305003 10.8954305003 15 12 15 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M17.79,11.97c-3.7-2.67-8.4-2.29-11.58,0c-0.69,0.5-0.73,1.51-0.13,2.11l0.01,0.01c0.49,0.49,1.26,0.54,1.83,0.13 c2.6-1.84,5.88-1.61,8.16,0c0.57,0.4,1.34,0.36,1.83-0.13l0.01-0.01C18.52,13.48,18.48,12.47,17.79,11.97z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M21.84,7.95c-5.71-4.68-13.97-4.67-19.69,0c-0.65,0.53-0.69,1.51-0.1,2.1c0.51,0.51,1.33,0.55,1.89,0.09 c3.45-2.83,10.36-4.72,16.11,0c0.56,0.46,1.38,0.42,1.89-0.09C22.54,9.46,22.49,8.48,21.84,7.95z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 12 15 C 13.1045694997 15 14 15.8954305003 14 17 C 14 18.1045694997 13.1045694997 19 12 19 C 10.8954305003 19 10 18.1045694997 10 17 C 10 15.8954305003 10.8954305003 15 12 15 Z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_storage_white.xml b/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_storage_white.xml
index 3ed5150..2ae828d 100644
--- a/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_storage_white.xml
+++ b/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_storage_white.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M19,16H5c-1.1,0-2,0.9-2,2c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2C21,16.9,20.1,16,19,16z M6,19c-0.55,0-1-0.45-1-1 c0-0.55,0.45-1,1-1s1,0.45,1,1C7,18.55,6.55,19,6,19z"/>
- <path android:fillColor="@android:color/white" android:pathData="M5,8h14c1.1,0,2-0.9,2-2c0-1.1-0.9-2-2-2H5C3.9,4,3,4.9,3,6C3,7.1,3.9,8,5,8z M6,5c0.55,0,1,0.45,1,1c0,0.55-0.45,1-1,1 S5,6.55,5,6C5,5.45,5.45,5,6,5z"/>
- <path android:fillColor="@android:color/white" android:pathData="M19,10H5c-1.1,0-2,0.9-2,2c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2C21,10.9,20.1,10,19,10z M6,13c-0.55,0-1-0.45-1-1 c0-0.55,0.45-1,1-1s1,0.45,1,1C7,12.55,6.55,13,6,13z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M19,16H5c-1.1,0-2,0.9-2,2c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2C21,16.9,20.1,16,19,16z M6,19c-0.55,0-1-0.45-1-1 c0-0.55,0.45-1,1-1s1,0.45,1,1C7,18.55,6.55,19,6,19z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M5,8h14c1.1,0,2-0.9,2-2c0-1.1-0.9-2-2-2H5C3.9,4,3,4.9,3,6C3,7.1,3.9,8,5,8z M6,5c0.55,0,1,0.45,1,1c0,0.55-0.45,1-1,1 S5,6.55,5,6C5,5.45,5.45,5,6,5z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M19,10H5c-1.1,0-2,0.9-2,2c0,1.1,0.9,2,2,2h14c1.1,0,2-0.9,2-2C21,10.9,20.1,10,19,10z M6,13c-0.55,0-1-0.45-1-1 c0-0.55,0.45-1,1-1s1,0.45,1,1C7,12.55,6.55,13,6,13z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_volume_up_24dp.xml b/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_volume_up_24dp.xml
index 0a9a4c7..4fc2489 100644
--- a/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_volume_up_24dp.xml
+++ b/packages/overlays/IconPackSamSettingsOverlay/res/drawable/ic_volume_up_24dp.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M10.29,5.71L7,9H6c-1.66,0-3,1.34-3,3s1.34,3,3,3h1l3.29,3.29c0.63,0.63,1.71,0.18,1.71-0.71V6.41 C12,5.52,10.92,5.08,10.29,5.71z"/>
- <path android:fillColor="@android:color/white" android:pathData="M14.79,15.52c1.04-0.82,1.71-2.09,1.71-3.52c0-1.43-0.67-2.7-1.71-3.52C14.47,8.22,14,8.47,14,8.88v6.23 C14,15.52,14.47,15.77,14.79,15.52z"/>
- <path android:fillColor="@android:color/white" android:pathData="M15.36,3.65C14.71,3.39,14,3.89,14,4.59v0c0,0.41,0.25,0.77,0.62,0.92C17.19,6.55,19,9.06,19,12 c0,2.94-1.81,5.45-4.38,6.49C14.25,18.64,14,19.01,14,19.41v0c0,0.7,0.71,1.19,1.36,0.93C18.67,19.02,21,15.78,21,12 C21,8.22,18.67,4.98,15.36,3.65z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M10.29,5.71L7,9H6c-1.66,0-3,1.34-3,3s1.34,3,3,3h1l3.29,3.29c0.63,0.63,1.71,0.18,1.71-0.71V6.41 C12,5.52,10.92,5.08,10.29,5.71z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M14.79,15.52c1.04-0.82,1.71-2.09,1.71-3.52c0-1.43-0.67-2.7-1.71-3.52C14.47,8.22,14,8.47,14,8.88v6.23 C14,15.52,14.47,15.77,14.79,15.52z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M15.36,3.65C14.71,3.39,14,3.89,14,4.59v0c0,0.41,0.25,0.77,0.62,0.92C17.19,6.55,19,9.06,19,12 c0,2.94-1.81,5.45-4.38,6.49C14.25,18.64,14,19.01,14,19.41v0c0,0.7,0.71,1.19,1.36,0.93C18.67,19.02,21,15.78,21,12 C21,8.22,18.67,4.98,15.36,3.65z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_apps.xml b/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_apps.xml
index ab58f204..d62b777 100644
--- a/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_apps.xml
+++ b/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_apps.xml
@@ -14,13 +14,13 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M 4 4 H 8 V 8 H 4 V 4 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 4 10 H 8 V 14 H 4 V 10 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 4 16 H 8 V 20 H 4 V 16 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 10 4 H 14 V 8 H 10 V 4 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 10 10 H 14 V 14 H 10 V 10 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 10 16 H 14 V 20 H 10 V 16 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 16 4 H 20 V 8 H 16 V 4 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 16 10 H 20 V 14 H 16 V 10 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 16 16 H 20 V 20 H 16 V 16 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 4 4 H 8 V 8 H 4 V 4 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 4 10 H 8 V 14 H 4 V 10 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 4 16 H 8 V 20 H 4 V 16 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 10 4 H 14 V 8 H 10 V 4 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 10 10 H 14 V 14 H 10 V 10 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 10 16 H 14 V 20 H 10 V 16 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 16 4 H 20 V 8 H 16 V 4 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 16 10 H 20 V 14 H 16 V 10 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 16 16 H 20 V 20 H 16 V 16 Z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_devices_other.xml b/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_devices_other.xml
index 7548dfa..71fb7a3 100644
--- a/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_devices_other.xml
+++ b/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_devices_other.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
<vector android:autoMirrored="true" android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M21.5,8h-5L15,9.5v9l1.5,1.5h5l1.5-1.5v-9L21.5,8z M21.5,18.5h-5v-9h5V18.5z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 2.5 5.5 L 21 5.5 L 21 4 L 2.5 4 L 1 5.5 L 1 18.5 L 2.5 20 L 7 20 L 7 18.5 L 2.5 18.5 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M13,12H9v1.78C8.39,14.33,8,15.11,8,16s0.39,1.67,1,2.22V20h4v-1.78c0.61-0.55,1-1.34,1-2.22s-0.39-1.67-1-2.22V12z M11,14.5c0.83,0,1.5,0.67,1.5,1.5s-0.67,1.5-1.5,1.5S9.5,16.83,9.5,16S10.17,14.5,11,14.5z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M21.5,8h-5L15,9.5v9l1.5,1.5h5l1.5-1.5v-9L21.5,8z M21.5,18.5h-5v-9h5V18.5z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 2.5 5.5 L 21 5.5 L 21 4 L 2.5 4 L 1 5.5 L 1 18.5 L 2.5 20 L 7 20 L 7 18.5 L 2.5 18.5 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M13,12H9v1.78C8.39,14.33,8,15.11,8,16s0.39,1.67,1,2.22V20h4v-1.78c0.61-0.55,1-1.34,1-2.22s-0.39-1.67-1-2.22V12z M11,14.5c0.83,0,1.5,0.67,1.5,1.5s-0.67,1.5-1.5,1.5S9.5,16.83,9.5,16S10.17,14.5,11,14.5z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_help.xml b/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_help.xml
index eb2e966..32c603d 100644
--- a/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_help.xml
+++ b/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_help.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2,2,6.48,2,12s4.48,10,10,10s10-4.48,10-10S17.52,2,12,2z M12,20.5c-4.69,0-8.5-3.81-8.5-8.5S7.31,3.5,12,3.5 s8.5,3.81,8.5,8.5S16.69,20.5,12,20.5z"/>
- <path android:fillColor="@android:color/white" android:pathData="M12.48,6c-1.71,0-3.53,0.96-3.53,3.17v0.37c0,0.11,0.06,0.17,0.17,0.17l1.29,0.07c0.11,0,0.17-0.06,0.17-0.17V9.17 c0-1.29,1.07-1.7,1.85-1.7c0.74,0,1.81,0.37,1.81,1.66c0,1.48-1.57,1.85-2.54,3.09c-0.48,0.6-0.39,1.28-0.39,2.1 c0,0.09,0.08,0.17,0.17,0.17l1.3,0c0.11,0,0.17-0.06,0.17-0.17c0-0.72-0.07-1.13,0.28-1.54c0.91-1.05,2.65-1.46,2.65-3.7 C15.89,6.99,14.27,6,12.48,6z"/>
- <path android:fillColor="@android:color/white" android:pathData="M12.83,16h-1.66C11.08,16,11,16.08,11,16.17v1.66c0,0.09,0.08,0.17,0.17,0.17h1.66c0.09,0,0.17-0.08,0.17-0.17v-1.66 C13,16.08,12.92,16,12.83,16z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M12,2C6.48,2,2,6.48,2,12s4.48,10,10,10s10-4.48,10-10S17.52,2,12,2z M12,20.5c-4.69,0-8.5-3.81-8.5-8.5S7.31,3.5,12,3.5 s8.5,3.81,8.5,8.5S16.69,20.5,12,20.5z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M12.48,6c-1.71,0-3.53,0.96-3.53,3.17v0.37c0,0.11,0.06,0.17,0.17,0.17l1.29,0.07c0.11,0,0.17-0.06,0.17-0.17V9.17 c0-1.29,1.07-1.7,1.85-1.7c0.74,0,1.81,0.37,1.81,1.66c0,1.48-1.57,1.85-2.54,3.09c-0.48,0.6-0.39,1.28-0.39,2.1 c0,0.09,0.08,0.17,0.17,0.17l1.3,0c0.11,0,0.17-0.06,0.17-0.17c0-0.72-0.07-1.13,0.28-1.54c0.91-1.05,2.65-1.46,2.65-3.7 C15.89,6.99,14.27,6,12.48,6z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M12.83,16h-1.66C11.08,16,11,16.08,11,16.17v1.66c0,0.09,0.08,0.17,0.17,0.17h1.66c0.09,0,0.17-0.08,0.17-0.17v-1.66 C13,16.08,12.92,16,12.83,16z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_phone_info.xml b/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_phone_info.xml
index 0484309..1307f38 100644
--- a/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_phone_info.xml
+++ b/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_phone_info.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M 11.25 11 H 12.75 V 16 H 11.25 V 11 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 11.25 8 H 12.75 V 9.5 H 11.25 V 8 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M17.59,1H6.41L5,2.41v19.17L6.41,23h11.17L19,21.59V2.41L17.59,1z M17.5,2.5v1.75h-11V2.5H17.5z M17.5,5.75v12.5h-11V5.75 H17.5z M6.5,21.5v-1.75h11v1.75H6.5z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 11.25 11 H 12.75 V 16 H 11.25 V 11 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 11.25 8 H 12.75 V 9.5 H 11.25 V 8 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M17.59,1H6.41L5,2.41v19.17L6.41,23h11.17L19,21.59V2.41L17.59,1z M17.5,2.5v1.75h-11V2.5H17.5z M17.5,5.75v12.5h-11V5.75 H17.5z M6.5,21.5v-1.75h11v1.75H6.5z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_settings_accessibility.xml b/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_settings_accessibility.xml
index 7f80c7d..5983b89 100644
--- a/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_settings_accessibility.xml
+++ b/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_settings_accessibility.xml
@@ -14,6 +14,6 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M20.5,4c-2.61,0.7-5.67,1-8.5,1S6.11,4.7,3.5,4L3,6c1.86,0.5,4,0.83,6,1v13h2v-6h2v6h2V7c2-0.17,4.14-0.5,6-1L20.5,4z M12,4c1.1,0,2-0.9,2-2c0-1.1-0.9-2-2-2s-2,0.9-2,2C10,3.1,10.9,4,12,4"/>
- <path android:fillColor="@android:color/white" android:pathData="M7,24h2v-2H7V24z M11,24h2v-2h-2V24z M15,24h2v-2h-2V24z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M20.5,4c-2.61,0.7-5.67,1-8.5,1S6.11,4.7,3.5,4L3,6c1.86,0.5,4,0.83,6,1v13h2v-6h2v6h2V7c2-0.17,4.14-0.5,6-1L20.5,4z M12,4c1.1,0,2-0.9,2-2c0-1.1-0.9-2-2-2s-2,0.9-2,2C10,3.1,10.9,4,12,4"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M7,24h2v-2H7V24z M11,24h2v-2h-2V24z M15,24h2v-2h-2V24z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_settings_accounts.xml b/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_settings_accounts.xml
index 758e63f..3a997b0 100644
--- a/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_settings_accounts.xml
+++ b/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_settings_accounts.xml
@@ -14,6 +14,6 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M12,13c1.93,0,3.5-1.57,3.5-3.5S13.93,6,12,6S8.5,7.57,8.5,9.5S10.07,13,12,13z M12,7.5c1.1,0,2,0.9,2,2s-0.9,2-2,2 s-2-0.9-2-2S10.9,7.5,12,7.5z"/>
- <path android:fillColor="@android:color/white" android:pathData="M19.5,3h-15L3,4.5v15L4.5,21h15l1.5-1.5v-15L19.5,3z M19.5,19.5h-15v-1.65c1.76-1.53,5.37-2.35,7.5-2.35 c1.45,0,3.76,0.38,5.67,1.24c0.62,0.28,1.29,0.65,1.83,1.12V19.5z M19.5,16.02C17.26,14.64,14.04,14,12,14s-5.26,0.64-7.5,2.02 V4.5h15V16.02z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M12,13c1.93,0,3.5-1.57,3.5-3.5S13.93,6,12,6S8.5,7.57,8.5,9.5S10.07,13,12,13z M12,7.5c1.1,0,2,0.9,2,2s-0.9,2-2,2 s-2-0.9-2-2S10.9,7.5,12,7.5z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M19.5,3h-15L3,4.5v15L4.5,21h15l1.5-1.5v-15L19.5,3z M19.5,19.5h-15v-1.65c1.76-1.53,5.37-2.35,7.5-2.35 c1.45,0,3.76,0.38,5.67,1.24c0.62,0.28,1.29,0.65,1.83,1.12V19.5z M19.5,16.02C17.26,14.64,14.04,14,12,14s-5.26,0.64-7.5,2.02 V4.5h15V16.02z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_settings_battery_white.xml b/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_settings_battery_white.xml
index e1b7945..ca9bfc9 100644
--- a/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_settings_battery_white.xml
+++ b/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_settings_battery_white.xml
@@ -14,5 +14,5 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M 16.59 4 L 15 4 L 14 2 L 10 2 L 9 4 L 7.41 4 L 6 5.41 L 6 20.59 L 7.41 22 L 16.59 22 L 18 20.59 L 18 5.41 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 16.59 4 L 15 4 L 14 2 L 10 2 L 9 4 L 7.41 4 L 6 5.41 L 6 20.59 L 7.41 22 L 16.59 22 L 18 20.59 L 18 5.41 Z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_settings_display_white.xml b/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_settings_display_white.xml
index c7d8a61..adf1c82 100644
--- a/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_settings_display_white.xml
+++ b/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_settings_display_white.xml
@@ -14,6 +14,6 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M12,7v10c2.76,0,5-2.24,5-5S14.76,7,12,7z"/>
- <path android:fillColor="@android:color/white" android:pathData="M22.81,12.5v-1L20,8.69V4.71l0,0L19.29,4l0,0h-3.98L12.5,1.19h-1v0L8.69,4H4.71l0,0L4,4.71l0,0v3.98L1.19,11.5v1h0 L4,15.31v3.98l0,0L4.71,20l0,0h3.98l2.81,2.81v0h1L15.31,20h3.98l0,0L20,19.29l0,0v-3.98L22.81,12.5L22.81,12.5z M18.5,14.69v3.81 h-3.81L12,21.19L9.31,18.5H5.5v-3.81L2.81,12L5.5,9.31V5.5h3.81L12,2.81l2.69,2.69h3.81v3.81L21.19,12L18.5,14.69z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M12,7v10c2.76,0,5-2.24,5-5S14.76,7,12,7z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M22.81,12.5v-1L20,8.69V4.71l0,0L19.29,4l0,0h-3.98L12.5,1.19h-1v0L8.69,4H4.71l0,0L4,4.71l0,0v3.98L1.19,11.5v1h0 L4,15.31v3.98l0,0L4.71,20l0,0h3.98l2.81,2.81v0h1L15.31,20h3.98l0,0L20,19.29l0,0v-3.98L22.81,12.5L22.81,12.5z M18.5,14.69v3.81 h-3.81L12,21.19L9.31,18.5H5.5v-3.81L2.81,12L5.5,9.31V5.5h3.81L12,2.81l2.69,2.69h3.81v3.81L21.19,12L18.5,14.69z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_settings_location.xml b/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_settings_location.xml
index 7975db6..90ad165 100644
--- a/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_settings_location.xml
+++ b/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_settings_location.xml
@@ -14,6 +14,6 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M12,2c-4.2,0-8,3.22-8,8.2c0,3.11,2.33,6.62,7,10.8h2c4.67-4.18,7-7.7,7-10.8C20,5.22,16.2,2,12,2z M12.42,19.5h-0.84 c-4.04-3.7-6.08-6.74-6.08-9.3c0-4.35,3.35-6.7,6.5-6.7s6.5,2.35,6.5,6.7C18.5,12.76,16.46,15.8,12.42,19.5z"/>
- <path android:fillColor="@android:color/white" android:pathData="M12,7c-1.66,0-3,1.34-3,3c0,1.66,1.34,3,3,3s3-1.34,3-3C15,8.34,13.66,7,12,7z M12,11.5c-0.83,0-1.5-0.67-1.5-1.5 c0-0.83,0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5C13.5,10.83,12.83,11.5,12,11.5z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M12,2c-4.2,0-8,3.22-8,8.2c0,3.11,2.33,6.62,7,10.8h2c4.67-4.18,7-7.7,7-10.8C20,5.22,16.2,2,12,2z M12.42,19.5h-0.84 c-4.04-3.7-6.08-6.74-6.08-9.3c0-4.35,3.35-6.7,6.5-6.7s6.5,2.35,6.5,6.7C18.5,12.76,16.46,15.8,12.42,19.5z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M12,7c-1.66,0-3,1.34-3,3c0,1.66,1.34,3,3,3s3-1.34,3-3C15,8.34,13.66,7,12,7z M12,11.5c-0.83,0-1.5-0.67-1.5-1.5 c0-0.83,0.67-1.5,1.5-1.5s1.5,0.67,1.5,1.5C13.5,10.83,12.83,11.5,12,11.5z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_settings_privacy.xml b/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_settings_privacy.xml
index 7da20c1..f499227 100644
--- a/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_settings_privacy.xml
+++ b/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_settings_privacy.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M12,8.5c1.48,0,2.71,1.08,2.95,2.5h1.5C16.2,8.76,14.31,7,12,7c-2.48,0-4.5,2.02-4.5,4.5c0,2.48,2.02,4.5,4.5,4.5 c0.72,0,1.39-0.19,2-0.49v-1.79c-0.53,0.48-1.23,0.78-2,0.78c-1.65,0-3-1.35-3-3S10.35,8.5,12,8.5z"/>
- <path android:fillColor="@android:color/white" android:pathData="M12,4C7.38,4,3.4,6.65,1.45,10.51v1.97C3.4,16.35,7.38,19,12,19c0.68,0,1.35-0.06,2-0.18v-1.54 c-0.65,0.13-1.32,0.22-2,0.22c-4.07,0-7.68-2.34-9.37-6c1.69-3.66,5.3-6,9.37-6c3.87,0,7.32,2.13,9.09,5.5h1.46v-0.49 C20.6,6.65,16.62,4,12,4z"/>
- <path android:fillColor="@android:color/white" android:pathData="M21,14l-1-1h-2l-1,1v2h-1v5h6v-5h-1V14z M19.5,16h-1v-1.5h1V16z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M12,8.5c1.48,0,2.71,1.08,2.95,2.5h1.5C16.2,8.76,14.31,7,12,7c-2.48,0-4.5,2.02-4.5,4.5c0,2.48,2.02,4.5,4.5,4.5 c0.72,0,1.39-0.19,2-0.49v-1.79c-0.53,0.48-1.23,0.78-2,0.78c-1.65,0-3-1.35-3-3S10.35,8.5,12,8.5z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M12,4C7.38,4,3.4,6.65,1.45,10.51v1.97C3.4,16.35,7.38,19,12,19c0.68,0,1.35-0.06,2-0.18v-1.54 c-0.65,0.13-1.32,0.22-2,0.22c-4.07,0-7.68-2.34-9.37-6c1.69-3.66,5.3-6,9.37-6c3.87,0,7.32,2.13,9.09,5.5h1.46v-0.49 C20.6,6.65,16.62,4,12,4z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M21,14l-1-1h-2l-1,1v2h-1v5h6v-5h-1V14z M19.5,16h-1v-1.5h1V16z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_settings_security_white.xml b/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_settings_security_white.xml
index fbf6ae1..49d31f7 100644
--- a/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_settings_security_white.xml
+++ b/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_settings_security_white.xml
@@ -14,6 +14,6 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M21,2h-5l-1.5,1.5l0,4.5h-9L4,9.5v11L5.5,22h13l1.5-1.5v-11L18.5,8H16V3.5h5v2.62h1.5V3.5L21,2z M18.5,20.5h-13v-11h13 V20.5z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 12 13 C 13.1045694997 13 14 13.8954305003 14 15 C 14 16.1045694997 13.1045694997 17 12 17 C 10.8954305003 17 10 16.1045694997 10 15 C 10 13.8954305003 10.8954305003 13 12 13 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M21,2h-5l-1.5,1.5l0,4.5h-9L4,9.5v11L5.5,22h13l1.5-1.5v-11L18.5,8H16V3.5h5v2.62h1.5V3.5L21,2z M18.5,20.5h-13v-11h13 V20.5z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 12 13 C 13.1045694997 13 14 13.8954305003 14 15 C 14 16.1045694997 13.1045694997 17 12 17 C 10.8954305003 17 10 16.1045694997 10 15 C 10 13.8954305003 10.8954305003 13 12 13 Z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml b/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml
index 0594b9a..b668eb2 100644
--- a/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml
+++ b/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_settings_system_dashboard_white.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2,2,6.48,2,12s4.48,10,10,10s10-4.48,10-10S17.52,2,12,2z M12,20.5c-4.69,0-8.5-3.81-8.5-8.5S7.31,3.5,12,3.5 s8.5,3.81,8.5,8.5S16.69,20.5,12,20.5z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 11.25 10 H 12.75 V 17 H 11.25 V 10 Z"/>
- <path android:fillColor="@android:color/white" android:pathData="M 11.25 7 H 12.75 V 8.5 H 11.25 V 7 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M12,2C6.48,2,2,6.48,2,12s4.48,10,10,10s10-4.48,10-10S17.52,2,12,2z M12,20.5c-4.69,0-8.5-3.81-8.5-8.5S7.31,3.5,12,3.5 s8.5,3.81,8.5,8.5S16.69,20.5,12,20.5z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 11.25 10 H 12.75 V 17 H 11.25 V 10 Z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M 11.25 7 H 12.75 V 8.5 H 11.25 V 7 Z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_settings_wireless.xml b/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_settings_wireless.xml
index 802a041..9223902 100644
--- a/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_settings_wireless.xml
+++ b/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_settings_wireless.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
<vector android:height="24dp" android:tint="?android:attr/colorControlNormal" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M12,4.5c-4.29,0-8.17,1.72-11.01,4.49l1.42,1.42C4.89,8,8.27,6.5,12,6.5c3.73,0,7.11,1.5,9.59,3.91l1.42-1.42 C20.17,6.22,16.29,4.5,12,4.5z"/>
- <path android:fillColor="@android:color/white" android:pathData="M4.93,12.93l1.42,1.42C7.79,12.9,9.79,12,12,12s4.21,0.9,5.65,2.35l1.42-1.42C17.26,11.12,14.76,10,12,10 S6.74,11.12,4.93,12.93z"/>
- <path android:fillColor="@android:color/white" android:pathData="M9.06,17.06L12,20l2.94-2.94c-0.73-0.8-1.77-1.31-2.94-1.31S9.79,16.26,9.06,17.06z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M12,4.5c-4.29,0-8.17,1.72-11.01,4.49l1.42,1.42C4.89,8,8.27,6.5,12,6.5c3.73,0,7.11,1.5,9.59,3.91l1.42-1.42 C20.17,6.22,16.29,4.5,12,4.5z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M4.93,12.93l1.42,1.42C7.79,12.9,9.79,12,12,12s4.21,0.9,5.65,2.35l1.42-1.42C17.26,11.12,14.76,10,12,10 S6.74,11.12,4.93,12.93z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M9.06,17.06L12,20l2.94-2.94c-0.73-0.8-1.77-1.31-2.94-1.31S9.79,16.26,9.06,17.06z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_storage_white.xml b/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_storage_white.xml
index 45288f9..22f6092 100644
--- a/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_storage_white.xml
+++ b/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_storage_white.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M19.5,4h-15L3,5.5v1L4.5,8h15L21,6.5v-1L19.5,4z M6.5,6.75H5v-1.5h1.5V6.75z"/>
- <path android:fillColor="@android:color/white" android:pathData="M4.5,10L3,11.5v1L4.5,14h15l1.5-1.5v-1L19.5,10H4.5z M6.5,12.75H5v-1.5h1.5V12.75z"/>
- <path android:fillColor="@android:color/white" android:pathData="M4.5,16L3,17.5v1L4.5,20h15l1.5-1.5v-1L19.5,16H4.5z M6.5,18.75H5v-1.5h1.5V18.75z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M19.5,4h-15L3,5.5v1L4.5,8h15L21,6.5v-1L19.5,4z M6.5,6.75H5v-1.5h1.5V6.75z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M4.5,10L3,11.5v1L4.5,14h15l1.5-1.5v-1L19.5,10H4.5z M6.5,12.75H5v-1.5h1.5V12.75z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M4.5,16L3,17.5v1L4.5,20h15l1.5-1.5v-1L19.5,16H4.5z M6.5,18.75H5v-1.5h1.5V18.75z"/>
</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_volume_up_24dp.xml b/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_volume_up_24dp.xml
index 781ed94..964f668 100644
--- a/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_volume_up_24dp.xml
+++ b/packages/overlays/IconPackVictorSettingsOverlay/res/drawable/ic_volume_up_24dp.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
<vector android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@android:color/white" android:pathData="M7,9H4.5L3,10.5v3L4.5,15H7l4,4h1V5h-1L7,9z M10.5,16.38L7.62,13.5H4.5v-3h3.12l2.88-2.88V16.38z"/>
- <path android:fillColor="@android:color/white" android:pathData="M14,3.23v1.55c3.17,0.88,5.5,3.78,5.5,7.22s-2.33,6.34-5.5,7.22v1.55c4.01-0.91,7-4.49,7-8.77S18.01,4.14,14,3.23z"/>
- <path android:fillColor="@android:color/white" android:pathData="M16.5,12c0-1.76-1.02-3.27-2.5-4.01v8.02C15.48,15.27,16.5,13.76,16.5,12z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M7,9H4.5L3,10.5v3L4.5,15H7l4,4h1V5h-1L7,9z M10.5,16.38L7.62,13.5H4.5v-3h3.12l2.88-2.88V16.38z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M14,3.23v1.55c3.17,0.88,5.5,3.78,5.5,7.22s-2.33,6.34-5.5,7.22v1.55c4.01-0.91,7-4.49,7-8.77S18.01,4.14,14,3.23z"/>
+ <path android:fillColor="?android:attr/colorPrimary" android:pathData="M16.5,12c0-1.76-1.02-3.27-2.5-4.01v8.02C15.48,15.27,16.5,13.76,16.5,12z"/>
</vector>
\ No newline at end of file
diff --git a/proto/src/metrics_constants/metrics_constants.proto b/proto/src/metrics_constants/metrics_constants.proto
index 3f712dd..f759d7a 100644
--- a/proto/src/metrics_constants/metrics_constants.proto
+++ b/proto/src/metrics_constants/metrics_constants.proto
@@ -7435,5 +7435,8 @@
// ---- End Q Constants, all Q constants go above this line ----
// Add new aosp constants above this line.
// END OF AOSP CONSTANTS
+
+ // Blissify
+ BLISSIFY = 1990;
}
}
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 2110061..ad91924 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -395,12 +395,14 @@
.toString());
long identity = Binder.clearCallingIdentity();
try {
- return PendingIntent.getActivity(getContext(),
+ return PendingIntent.getActivityAsUser(getContext(),
0 /* request code */,
NotificationAccessConfirmationActivityContract.launcherIntent(
userId, component, packageTitle),
PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_ONE_SHOT
- | PendingIntent.FLAG_CANCEL_CURRENT);
+ | PendingIntent.FLAG_CANCEL_CURRENT,
+ null /* options */,
+ new UserHandle(userId));
} finally {
Binder.restoreCallingIdentity(identity);
}
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 4bba0d8..290a294 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -131,6 +131,7 @@
"netd_aidl_interfaces-platform-java",
"overlayable_policy_aidl-java",
"SurfaceFlingerProperties",
+ "vendor.lineage.biometrics.fingerprint.inscreen-V1.0-java",
],
}
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 7cdcc01..0ba5e52 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -205,6 +205,7 @@
int mBroadcastRefCount = 0;
PowerManager.WakeLock mWakeLock;
SparseIntArray mAlarmsPerUid = new SparseIntArray();
+ private QCNsrmAlarmExtension qcNsrmExt = new QCNsrmAlarmExtension(this);
ArrayList<Alarm> mPendingNonWakeupAlarms = new ArrayList<>();
ArrayList<InFlight> mInFlight = new ArrayList<>();
private final ArrayList<AlarmManagerInternal.InFlightListener> mInFlightListeners =
@@ -2208,6 +2209,16 @@
}
@Override
+ /* updates the blocked uids, so if a wake lock is acquired to only fire
+ * alarm for it, it can be released.
+ */
+ public void updateBlockedUids(int uid, boolean isBlocked) {
+ synchronized(mLock) {
+ qcNsrmExt.processBlockedUids(uid, isBlocked, mWakeLock);
+ }
+ }
+
+ @Override
public void onShellCommand(FileDescriptor in, FileDescriptor out,
FileDescriptor err, String[] args, ShellCallback callback,
ResultReceiver resultReceiver) {
@@ -4145,11 +4156,10 @@
mWakeLock.setWorkSource(new WorkSource(knownUid));
return;
}
+ // Something went wrong; fall back to attributing the lock to the OS
+ mWakeLock.setWorkSource(null);
} catch (Exception e) {
}
-
- // Something went wrong; fall back to attributing the lock to the OS
- mWakeLock.setWorkSource(null);
}
private static int getAlarmAttributionUid(Alarm alarm) {
@@ -4623,9 +4633,13 @@
if (DEBUG_WAKELOCK) {
Slog.d(TAG, "mBroadcastRefCount -> " + mBroadcastRefCount);
}
+ qcNsrmExt.removeTriggeredUid(inflight.mUid);
+
if (mBroadcastRefCount == 0) {
mHandler.obtainMessage(AlarmHandler.REPORT_ALARMS_ACTIVE, 0).sendToTarget();
- mWakeLock.release();
+ if (mWakeLock.isHeld()) {
+ mWakeLock.release();
+ }
if (mInFlight.size() > 0) {
mLog.w("Finished all dispatches with " + mInFlight.size()
+ " remaining inflights");
@@ -4794,7 +4808,9 @@
}
if (mBroadcastRefCount == 0) {
setWakelockWorkSource(alarm.workSource, alarm.creatorUid, alarm.statsTag, true);
+ if (!mWakeLock.isHeld()) {
mWakeLock.acquire();
+ }
mHandler.obtainMessage(AlarmHandler.REPORT_ALARMS_ACTIVE, 1).sendToTarget();
}
final InFlight inflight = new InFlight(AlarmManagerService.this, alarm, nowELAPSED);
@@ -4803,6 +4819,10 @@
if (inflight.isBroadcast()) {
notifyBroadcastAlarmPendingLocked(alarm.uid);
}
+ qcNsrmExt.addTriggeredUid((alarm.operation != null) ?
+ alarm.operation.getCreatorUid() :
+ alarm.uid);
+
if (allowWhileIdle) {
// Record the last time this uid handled an ALLOW_WHILE_IDLE alarm.
mLastAllowWhileIdleDispatch.put(alarm.creatorUid, nowELAPSED);
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index 8dd4fa6..bf47a33 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -72,9 +72,12 @@
import com.android.server.lights.LightsManager;
import com.android.server.lights.LogicalLight;
+import java.io.BufferedReader;
import java.io.File;
import java.io.FileDescriptor;
+import java.io.FileNotFoundException;
import java.io.FileOutputStream;
+import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayDeque;
@@ -174,6 +177,18 @@
private boolean mBatteryLevelLow;
+ private boolean mDashCharger;
+ private boolean mHasDashCharger;
+ private boolean mLastDashCharger;
+
+ private boolean mWarpCharger;
+ private boolean mHasWarpCharger;
+ private boolean mLastWarpCharger;
+
+ private boolean mVoocCharger;
+ private boolean mHasVoocCharger;
+ private boolean mLastVoocCharger;
+
private long mDischargeStartTime;
private int mDischargeStartLevel;
@@ -205,6 +220,13 @@
mBatteryStats = BatteryStatsService.getService();
mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
+ mHasDashCharger = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_hasDashCharger);
+ mHasWarpCharger = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_hasWarpCharger);
+ mHasVoocCharger = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_hasVoocCharger);
+
mCriticalBatteryLevel = mContext.getResources().getInteger(
com.android.internal.R.integer.config_criticalBatteryWarningLevel);
mLowBatteryWarningLevel = mContext.getResources().getInteger(
@@ -501,6 +523,10 @@
shutdownIfNoPowerLocked();
shutdownIfOverTempLocked();
+ mDashCharger = mHasDashCharger && isDashCharger();
+ mWarpCharger = mHasWarpCharger && isWarpCharger();
+ mVoocCharger = mHasVoocCharger && isVoocCharger();
+
if (force || (mHealthInfo.batteryStatus != mLastBatteryStatus ||
mHealthInfo.batteryHealth != mLastBatteryHealth ||
mHealthInfo.batteryPresent != mLastBatteryPresent ||
@@ -511,7 +537,10 @@
mHealthInfo.maxChargingCurrent != mLastMaxChargingCurrent ||
mHealthInfo.maxChargingVoltage != mLastMaxChargingVoltage ||
mHealthInfo.batteryChargeCounter != mLastChargeCounter ||
- mInvalidCharger != mLastInvalidCharger)) {
+ mInvalidCharger != mLastInvalidCharger ||
+ mDashCharger != mLastDashCharger ||
+ mWarpCharger != mLastWarpCharger ||
+ mVoocCharger != mLastVoocCharger)) {
if (mPlugType != mLastPlugType) {
if (mLastPlugType == BATTERY_PLUGGED_NONE) {
@@ -682,6 +711,9 @@
mLastChargeCounter = mHealthInfo.batteryChargeCounter;
mLastBatteryLevelCritical = mBatteryLevelCritical;
mLastInvalidCharger = mInvalidCharger;
+ mLastDashCharger = mDashCharger;
+ mLastWarpCharger = mWarpCharger;
+ mLastVoocCharger = mVoocCharger;
}
}
@@ -709,6 +741,9 @@
intent.putExtra(BatteryManager.EXTRA_MAX_CHARGING_CURRENT, mHealthInfo.maxChargingCurrent);
intent.putExtra(BatteryManager.EXTRA_MAX_CHARGING_VOLTAGE, mHealthInfo.maxChargingVoltage);
intent.putExtra(BatteryManager.EXTRA_CHARGE_COUNTER, mHealthInfo.batteryChargeCounter);
+ intent.putExtra(BatteryManager.EXTRA_DASH_CHARGER, mDashCharger);
+ intent.putExtra(BatteryManager.EXTRA_WARP_CHARGER, mWarpCharger);
+ intent.putExtra(BatteryManager.EXTRA_VOOC_CHARGER, mVoocCharger);
if (DEBUG) {
Slog.d(TAG, "Sending ACTION_BATTERY_CHANGED. scale:" + BATTERY_SCALE
+ ", info:" + mHealthInfo.toString());
@@ -763,6 +798,48 @@
mLastBatteryLevelChangedSentMs = SystemClock.elapsedRealtime();
}
+ private boolean isDashCharger() {
+ try {
+ FileReader file = new FileReader("/sys/class/power_supply/battery/fastchg_status");
+ BufferedReader br = new BufferedReader(file);
+ String state = br.readLine();
+ br.close();
+ file.close();
+ return "1".equals(state);
+ } catch (FileNotFoundException e) {
+ } catch (IOException e) {
+ }
+ return false;
+ }
+
+ private boolean isWarpCharger() {
+ try {
+ FileReader file = new FileReader("/sys/class/power_supply/battery/fastchg_status");
+ BufferedReader br = new BufferedReader(file);
+ String state = br.readLine();
+ br.close();
+ file.close();
+ return "1".equals(state);
+ } catch (FileNotFoundException e) {
+ } catch (IOException e) {
+ }
+ return false;
+ }
+
+ private boolean isVoocCharger() {
+ try {
+ FileReader file = new FileReader("/sys/class/power_supply/battery/voocchg_ing");
+ BufferedReader br = new BufferedReader(file);
+ String state = br.readLine();
+ br.close();
+ file.close();
+ return "1".equals(state);
+ } catch (FileNotFoundException e) {
+ } catch (IOException e) {
+ }
+ 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/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index a1cbd00..56207fe 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -142,6 +142,7 @@
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
+import android.os.FileUtils;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
@@ -351,6 +352,8 @@
private final Object mTNSLock = new Object();
private String mCurrentTcpBufferSizes;
+ private int mCurrentTcpDelayedAckSegments;
+ private int mCurrentTcpUserCfg;
private static final SparseArray<String> sMagicDecoderRing = MessageUtils.findMessageNames(
new Class[] { AsyncChannel.class, ConnectivityService.class, NetworkAgent.class,
@@ -2465,6 +2468,35 @@
}
}
+ private void updateTcpDelayedAck(NetworkAgentInfo nai) {
+ if (isDefaultNetwork(nai) == false) {
+ return;
+ }
+
+ int segments = nai.linkProperties.getTcpDelayedAckSegments();
+ int usercfg = nai.linkProperties.getTcpUserCfg();
+
+ if (segments != mCurrentTcpDelayedAckSegments) {
+ try {
+ FileUtils.stringToFile("/sys/kernel/ipv4/tcp_delack_seg",
+ String.valueOf(segments));
+ mCurrentTcpDelayedAckSegments = segments;
+ } catch (IOException e) {
+ // optional
+ }
+ }
+
+ if (usercfg != mCurrentTcpUserCfg) {
+ try {
+ FileUtils.stringToFile("/sys/kernel/ipv4/tcp_use_usercfg",
+ String.valueOf(usercfg));
+ mCurrentTcpUserCfg = usercfg;
+ } catch (IOException e) {
+ // optional
+ }
+ }
+ }
+
@Override
public int getRestoreDefaultNetworkDelay(int networkType) {
String restoreDefaultNetworkDelayStr = mSystemProperties.get(
@@ -5988,7 +6020,7 @@
if (isDefaultNetwork(networkAgent)) {
updateTcpBufferSizes(newLp.getTcpBufferSizes());
}
-
+ updateTcpDelayedAck(networkAgent);
updateRoutes(newLp, oldLp, netId);
updateDnses(newLp, oldLp, netId);
// Make sure LinkProperties represents the latest private DNS status.
@@ -6719,6 +6751,7 @@
? newNetwork.linkProperties.getHttpProxy() : null);
updateTcpBufferSizes(null != newNetwork
? newNetwork.linkProperties.getTcpBufferSizes() : null);
+ updateTcpDelayedAck(newNetwork != null ? newNetwork : null);
mDnsManager.setDefaultDnsSystemProperties(null != newNetwork
? newNetwork.linkProperties.getDnsServers() : Collections.EMPTY_LIST);
notifyIfacesChangedForNetworkStats();
diff --git a/services/core/java/com/android/server/QCNsrmAlarmExtension.java b/services/core/java/com/android/server/QCNsrmAlarmExtension.java
new file mode 100644
index 0000000..a042f72
--- /dev/null
+++ b/services/core/java/com/android/server/QCNsrmAlarmExtension.java
@@ -0,0 +1,120 @@
+/*
+ *Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *
+ *Redistribution and use in source and binary forms, with or without
+ *modification, are permitted provided that the following conditions are
+ *met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ *THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ *WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ *ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ *BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ *WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ *OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ *IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.android.server;
+
+import android.os.Binder;
+import android.os.PowerManager;
+import android.os.Process;
+import android.util.Slog;
+
+import java.util.ArrayList;
+import java.util.Timer;
+import java.util.TimerTask;
+
+public final class QCNsrmAlarmExtension {
+ static final String TAG = "QCNsrmAlarmExtn";
+ static final boolean localLOGV = false;
+ private AlarmManagerService almHandle;
+
+ //track the blocked and triggered uids in AlarmManagerService
+ private static final ArrayList<Integer> mTriggeredUids = new ArrayList<Integer>();
+ private static final ArrayList<Integer> mBlockedUids = new ArrayList<Integer>();
+ private static final int BLOCKED_UID_CHECK_INTERVAL = 1000; // 1 sec.
+
+ public QCNsrmAlarmExtension(AlarmManagerService handle) {
+ almHandle = handle;
+ }
+
+ //AlarmManagerService extension Methods
+ protected void processBlockedUids(int uid, boolean isBlocked, PowerManager.WakeLock mWakeLock ){
+ if (localLOGV) Slog.v(TAG, "UpdateBlockedUids: uid = " + uid +
+ " isBlocked = " + isBlocked);
+ if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+ if (localLOGV) Slog.v(TAG, "UpdateBlockedUids is not allowed");
+ return;
+ }
+
+ if(isBlocked) {
+ if (localLOGV) Slog.v(TAG, "updating alarmMgr mBlockedUids "+
+ "with uid " + uid);
+ mBlockedUids.add(new Integer(uid));
+ Timer checkBlockedUidTimer = new Timer();
+ checkBlockedUidTimer.schedule( new CheckBlockedUidTimerTask(
+ uid,
+ mWakeLock),
+ BLOCKED_UID_CHECK_INTERVAL);
+ } else {
+ if (localLOGV) Slog.v(TAG, "clearing alarmMgr mBlockedUids ");
+ mBlockedUids.clear();
+ }
+ }
+
+ protected void addTriggeredUid (int uid){
+ if (localLOGV) Slog.v(TAG, "adding uid to mTriggeredUids uid=" + uid);
+ mTriggeredUids.add(new Integer(uid));
+
+ }
+
+ protected void removeTriggeredUid (int uid) {
+ if (localLOGV) Slog.v(TAG, "removing uid from mTriggeredUids uid= " + uid);
+ mTriggeredUids.remove(new Integer(uid));
+ }
+
+ protected boolean hasBlockedUid (int uid) {
+
+ return mBlockedUids.contains(uid);
+
+ }
+
+ class CheckBlockedUidTimerTask extends TimerTask {
+ private int mUid;
+ PowerManager.WakeLock mWakeLock;
+
+ CheckBlockedUidTimerTask(int uid, PowerManager.WakeLock lWakeLock) {
+ mUid = uid;
+ mWakeLock = lWakeLock;
+ }
+
+ @Override
+ public void run(){
+ if (mBlockedUids.contains(mUid) && mTriggeredUids.contains(mUid)) {
+ synchronized(almHandle.mLock) {
+ if (mWakeLock.isHeld()) {
+ mWakeLock.release();
+ if (localLOGV)
+ Slog.v(TAG, "CheckBlockedUidTimerTask: AM "+
+ "WakeLock Released Internally!!");
+ }
+ }
+ return;
+ }
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/RescueParty.java b/services/core/java/com/android/server/RescueParty.java
index 9fc8f0b..e27f77d 100644
--- a/services/core/java/com/android/server/RescueParty.java
+++ b/services/core/java/com/android/server/RescueParty.java
@@ -150,6 +150,7 @@
* Check if we're currently attempting to reboot for a factory reset.
*/
public static boolean isAttemptingFactoryReset() {
+ if (isDisabled()) return false;
return SystemProperties.getInt(PROP_RESCUE_LEVEL, LEVEL_NONE) == LEVEL_FACTORY_RESET;
}
@@ -158,6 +159,7 @@
* opportunity to reset any settings depending on our rescue level.
*/
public static void onSettingsProviderPublished(Context context) {
+ if (isDisabled()) return;
handleNativeRescuePartyResets();
executeRescueLevel(context, /*failedPackage=*/ null);
ContentResolver contentResolver = context.getContentResolver();
@@ -243,6 +245,7 @@
}
private static void executeRescueLevel(Context context, @Nullable String failedPackage) {
+ if (isDisabled()) return;
final int level = SystemProperties.getInt(PROP_RESCUE_LEVEL, LEVEL_NONE);
if (level == LEVEL_NONE) return;
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 3919233..9016a6f 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -154,6 +154,7 @@
import com.android.internal.util.HexDump;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Preconditions;
+import com.android.internal.widget.ILockSettings;
import com.android.internal.widget.LockPatternUtils;
import com.android.server.pm.Installer;
import com.android.server.storage.AppFuseBridge;
@@ -1523,9 +1524,11 @@
vol.mountFlags |= VolumeInfo.MOUNT_FLAG_VISIBLE;
}
- // Adoptable public disks are visible to apps, since they meet
- // public API requirement of being in a stable location.
- if (vol.disk.isAdoptable()) {
+ // Set sdcards to visible to apps. If they are visible media is scanned
+ // and they can be used for other stuff.
+ if (vol.disk.isSd()) {
+ vol.mountFlags |= VolumeInfo.MOUNT_FLAG_VISIBLE;
+ } else if (vol.disk.isSd()) {
vol.mountFlags |= VolumeInfo.MOUNT_FLAG_VISIBLE;
}
@@ -2339,8 +2342,10 @@
final long destroy = extras.getLong("destroy");
final DropBoxManager dropBox = mContext.getSystemService(DropBoxManager.class);
- dropBox.addText(TAG_STORAGE_BENCHMARK, scrubPath(path)
- + " " + ident + " " + create + " " + run + " " + destroy);
+ if (dropBox != null) {
+ dropBox.addText(TAG_STORAGE_BENCHMARK, scrubPath(path)
+ + " " + ident + " " + create + " " + run + " " + destroy);
+ }
synchronized (mLock) {
final VolumeRecord rec = findRecordForPath(path);
@@ -2404,6 +2409,8 @@
Objects.requireNonNull(fsUuid);
synchronized (mLock) {
final VolumeRecord rec = mRecords.get(fsUuid);
+ if (rec == null)
+ return;
rec.nickname = nickname;
mCallbacks.notifyVolumeRecordChanged(rec);
writeSettingsLocked();
@@ -2417,6 +2424,8 @@
Objects.requireNonNull(fsUuid);
synchronized (mLock) {
final VolumeRecord rec = mRecords.get(fsUuid);
+ if (rec == null)
+ return;
rec.userFlags = (rec.userFlags & ~mask) | (flags & mask);
mCallbacks.notifyVolumeRecordChanged(rec);
writeSettingsLocked();
@@ -2502,7 +2511,9 @@
final long time = extras.getLong("time");
final DropBoxManager dropBox = mContext.getSystemService(DropBoxManager.class);
- dropBox.addText(TAG_STORAGE_TRIM, scrubPath(path) + " " + bytes + " " + time);
+ if (dropBox != null) {
+ dropBox.addText(TAG_STORAGE_TRIM, scrubPath(path) + " " + bytes + " " + time);
+ }
synchronized (mLock) {
final VolumeRecord rec = findRecordForPath(path);
@@ -2993,8 +3004,22 @@
Slog.i(TAG, "changing encryption password...");
}
+ ILockSettings lockSettings = ILockSettings.Stub.asInterface(
+ ServiceManager.getService("lock_settings"));
+ String currentPassword="default_password";
try {
- mVold.fdeChangePassword(type, password);
+ currentPassword = lockSettings.getPassword();
+ } catch (Exception e) {
+ Slog.wtf(TAG, "Couldn't get password" + e);
+ }
+
+ try {
+ mVold.fdeChangePassword(type, currentPassword, password);
+ try {
+ lockSettings.sanitizePassword();
+ } catch (Exception e) {
+ Slog.wtf(TAG, "Couldn't sanitize password" + e);
+ }
return 0;
} catch (Exception e) {
Slog.wtf(TAG, e);
diff --git a/services/core/java/com/android/server/WiredAccessoryManager.java b/services/core/java/com/android/server/WiredAccessoryManager.java
index 8e5c73bf..e460033 100644
--- a/services/core/java/com/android/server/WiredAccessoryManager.java
+++ b/services/core/java/com/android/server/WiredAccessoryManager.java
@@ -70,6 +70,12 @@
private static final String NAME_H2W = "h2w";
private static final String NAME_USB_AUDIO = "usb_audio";
private static final String NAME_HDMI_AUDIO = "hdmi_audio";
+ private static final String NAME_DP_AUDIO = "soc:qcom,msm-ext-disp";
+ // within a device, a single stream supports DP
+ private static final String[] DP_AUDIO_CONNS = {
+ NAME_DP_AUDIO + "/1/0",
+ NAME_DP_AUDIO + "/0/0"
+ };
private static final String NAME_HDMI = "hdmi";
private static final int MSG_NEW_DEVICE_STATE = 1;
@@ -81,6 +87,7 @@
private final AudioManager mAudioManager;
private int mHeadsetState;
+ private int mDpCount;
private int mSwitchValues;
@@ -123,7 +130,7 @@
}
- if (ExtconUEventObserver.extconExists()) {
+ if (ExtconUEventObserver.extconExists() && mExtconObserver.uEventCount() > 0) {
if (mUseDevInputEventForAudioJack) {
Log.w(TAG, "Both input event and extcon are used for audio jack,"
+ " please just choose one.");
@@ -172,7 +179,7 @@
break;
}
- updateLocked(NAME_H2W,
+ updateLocked(NAME_H2W, "",
(mHeadsetState & ~(BIT_HEADSET | BIT_HEADSET_NO_MIC | BIT_LINEOUT)) | headset);
}
}
@@ -193,25 +200,32 @@
* results in support for the last one plugged in. Similarly, unplugging either is seen as
* unplugging all.
*
+ * For Display port allow up to two connections.
+ * Block display port request if HDMI already connected and vice versa.
+ *
* @param newName One of the NAME_xxx variables defined above.
* @param newState 0 or one of the BIT_xxx variables defined above.
*/
- private void updateLocked(String newName, int newState) {
+ private void updateLocked(String newName, String address, int newState) {
// Retain only relevant bits
int headsetState = newState & SUPPORTED_HEADSETS;
+ int newDpState = newState & BIT_HDMI_AUDIO;
int usb_headset_anlg = headsetState & BIT_USB_HEADSET_ANLG;
int usb_headset_dgtl = headsetState & BIT_USB_HEADSET_DGTL;
int h2w_headset = headsetState & (BIT_HEADSET | BIT_HEADSET_NO_MIC | BIT_LINEOUT);
boolean h2wStateChange = true;
boolean usbStateChange = true;
+ boolean dpBitState = (mHeadsetState & BIT_HDMI_AUDIO) > 0;
+ boolean dpCountState = mDpCount != 0;
if (LOG) {
Slog.v(TAG, "newName=" + newName
+ " newState=" + newState
+ " headsetState=" + headsetState
- + " prev headsetState=" + mHeadsetState);
+ + " prev headsetState=" + mHeadsetState
+ + " num of active dp conns= " + mDpCount);
}
- if (mHeadsetState == headsetState) {
+ if (mHeadsetState == headsetState && !newName.startsWith(NAME_DP_AUDIO)) {
Log.e(TAG, "No state change.");
return;
}
@@ -234,11 +248,42 @@
return;
}
+ if (newName.startsWith(NAME_DP_AUDIO)) {
+ if ((newDpState > 0) && (mDpCount < DP_AUDIO_CONNS.length)
+ && (dpBitState == dpCountState)) {
+ // Allow DP0 if no HDMI previously connected.
+ // Allow second request only if DP connected previously.
+ mDpCount++;
+ } else if ((newDpState == 0) && (mDpCount > 0)) {
+ mDpCount--;
+ } else {
+ Log.e(TAG, "No state change for DP.");
+ return;
+ }
+ }
+
mWakeLock.acquire();
Log.i(TAG, "MSG_NEW_DEVICE_STATE");
- Message msg = mHandler.obtainMessage(MSG_NEW_DEVICE_STATE, headsetState,
- mHeadsetState, "");
+ // Send a combined name, address string separated by |
+ Message msg;
+ if (newName.startsWith(NAME_DP_AUDIO)) {
+ int pseudoHeadsetState = mHeadsetState;
+ if (dpBitState && (newDpState != 0)) {
+ // One DP already connected, so allow request to connect second.
+ pseudoHeadsetState = mHeadsetState & (~BIT_HDMI_AUDIO);
+ }
+ msg = mHandler.obtainMessage(MSG_NEW_DEVICE_STATE, headsetState,
+ pseudoHeadsetState, NAME_DP_AUDIO + "/" + address);
+
+ if ((headsetState == 0) && (mDpCount != 0)) {
+ // Atleast one DP is connected, so keep mHeadsetState's DP bit set.
+ headsetState = headsetState | BIT_HDMI_AUDIO;
+ }
+ } else {
+ msg = mHandler.obtainMessage(MSG_NEW_DEVICE_STATE, headsetState,
+ mHeadsetState, newName + "/" + address);
+ }
mHandler.sendMessage(msg);
mHeadsetState = headsetState;
@@ -261,12 +306,13 @@
};
private void setDevicesState(
- int headsetState, int prevHeadsetState, String headsetName) {
+ int headsetState, int prevHeadsetState, String headsetNameAddr) {
synchronized (mLock) {
int allHeadsets = SUPPORTED_HEADSETS;
for (int curHeadset = 1; allHeadsets != 0; curHeadset <<= 1) {
if ((curHeadset & allHeadsets) != 0) {
- setDeviceStateLocked(curHeadset, headsetState, prevHeadsetState, headsetName);
+ setDeviceStateLocked(curHeadset, headsetState, prevHeadsetState,
+ headsetNameAddr);
allHeadsets &= ~curHeadset;
}
}
@@ -274,7 +320,7 @@
}
private void setDeviceStateLocked(int headset,
- int headsetState, int prevHeadsetState, String headsetName) {
+ int headsetState, int prevHeadsetState, String headsetNameAddr) {
if ((headsetState & headset) != (prevHeadsetState & headset)) {
int outDevice = 0;
int inDevice = 0;
@@ -305,15 +351,18 @@
}
if (LOG) {
- Slog.v(TAG, "headsetName: " + headsetName +
+ Slog.v(TAG, "headsetNameAddr: " + headsetNameAddr +
(state == 1 ? " connected" : " disconnected"));
}
+ String[] hs = headsetNameAddr.split("/");
if (outDevice != 0) {
- mAudioManager.setWiredDeviceConnectionState(outDevice, state, "", headsetName);
+ mAudioManager.setWiredDeviceConnectionState(outDevice, state,
+ (hs.length > 1 ? hs[1] : ""), hs[0]);
}
if (inDevice != 0) {
- mAudioManager.setWiredDeviceConnectionState(inDevice, state, "", headsetName);
+ mAudioManager.setWiredDeviceConnectionState(inDevice, state,
+ (hs.length > 1 ? hs[1] : ""), hs[0]);
}
}
}
@@ -416,22 +465,91 @@
}
}
+ for (String conn : DP_AUDIO_CONNS) {
+ // Monitor DisplayPort
+ if (LOG) {
+ Slog.v(TAG, "Monitor DP conn " + conn);
+ }
+ uei = new UEventInfo(conn, BIT_HDMI_AUDIO, 0, 0);
+ if (uei.checkSwitchExists()) {
+ retVal.add(uei);
+ } else {
+ Slog.w(TAG, "Conn " + conn + " does not have DP audio support");
+ }
+ }
+
return retVal;
}
@Override
public void onUEvent(UEventObserver.UEvent event) {
- if (LOG) Slog.v(TAG, "Headset UEVENT: " + event.toString());
+ String devPath = event.get("DEVPATH");
+ String name = event.get("NAME");
+ int state = 0;
+
+ if (name == null) {
+ name = event.get("SWITCH_NAME");
+ }
try {
- String devPath = event.get("DEVPATH");
- String name = event.get("SWITCH_NAME");
- int state = Integer.parseInt(event.get("SWITCH_STATE"));
- synchronized (mLock) {
- updateStateLocked(devPath, name, state);
+ if (name.startsWith(NAME_DP_AUDIO)) {
+ String stateStr = event.get("STATE");
+ int offset = 0;
+ int length = stateStr.length();
+
+ // parse DP=1\nHDMI=1\0
+ while (offset < length) {
+ int equals = stateStr.indexOf('=', offset);
+
+ if (equals > offset) {
+ String intfName = stateStr.substring(offset, equals);
+
+ if (intfName.equals("DP")) {
+ state = Integer.parseInt(
+ stateStr.substring(equals + 1, equals + 2));
+ break;
+ }
+ }
+
+ offset = equals + 3;
+ }
+ } else {
+ state = Integer.parseInt(event.get("SWITCH_STATE"));
}
} catch (NumberFormatException e) {
- Slog.e(TAG, "Could not parse switch state from event " + event);
+ Slog.i(TAG, "couldn't get state from event, checking node");
+
+ for (int i = 0; i < mUEventInfo.size(); ++i) {
+ UEventInfo uei = mUEventInfo.get(i);
+
+ if (name.equals(uei.getDevName())) {
+ char[] buffer = new char[1024];
+ int len = 0;
+
+ try {
+ FileReader file = new FileReader(uei.getSwitchStatePath());
+ len = file.read(buffer, 0, 1024);
+ file.close();
+ } catch (FileNotFoundException e1) {
+ Slog.e(TAG, "file not found");
+ break;
+ } catch (Exception e11) {
+ Slog.e(TAG, "onUEvent exception", e11);
+ }
+
+ try {
+ state = Integer.parseInt((new String(buffer, 0, len)).trim());
+ } catch (NumberFormatException e2) {
+ Slog.e(TAG, "could not convert to number");
+ break;
+ }
+ break;
+ }
+ }
+ }
+
+ synchronized (mLock) {
+ updateStateLocked(devPath, name, state);
}
}
@@ -439,7 +557,8 @@
for (int i = 0; i < mUEventInfo.size(); ++i) {
UEventInfo uei = mUEventInfo.get(i);
if (devPath.equals(uei.getDevPath())) {
- updateLocked(name, uei.computeNewHeadsetState(mHeadsetState, state));
+ updateLocked(name, uei.getDevAddress(),
+ uei.computeNewHeadsetState(mHeadsetState, state));
return;
}
}
@@ -447,26 +566,140 @@
private final class UEventInfo {
private final String mDevName;
+ private String mDevAddress;
private final int mState1Bits;
private final int mState2Bits;
private final int mStateNbits;
+ private int mDevIndex;
+ private int mCableIndex;
public UEventInfo(String devName, int state1Bits, int state2Bits, int stateNbits) {
mDevName = devName;
+ mDevAddress = "controller=0;stream=0";
mState1Bits = state1Bits;
mState2Bits = state2Bits;
mStateNbits = stateNbits;
+
+ mDevIndex = -1;
+ mCableIndex = -1;
+
+ if (mDevName.startsWith(NAME_DP_AUDIO)) {
+ int idx = mDevName.indexOf("/");
+ if (idx != -1) {
+ int idx2 = mDevName.indexOf("/", idx + 1);
+ assert(idx2 != -1);
+ int dev = Integer.parseInt(mDevName.substring(idx + 1, idx2));
+ int cable = Integer.parseInt(mDevName.substring(idx2 + 1));
+ mDevAddress = "controller=" + cable + ";stream=" + dev;
+ if (LOG) {
+ Slog.v(TAG, "UEvent dev address " + mDevAddress);
+ }
+ checkDevIndex(dev);
+ checkCableIndex(cable);
+ }
+ }
+ }
+
+ private void checkDevIndex(int devIndex) {
+ int index = 0;
+ char[] buffer = new char[1024];
+
+ while (true) {
+ String devPath = String.format(Locale.US,
+ "/sys/devices/platform/soc/%s/extcon/extcon%d/name",
+ NAME_DP_AUDIO, index);
+ if (LOG) {
+ Slog.v(TAG, "checkDevIndex " + devPath);
+ }
+
+ File f = new File(devPath);
+ if (!f.exists()) {
+ Slog.e(TAG, "file " + devPath + " not found");
+ break;
+ }
+
+ try {
+ FileReader file = new FileReader(f);
+ int len = file.read(buffer, 0, 1024);
+ file.close();
+
+ String devName = (new String(buffer, 0, len)).trim();
+ if (devName.startsWith(NAME_DP_AUDIO) && index == devIndex) {
+ mDevIndex = devIndex;
+ break;
+ } else {
+ index++;
+ }
+ } catch (Exception e) {
+ Slog.e(TAG, "checkDevIndex exception", e);
+ break;
+ }
+ }
+ }
+
+ private void checkCableIndex(int cableIndex) {
+ if (mDevIndex == -1) {
+ return;
+ }
+ int index = 0;
+ char[] buffer = new char[1024];
+
+ while (true) {
+ String cablePath = String.format(Locale.US,
+ "/sys/devices/platform/soc/%s/extcon/extcon%d/cable.%d/name",
+ NAME_DP_AUDIO, mDevIndex, index);
+ if (LOG) {
+ Slog.v(TAG, "checkCableIndex " + cablePath);
+ }
+
+ File f = new File(cablePath);
+ if (!f.exists()) {
+ Slog.e(TAG, "file " + cablePath + " not found");
+ break;
+ }
+
+ try {
+ FileReader file = new FileReader(f);
+ int len = file.read(buffer, 0, 1024);
+ file.close();
+
+ String cableName = (new String(buffer, 0, len)).trim();
+ if (cableName.equals("DP") && index == cableIndex) {
+ mCableIndex = cableIndex;
+ break;
+ } else {
+ index++;
+ }
+ } catch (Exception e) {
+ Slog.e(TAG, "checkCableIndex exception", e);
+ break;
+ }
+ }
}
public String getDevName() {
return mDevName;
}
+ public String getDevAddress() {
+ return mDevAddress;
+ }
+
public String getDevPath() {
+ if (mDevName.startsWith(NAME_DP_AUDIO)) {
+ return String.format(Locale.US,
+ "/devices/platform/soc/%s/extcon/extcon%d",
+ NAME_DP_AUDIO, mDevIndex);
+ }
return String.format(Locale.US, "/devices/virtual/switch/%s", mDevName);
}
public String getSwitchStatePath() {
+ if (mDevName.startsWith(NAME_DP_AUDIO)) {
+ return String.format(Locale.US,
+ "/sys/devices/platform/soc/%s/extcon/extcon%d/cable.%d/state",
+ NAME_DP_AUDIO, mDevIndex, mCableIndex);
+ }
return String.format(Locale.US, "/sys/class/switch/%s/state", mDevName);
}
@@ -518,6 +751,10 @@
}
+ public int uEventCount() {
+ return mExtconInfos.size();
+ }
+
@Override
public Pair<Integer, Integer> parseState(ExtconInfo extconInfo, String status) {
if (LOG) Slog.v(TAG, "status " + status);
@@ -538,7 +775,7 @@
synchronized (mLock) {
int mask = maskAndState.first;
int state = maskAndState.second;
- updateLocked(name, mHeadsetState & ~(mask & ~state) | (mask & state));
+ updateLocked(name, "", mHeadsetState & ~(mask & ~state) | (mask & state));
return;
}
}
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index dd0e1f6..69dddeb 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -3743,6 +3743,10 @@
sr.isolatedProc = null;
mPendingServices.remove(i);
i--;
+ if (proc.isPersistent() && !proc.isolated) {
+ mRestartingServices.add(sr);
+ continue;
+ }
bringDownServiceLocked(sr);
}
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 3f4878e..8482897 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1155,6 +1155,7 @@
CoreSettingsObserver mCoreSettingsObserver;
+/*
DevelopmentSettingsObserver mDevelopmentSettingsObserver;
private final class DevelopmentSettingsObserver extends ContentObserver {
@@ -1181,13 +1182,13 @@
public void onChange() {
final boolean enabled = Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, Build.IS_ENG ? 1 : 0) != 0;
+ Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1) != 0;
mContext.getPackageManager().setComponentEnabledSetting(mBugreportStorageProvider,
enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
: PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
0);
}
- }
+ }*/
/**
* Thread-local storage used to carry caller permissions over through
@@ -7907,7 +7908,7 @@
mConstants.start(mContext.getContentResolver());
mCoreSettingsObserver = new CoreSettingsObserver(this);
mActivityTaskManager.installSystemProviders();
- mDevelopmentSettingsObserver = new DevelopmentSettingsObserver();
+ //mDevelopmentSettingsObserver = new DevelopmentSettingsObserver();
SettingsToPropertiesMapper.start(mContext.getContentResolver());
mOomAdjuster.initSettings();
@@ -8575,8 +8576,8 @@
@Override
public void requestSystemServerHeapDump() {
- if (!Build.IS_DEBUGGABLE) {
- Slog.wtf(TAG, "requestSystemServerHeapDump called on a user build");
+ if (!Build.IS_ENG) {
+ Slog.wtf(TAG, "requestSystemServerHeapDump called on a non eng build.");
return;
}
if (Binder.getCallingUid() != SYSTEM_UID) {
diff --git a/services/core/java/com/android/server/am/AppErrorDialog.java b/services/core/java/com/android/server/am/AppErrorDialog.java
index d76e2d7..9eceeb62 100644
--- a/services/core/java/com/android/server/am/AppErrorDialog.java
+++ b/services/core/java/com/android/server/am/AppErrorDialog.java
@@ -17,8 +17,12 @@
package com.android.server.am;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
+import com.android.internal.util.DogbinUtils;
+import com.android.internal.util.DogbinUtils.UploadResultCallback;
import android.content.BroadcastReceiver;
+import android.content.ClipboardManager;
+import android.content.ClipData;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -29,18 +33,23 @@
import android.os.Message;
import android.provider.Settings;
import android.text.BidiFormatter;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.TextView;
+import android.widget.Toast;
final class AppErrorDialog extends BaseErrorDialog implements View.OnClickListener {
+ private static final String TAG = "AppErrorDialog";
+
private final ActivityManagerService mService;
private final AppErrorResult mResult;
private final ProcessRecord mProc;
private final boolean mIsRestartable;
+ private String mPaste;
static int CANT_SHOW = -1;
static int BACKGROUND_USER = -2;
@@ -68,6 +77,7 @@
mIsRestartable = (data.taskId != INVALID_TASK_ID || data.isRestartableForService)
&& Settings.Global.getInt(context.getContentResolver(),
Settings.Global.SHOW_RESTART_IN_CRASH_DIALOG, 0) != 0;
+ mPaste = data.paste;
BidiFormatter bidi = BidiFormatter.getInstance();
CharSequence name;
@@ -120,13 +130,15 @@
final TextView report = findViewById(com.android.internal.R.id.aerr_report);
report.setOnClickListener(this);
report.setVisibility(hasReceiver ? View.VISIBLE : View.GONE);
+ final TextView copy = findViewById(com.android.internal.R.id.aerr_copy);
+ copy.setOnClickListener(this);
final TextView close = findViewById(com.android.internal.R.id.aerr_close);
close.setOnClickListener(this);
final TextView appInfo = findViewById(com.android.internal.R.id.aerr_app_info);
appInfo.setOnClickListener(this);
boolean showMute = !Build.IS_USER && Settings.Global.getInt(context.getContentResolver(),
- Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0
+ Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1) != 0
&& Settings.Global.getInt(context.getContentResolver(),
Settings.Global.SHOW_MUTE_IN_CRASH_DIALOG, 0) != 0;
final TextView mute = findViewById(com.android.internal.R.id.aerr_mute);
@@ -188,6 +200,10 @@
case com.android.internal.R.id.aerr_report:
mHandler.obtainMessage(FORCE_QUIT_AND_REPORT).sendToTarget();
break;
+ case com.android.internal.R.id.aerr_copy:
+ postToDogbinAndCopyURL();
+ mHandler.obtainMessage(FORCE_QUIT).sendToTarget();
+ break;
case com.android.internal.R.id.aerr_close:
mHandler.obtainMessage(FORCE_QUIT).sendToTarget();
break;
@@ -202,6 +218,25 @@
}
}
+ private void postToDogbinAndCopyURL() {
+ // Post to dogbin
+ DogbinUtils.upload(mPaste, new UploadResultCallback() {
+ public void onSuccess(String url) {
+ // Copy to clipboard
+ ClipboardManager clipboard = (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE);
+ clipboard.setPrimaryClip(ClipData.newPlainText("Log URL", url));
+
+ // Show toast
+ Toast.makeText(getContext(), com.android.internal.R.string.url_copy_success, Toast.LENGTH_LONG).show();
+ }
+
+ public void onFail(String message, Exception e) {
+ Toast.makeText(getContext(), com.android.internal.R.string.url_copy_failed, Toast.LENGTH_LONG).show();
+ Log.e(TAG, message, e);
+ }
+ });
+ }
+
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -217,5 +252,6 @@
boolean repeating;
ProcessRecord proc;
boolean isRestartableForService;
+ String paste;
}
}
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index 50d2cab..178b660 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -490,6 +490,11 @@
return;
}
+ // Add paste content for dogbin option
+ data.paste = "time: " + timeMillis + "\n" +
+ "msg: " + longMsg + "\n" +
+ "stacktrace: " + stackTrace;
+
final Message msg = Message.obtain();
msg.what = ActivityManagerService.SHOW_ERROR_UI_MSG;
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 090ac54..3441d8f 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -423,6 +423,14 @@
}
}
+ public void resetStatistics() {
+ mContext.enforceCallingPermission(
+ android.Manifest.permission.RESET_BATTERY_STATS, null);
+ synchronized (mStats) {
+ mStats.resetAllStatsCmdLocked();
+ }
+ }
+
public long computeBatteryTimeRemaining() {
synchronized (mStats) {
long time = mStats.computeBatteryTimeRemaining(SystemClock.elapsedRealtime());
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 2d8d2c3..dae1428 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -645,7 +645,7 @@
// 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, Build.FINGERPRINT)) {
+ if (!Objects.equals(info.lastLoggedInFingerprint, Build.DATE)) {
// Suppress double notifications for managed profiles that
// were unlocked automatically as part of their parent user
// being unlocked.
diff --git a/services/core/java/com/android/server/attention/AttentionManagerService.java b/services/core/java/com/android/server/attention/AttentionManagerService.java
index e8acbd4..619ab2f 100644
--- a/services/core/java/com/android/server/attention/AttentionManagerService.java
+++ b/services/core/java/com/android/server/attention/AttentionManagerService.java
@@ -396,7 +396,7 @@
final ResolveInfo resolveInfo = context.getPackageManager().resolveService(intent, flags);
if (resolveInfo == null || resolveInfo.serviceInfo == null) {
- Slog.wtf(LOG_TAG, String.format("Service %s not found in package %s",
+ Slog.v(LOG_TAG, String.format("Service %s not found in package %s",
AttentionService.SERVICE_INTERFACE, serviceConfigPackage
));
return null;
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index 074d3fe..90ceec2 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -403,6 +403,15 @@
devInfoToRemove);
}
+ /*package*/ void postBluetoothA2dpDeviceConfigChangeExt(
+ @NonNull BluetoothDevice device,
+ @AudioService.BtProfileConnectionState int state, int profile,
+ boolean suppressNoisyIntent, int a2dpVolume) {
+ final BtDeviceConnectionInfo info = new BtDeviceConnectionInfo(device, state, profile,
+ suppressNoisyIntent, a2dpVolume);
+ sendLMsgNoDelay(MSG_L_A2DP_ACTIVE_DEVICE_CHANGE_EXT, SENDMSG_QUEUE, info);
+ }
+
private static final class HearingAidDeviceConnectionInfo {
final @NonNull BluetoothDevice mDevice;
final @AudioService.BtProfileConnectionState int mState;
@@ -1096,6 +1105,22 @@
case MSG_CHECK_MUTE_MUSIC:
checkMessagesMuteMusic(0);
break;
+ case MSG_L_A2DP_ACTIVE_DEVICE_CHANGE_EXT: {
+ final BtDeviceConnectionInfo info = (BtDeviceConnectionInfo) msg.obj;
+ AudioService.sDeviceLogger.log((new AudioEventLogger.StringEvent(
+ "handleBluetoothA2dpActiveDeviceChangeExt "
+ + " state=" + info.mState
+ // only querying address as this is the only readily available
+ // field on the device
+ + " addr=" + info.mDevice.getAddress()
+ + " prof=" + info.mProfile + " supprNoisy=" + info.mSupprNoisy
+ + " vol=" + info.mVolume)).printLog(TAG));
+ synchronized (mDeviceStateLock) {
+ mDeviceInventory.handleBluetoothA2dpActiveDeviceChangeExt(
+ info.mDevice, info.mState, info.mProfile,
+ info.mSupprNoisy, info.mVolume);
+ }
+ } break;
default:
Log.wtf(TAG, "Invalid message " + msg.what);
}
@@ -1163,6 +1188,9 @@
// process external command to (dis)connect a hearing aid device
private static final int MSG_L_HEARING_AID_DEVICE_CONNECTION_CHANGE_EXT = 31;
+ // process external command to (dis)connect or change active A2DP device
+ private static final int MSG_L_A2DP_ACTIVE_DEVICE_CHANGE_EXT = 38;
+
// a ScoClient died in BtHelper
private static final int MSG_L_SCOCLIENT_DIED = 32;
private static final int MSG_IL_SAVE_PREF_DEVICE_FOR_STRATEGY = 33;
@@ -1172,7 +1200,6 @@
private static final int MSG_CHECK_MUTE_MUSIC = 36;
private static final int MSG_REPORT_NEW_ROUTES_A2DP = 37;
-
private static boolean isMessageHandledUnderWakelock(int msgId) {
switch(msgId) {
case MSG_L_SET_WIRED_DEVICE_CONNECTION_STATE:
@@ -1188,6 +1215,7 @@
case MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT_DISCONNECTION:
case MSG_L_HEARING_AID_DEVICE_CONNECTION_CHANGE_EXT:
case MSG_CHECK_MUTE_MUSIC:
+ case MSG_L_A2DP_ACTIVE_DEVICE_CHANGE_EXT:
return true;
default:
return false;
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index 02a846e..b576524 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -51,6 +51,7 @@
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashMap;
+import java.util.Map;
import java.util.Set;
/**
@@ -458,6 +459,7 @@
if (event == BtHelper.EVENT_ACTIVE_DEVICE_CHANGE) {
// Device is connected
+ mApmConnectedDevices.replace(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, key);
if (a2dpVolume != -1) {
mDeviceBroker.postSetVolumeIndexOnDevice(AudioSystem.STREAM_MUSIC,
// convert index to internal representation in VolumeStreamState
@@ -815,7 +817,20 @@
delay = 0;
}
- final int a2dpCodec = mDeviceBroker.getA2dpCodec(device);
+ final int a2dpCodec;
+ if (state == BluetoothA2dp.STATE_DISCONNECTED) {
+ final String key = DeviceInfo.makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
+ device.getAddress());
+ final DeviceInfo di = mConnectedDevices.get(key);
+ if (di != null) {
+ a2dpCodec = di.mDeviceCodecFormat;
+ } else {
+ Log.e(TAG, "invalid null DeviceInfo in setBluetoothA2dpDeviceConnectionState");
+ return;
+ }
+ } else {
+ a2dpCodec = mDeviceBroker.getA2dpCodec(device);
+ }
if (AudioService.DEBUG_DEVICES) {
Log.i(TAG, "setBluetoothA2dpDeviceConnectionState device: " + device
@@ -838,6 +853,55 @@
}
}
+ /*package*/ void handleBluetoothA2dpActiveDeviceChangeExt(
+ @NonNull BluetoothDevice device,
+ @AudioService.BtProfileConnectionState int state, int profile,
+ boolean suppressNoisyIntent, int a2dpVolume) {
+ if (state == BluetoothProfile.STATE_DISCONNECTED) {
+ mDeviceBroker.postBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(
+ device, state, profile, suppressNoisyIntent, a2dpVolume);
+ BtHelper.SetA2dpActiveDevice(null);
+ return;
+ }
+ // state == BluetoothProfile.STATE_CONNECTED
+ synchronized (mConnectedDevices) {
+ final String address = device.getAddress();
+ final int a2dpCodec = mDeviceBroker.getA2dpCodec(device);
+ final String deviceKey = DeviceInfo.makeDeviceListKey(
+ AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address);
+ DeviceInfo deviceInfo = mConnectedDevices.get(deviceKey);
+ if (deviceInfo != null) {
+ // Device config change for matching A2DP device
+ mDeviceBroker.postBluetoothA2dpDeviceConfigChange(device);
+ return;
+ }
+ for (Map.Entry<String, DeviceInfo> existingDevice : mConnectedDevices.entrySet()) {
+ if (existingDevice.getValue().mDeviceType != AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) {
+ continue;
+ }
+ // A2DP device exists, handle active device change
+ mConnectedDevices.remove(existingDevice.getKey());
+ mConnectedDevices.put(deviceKey, new DeviceInfo(
+ AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, BtHelper.getName(device),
+ address, a2dpCodec));
+ if (BtHelper.isTwsPlusSwitch(device, existingDevice.getValue().mDeviceAddress)) {
+ BtHelper.SetA2dpActiveDevice(device);
+ if (AudioService.DEBUG_DEVICES) {
+ Log.d(TAG,"TWS+ device switch");
+ }
+ return;
+ }
+ mDeviceBroker.postA2dpActiveDeviceChange(
+ new BtHelper.BluetoothA2dpDeviceInfo(
+ device, a2dpVolume, a2dpCodec));
+ return;
+ }
+ }
+ // New A2DP device connection
+ mDeviceBroker.postBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(
+ device, state, profile, suppressNoisyIntent, a2dpVolume);
+ }
+
/*package*/ int setWiredDeviceConnectionState(int type, @AudioService.ConnectionState int state,
String address, String name, String caller) {
synchronized (mDevicesLock) {
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index fb9cf0d..92387a5 100755
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -23,6 +23,7 @@
import static android.media.AudioManager.STREAM_SYSTEM;
import static android.os.Process.FIRST_APPLICATION_UID;
import static android.provider.Settings.Secure.VOLUME_HUSH_MUTE;
+import static android.provider.Settings.Secure.VOLUME_HUSH_MUTE_NO_MEDIA;
import static android.provider.Settings.Secure.VOLUME_HUSH_OFF;
import static android.provider.Settings.Secure.VOLUME_HUSH_VIBRATE;
@@ -141,6 +142,7 @@
import android.view.accessibility.AccessibilityManager;
import android.widget.Toast;
+import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.DumpUtils;
@@ -610,6 +612,9 @@
private @AttributeSystemUsage int[] mSupportedSystemUsages =
new int[]{AudioAttributes.USAGE_CALL_ASSISTANT};
+ // Alert Slider
+ private boolean mHasAlertSlider = false;
+
// Defines the format for the connection "address" for ALSA devices
public static String makeAlsaAddressString(int card, int device) {
return "card=" + card + ";device=" + device + ";";
@@ -701,6 +706,10 @@
mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
mHasVibrator = mVibrator == null ? false : mVibrator.hasVibrator();
+ mHasAlertSlider = mContext.getResources().getBoolean(R.bool.config_hasAlertSlider)
+ && !TextUtils.isEmpty(mContext.getResources().getString(R.string.alert_slider_state_path))
+ && !TextUtils.isEmpty(mContext.getResources().getString(R.string.alert_slider_uevent_match_path));
+
// Initialize volume
// Priority 1 - Android Property
// Priority 2 - Audio Policy Service
@@ -2046,6 +2055,27 @@
}
}
+ if (mHasAlertSlider) {
+ int volumeType = mStreamVolumeAlias[streamType];
+ VolumeStreamState volumeState = mStreamStates[volumeType];
+ int state = getDeviceForStream(volumeType);
+ int index = volumeState.getIndex(state);
+ int ringerMode = getRingerModeInternal();
+ if ((volumeType == AudioSystem.STREAM_RING)
+ && (direction == AudioManager.ADJUST_LOWER)
+ && (index == 0)) {
+ direction = AudioManager.ADJUST_SAME;
+ }
+ if ((ringerMode == AudioManager.RINGER_MODE_SILENT)
+ && (direction == AudioManager.ADJUST_RAISE
+ && volumeType != AudioSystem.STREAM_MUSIC
+ && volumeType != AudioSystem.STREAM_ALARM
+ && volumeType != AudioSystem.STREAM_VOICE_CALL
+ && !isInCommunication())) {
+ direction = AudioManager.ADJUST_SAME;
+ }
+ }
+
final boolean isMute = isMuteAdjust(direction);
ensureValidStreamType(streamType);
@@ -3491,6 +3521,12 @@
ringerMode = AudioManager.RINGER_MODE_SILENT;
toastText = com.android.internal.R.string.volume_dialog_ringer_guidance_silent;
break;
+ case VOLUME_HUSH_MUTE_NO_MEDIA:
+ effect = VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK);
+ ringerMode = AudioManager.RINGER_MODE_SILENT;
+ mStreamStates[AudioSystem.STREAM_MUSIC].mute(true);
+ toastText = com.android.internal.R.string.volume_dialog_ringer_guidance_silent_no_media;
+ break;
case VOLUME_HUSH_VIBRATE:
effect = VibrationEffect.get(VibrationEffect.EFFECT_HEAVY_CLICK);
ringerMode = AudioManager.RINGER_MODE_VIBRATE;
@@ -5211,6 +5247,27 @@
mDeviceBroker.postBluetoothA2dpDeviceConfigChange(device);
}
+ /**
+ * @see AudioManager#handleBluetoothA2dpActiveDeviceChange(BluetoothDevice, int, int,
+ * boolean, int)
+ */
+ public void handleBluetoothA2dpActiveDeviceChange(
+ BluetoothDevice device, int state, int profile, boolean suppressNoisyIntent,
+ int a2dpVolume) {
+ if (device == null) {
+ throw new IllegalArgumentException("Illegal null device");
+ }
+ if (profile != BluetoothProfile.A2DP && profile != BluetoothProfile.A2DP_SINK) {
+ throw new IllegalArgumentException("invalid profile " + profile);
+ }
+ if (state != BluetoothProfile.STATE_CONNECTED
+ && state != BluetoothProfile.STATE_DISCONNECTED) {
+ throw new IllegalArgumentException("Invalid state " + state);
+ }
+ mDeviceBroker.postBluetoothA2dpDeviceConfigChangeExt(device, state, profile,
+ suppressNoisyIntent, a2dpVolume);
+ }
+
private static final Set<Integer> DEVICE_MEDIA_UNMUTED_ON_PLUG_SET;
static {
DEVICE_MEDIA_UNMUTED_ON_PLUG_SET = new HashSet<>();
@@ -6735,8 +6792,7 @@
UserManager.DISALLOW_RECORD_AUDIO, false, userId);
} else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
- if (state == BluetoothAdapter.STATE_OFF ||
- state == BluetoothAdapter.STATE_TURNING_OFF) {
+ if (state == BluetoothAdapter.STATE_OFF) {
mDeviceBroker.disconnectAllBluetoothProfiles();
}
} else if (action.equals(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION) ||
diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java
index 7616557..9970477 100644
--- a/services/core/java/com/android/server/audio/BtHelper.java
+++ b/services/core/java/com/android/server/audio/BtHelper.java
@@ -71,7 +71,8 @@
private @Nullable BluetoothHearingAid mHearingAid;
// Reference to BluetoothA2dp to query for AbsoluteVolume.
- private @Nullable BluetoothA2dp mA2dp;
+ static private @Nullable BluetoothA2dp mA2dp;
+ static private @Nullable BluetoothDevice mBluetoothA2dpActiveDevice;
// If absolute volume is supported in AVRCP device
private boolean mAvrcpAbsVolSupported = false;
@@ -219,6 +220,31 @@
return deviceName;
}
+ /*packages*/ static void SetA2dpActiveDevice(BluetoothDevice device) {
+ Log.w(TAG,"SetA2dpActiveDevice for TWS+ pair as " + device);
+ mBluetoothA2dpActiveDevice = device;
+ }
+
+ /*packages*/ @NonNull static boolean isTwsPlusSwitch(@NonNull BluetoothDevice device,
+ String address) {
+ BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+ BluetoothDevice connDevice = adapter.getRemoteDevice(address);
+ if (device == null || connDevice == null ||
+ device.getTwsPlusPeerAddress() == null) {
+ return false;
+ }
+ if (device.isTwsPlusDevice() &&
+ connDevice.isTwsPlusDevice() &&
+ device.getTwsPlusPeerAddress().equals(address)) {
+ if (mBluetoothA2dpActiveDevice == null) {
+ Log.w(TAG,"Not a TwsPlusSwitch as previous active device was null");
+ return false;
+ }
+ Log.i(TAG,"isTwsPlusSwitch true");
+ return true;
+ }
+ return false;
+ }
//----------------------------------------------------------------------
// Interface for AudioDeviceBroker
diff --git a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
index 20c004d..02e63e4 100644
--- a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
+++ b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
@@ -78,7 +78,6 @@
protected static final boolean DEBUG = true;
- private static final boolean CLEANUP_UNKNOWN_TEMPLATES = true;
private static final String KEY_LOCKOUT_RESET_USER = "lockout_reset_user";
private static final int MSG_USER_SWITCHING = 10;
private static final long CANCEL_TIMEOUT_LIMIT = 3000; // max wait for onCancel() from HAL,in ms
@@ -89,9 +88,12 @@
private final PowerManager mPowerManager;
private final UserManager mUserManager;
private final MetricsLogger mMetricsLogger;
+ private final boolean mPostResetRunnableForAllClients;
private final BiometricTaskStackListener mTaskStackListener = new BiometricTaskStackListener();
private final ResetClientStateRunnable mResetClientState = new ResetClientStateRunnable();
private final ArrayList<LockoutResetMonitor> mLockoutMonitors = new ArrayList<>();
+ private final boolean mNotifyClient;
+ private final boolean mCleanupUnusedFingerprints;
protected final IStatusBarService mStatusBarService;
protected final Map<Integer, Long> mAuthenticatorIds =
@@ -284,10 +286,12 @@
@Override
public int handleFailedAttempt() {
final int lockoutMode = getLockoutMode();
- if (lockoutMode == AuthenticationClient.LOCKOUT_PERMANENT) {
- mPerformanceStats.permanentLockout++;
- } else if (lockoutMode == AuthenticationClient.LOCKOUT_TIMED) {
- mPerformanceStats.lockout++;
+ if (mPerformanceStats != null) {
+ if (lockoutMode == AuthenticationClient.LOCKOUT_PERMANENT) {
+ mPerformanceStats.permanentLockout++;
+ } else if (lockoutMode == AuthenticationClient.LOCKOUT_TIMED) {
+ mPerformanceStats.lockout++;
+ }
}
// Failing multiple times will continue to push out the lockout time
@@ -660,6 +664,12 @@
mPowerManager = mContext.getSystemService(PowerManager.class);
mUserManager = UserManager.get(mContext);
mMetricsLogger = new MetricsLogger();
+ mNotifyClient = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_notifyClientOnFingerprintCancelSuccess);
+ mCleanupUnusedFingerprints = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_cleanupUnusedFingerprints);
+ mPostResetRunnableForAllClients = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_fingerprintPostResetRunnableForAllClients);
}
@Override
@@ -729,10 +739,12 @@
if (client != null && client.onAuthenticated(identifier, authenticated, token)) {
removeClient(client);
}
- if (authenticated) {
- mPerformanceStats.accept++;
- } else {
- mPerformanceStats.reject++;
+ if (mPerformanceStats != null) {
+ if (authenticated) {
+ mPerformanceStats.accept++;
+ } else {
+ mPerformanceStats.reject++;
+ }
}
}
@@ -854,7 +866,11 @@
ClientMonitor client = mCurrentClient;
if (client instanceof EnrollClient && client.getToken() == token) {
if (DEBUG) Slog.v(getTag(), "Cancelling enrollment");
- client.stop(client.getToken() == token);
+ final int stopResult = client.stop(client.getToken() == token);
+ if (mNotifyClient && (stopResult == 0)) {
+ handleError(mHalDeviceId,
+ BiometricConstants.BIOMETRIC_ERROR_CANCELED, 0);
+ }
}
});
}
@@ -925,7 +941,11 @@
+ ", fromClient: " + fromClient);
// If cancel was from BiometricService, it means the dialog was dismissed
// and authentication should be canceled.
- client.stop(client.getToken() == token);
+ final int stopResult = client.stop(client.getToken() == token);
+ if (mNotifyClient && (stopResult == 0)) {
+ handleError(mHalDeviceId,
+ BiometricConstants.BIOMETRIC_ERROR_CANCELED, 0);
+ }
} else {
if (DEBUG) Slog.v(getTag(), "Can't stop client " + client.getOwnerString()
+ " since tokens don't match. fromClient: " + fromClient);
@@ -1037,7 +1057,7 @@
/**
* @return true if this is keyguard package
*/
- private boolean isKeyguard(String clientPackage) {
+ protected boolean isKeyguard(String clientPackage) {
return mKeyguardPackage.equals(clientPackage);
}
@@ -1068,6 +1088,10 @@
+ "(" + newClient.getOwnerString() + ")"
+ ", initiatedByClient = " + initiatedByClient);
}
+ if (mPostResetRunnableForAllClients) {
+ mHandler.removeCallbacks(mResetClientState);
+ mHandler.postDelayed(mResetClientState, CANCEL_TIMEOUT_LIMIT);
+ }
} else {
currentClient.stop(initiatedByClient);
@@ -1236,7 +1260,7 @@
* @param userId
*/
protected void doTemplateCleanupForUser(int userId) {
- if (CLEANUP_UNKNOWN_TEMPLATES) {
+ if (mCleanupUnusedFingerprints) {
enumerateUser(userId);
}
}
diff --git a/services/core/java/com/android/server/biometrics/ClientMonitor.java b/services/core/java/com/android/server/biometrics/ClientMonitor.java
index b029695..2f613c4 100644
--- a/services/core/java/com/android/server/biometrics/ClientMonitor.java
+++ b/services/core/java/com/android/server/biometrics/ClientMonitor.java
@@ -22,8 +22,10 @@
import android.media.AudioAttributes;
import android.os.IBinder;
import android.os.RemoteException;
+import android.os.UserHandle;
import android.os.VibrationEffect;
import android.os.Vibrator;
+import android.provider.Settings;
import android.util.Slog;
import com.android.internal.logging.MetricsLogger;
@@ -297,7 +299,9 @@
public final void vibrateSuccess() {
Vibrator vibrator = mContext.getSystemService(Vibrator.class);
- if (vibrator != null) {
+ boolean FingerprintVib = Settings.System.getIntForUser(mContext.getContentResolver(),
+ Settings.System.FP_SUCCESS_VIBRATE, 1, UserHandle.USER_CURRENT) == 1;
+ if (vibrator != null && FingerprintVib) {
vibrator.vibrate(mSuccessVibrationEffect, FINGERPRINT_SONFICATION_ATTRIBUTES);
}
}
diff --git a/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java
index a90fee6..82f5eab 100644
--- a/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java
@@ -80,12 +80,15 @@
import org.json.JSONException;
import org.json.JSONObject;
+import vendor.lineage.biometrics.fingerprint.inscreen.V1_0.IFingerprintInscreen;
+
import java.io.File;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.NoSuchElementException;
import java.util.concurrent.CopyOnWriteArrayList;
/**
@@ -102,11 +105,14 @@
private static final String FP_DATA_DIR = "fpdata";
private static final String ACTION_LOCKOUT_RESET =
"com.android.server.biometrics.fingerprint.ACTION_LOCKOUT_RESET";
- private static final int MAX_FAILED_ATTEMPTS_LOCKOUT_TIMED = 5;
+ private static final int MAX_FAILED_ATTEMPTS_LOCKOUT_TIMED = 10;
private static final int MAX_FAILED_ATTEMPTS_LOCKOUT_PERMANENT = 20;
private static final long FAIL_LOCKOUT_TIMEOUT_MS = 30 * 1000;
private static final String KEY_LOCKOUT_RESET_USER = "lockout_reset_user";
+ private final boolean mHasFod;
+ private boolean mIsKeyguard;
+
private final class ResetFailedAttemptsForUserRunnable implements Runnable {
@Override
public void run() {
@@ -641,6 +647,7 @@
@GuardedBy("this")
private IBiometricsFingerprint mDaemon;
+ private IFingerprintInscreen mFingerprintInscreenDaemon;
private final SparseBooleanArray mTimedLockoutCleared;
private final SparseIntArray mFailedAttempts;
private final AlarmManager mAlarmManager;
@@ -662,6 +669,21 @@
new Fingerprint(getBiometricUtils().getUniqueName(getContext(), groupId),
groupId, fingerId, deviceId);
FingerprintService.super.handleEnrollResult(fingerprint, remaining);
+ if (remaining == 0 && mHasFod) {
+ IFingerprintInscreen fodDaemon = getFingerprintInScreenDaemon();
+ if (fodDaemon != null) {
+ try {
+ fodDaemon.onFinishEnroll();
+ } catch (RemoteException e) {
+ Slog.e(TAG, "onFinishEnroll failed", e);
+ }
+ }
+ try {
+ mStatusBarService.hideInDisplayFingerprintView();
+ } catch (RemoteException e) {
+ Slog.e(TAG, "hideInDisplayFingerprintView failed", e);
+ }
+ }
});
}
@@ -673,6 +695,16 @@
@Override
public void onAcquired_2_2(long deviceId, int acquiredInfo, int vendorCode) {
mHandler.post(() -> {
+ IFingerprintInscreen daemon = getFingerprintInScreenDaemon();
+ if (daemon != null) {
+ try {
+ if (daemon.handleAcquired(acquiredInfo, vendorCode)) {
+ return;
+ }
+ } catch (RemoteException e) {
+ Slog.e(TAG, "handleError failed", e);
+ }
+ }
FingerprintService.super.handleAcquired(deviceId, acquiredInfo, vendorCode);
});
}
@@ -692,12 +724,29 @@
final Fingerprint fp = new Fingerprint("", groupId, fingerId, deviceId);
FingerprintService.super.handleAuthenticated(authenticated, fp, token);
+ if (mHasFod && fp.getBiometricId() != 0) {
+ try {
+ mStatusBarService.hideInDisplayFingerprintView();
+ } catch (RemoteException e) {
+ Slog.e(TAG, "hideInDisplayFingerprintView failed", e);
+ }
+ }
});
}
@Override
public void onError(final long deviceId, final int error, final int vendorCode) {
mHandler.post(() -> {
+ IFingerprintInscreen daemon = getFingerprintInScreenDaemon();
+ if (daemon != null) {
+ try {
+ if (daemon.handleError(error, vendorCode)) {
+ return;
+ }
+ } catch (RemoteException e) {
+ Slog.e(TAG, "handleError failed", e);
+ }
+ }
FingerprintService.super.handleError(deviceId, error, vendorCode);
// TODO: this chunk of code should be common to all biometric services
if (error == BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE) {
@@ -745,6 +794,21 @@
Slog.w(TAG, "authenticate(): no fingerprint HAL!");
return ERROR_ESRCH;
}
+ if (mHasFod) {
+ IFingerprintInscreen fodDaemon = getFingerprintInScreenDaemon();
+ if (fodDaemon != null) {
+ try {
+ fodDaemon.setLongPressEnabled(mIsKeyguard);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "setLongPressEnabled failed", e);
+ }
+ }
+ try {
+ mStatusBarService.showInDisplayFingerprintView();
+ } catch (RemoteException e) {
+ Slog.e(TAG, "showInDisplayFingerprintView failed", e);
+ }
+ }
return daemon.authenticate(operationId, groupId);
}
@@ -755,6 +819,13 @@
Slog.w(TAG, "cancel(): no fingerprint HAL!");
return ERROR_ESRCH;
}
+ if (mHasFod) {
+ try {
+ mStatusBarService.hideInDisplayFingerprintView();
+ } catch (RemoteException e) {
+ Slog.e(TAG, "hideInDisplayFingerprintView failed", e);
+ }
+ }
return daemon.cancel();
}
@@ -786,6 +857,21 @@
Slog.w(TAG, "enroll(): no fingerprint HAL!");
return ERROR_ESRCH;
}
+ if (mHasFod) {
+ IFingerprintInscreen fodDaemon = getFingerprintInScreenDaemon();
+ if (fodDaemon != null) {
+ try {
+ fodDaemon.onStartEnroll();
+ } catch (RemoteException e) {
+ Slog.e(TAG, "onStartEnroll failed", e);
+ }
+ }
+ try {
+ mStatusBarService.showInDisplayFingerprintView();
+ } catch (RemoteException e) {
+ Slog.e(TAG, "showInDisplayFingerprintView failed", e);
+ }
+ }
return daemon.enroll(cryptoToken, groupId, timeout);
}
@@ -805,6 +891,10 @@
context.registerReceiver(mLockoutReceiver, new IntentFilter(getLockoutResetIntent()),
getLockoutBroadcastPermission(), null /* handler */);
mLockPatternUtils = new LockPatternUtils(context);
+
+ PackageManager packageManager = context.getPackageManager();
+ mHasFod = context.getResources().getBoolean(
+ com.android.internal.R.bool.config_needCustomFODView);
}
@Override
@@ -889,6 +979,7 @@
daemon.setActiveGroup(userId, fpDir.getAbsolutePath());
mCurrentUserId = userId;
+ mIsKeyguard = isKeyguard(clientPackage);
}
mAuthenticatorIds.put(userId,
hasEnrolledBiometrics(userId) ? daemon.getAuthenticatorId() : 0L);
@@ -1026,6 +1117,26 @@
return mDaemon;
}
+ private synchronized IFingerprintInscreen getFingerprintInScreenDaemon() {
+ if (!mHasFod) {
+ return null;
+ }
+
+ if (mFingerprintInscreenDaemon == null) {
+ try {
+ mFingerprintInscreenDaemon = IFingerprintInscreen.getService();
+ if (mFingerprintInscreenDaemon != null) {
+ mFingerprintInscreenDaemon.asBinder().linkToDeath((cookie) -> {
+ mFingerprintInscreenDaemon = null;
+ }, 0);
+ }
+ } catch (NoSuchElementException | RemoteException e) {
+ Slog.e(TAG, "Failed to get IFingerprintInscreen interface", e);
+ }
+ }
+ return mFingerprintInscreenDaemon;
+ }
+
private long startPreEnroll(IBinder token) {
IBiometricsFingerprint daemon = getFingerprintDaemon();
if (daemon == null) {
diff --git a/services/core/java/com/android/server/camera/CameraServiceProxy.java b/services/core/java/com/android/server/camera/CameraServiceProxy.java
index 61c99b8..68be460 100644
--- a/services/core/java/com/android/server/camera/CameraServiceProxy.java
+++ b/services/core/java/com/android/server/camera/CameraServiceProxy.java
@@ -107,6 +107,7 @@
private ScheduledThreadPoolExecutor mLogWriterService = new ScheduledThreadPoolExecutor(
/*corePoolSize*/ 1);
+ private final boolean mAllowMediaUid;
/**
* Structure to track camera usage
@@ -176,7 +177,8 @@
private final ICameraServiceProxy.Stub mCameraServiceProxy = new ICameraServiceProxy.Stub() {
@Override
public void pingForUserUpdate() {
- if (Binder.getCallingUid() != Process.CAMERASERVER_UID) {
+ if (Binder.getCallingUid() != Process.CAMERASERVER_UID
+ && (!mAllowMediaUid || Binder.getCallingUid() != Process.MEDIA_UID)) {
Slog.e(TAG, "Calling UID: " + Binder.getCallingUid() + " doesn't match expected " +
" camera service UID!");
return;
@@ -187,7 +189,8 @@
@Override
public void notifyCameraState(String cameraId, int newCameraState, int facing,
String clientName, int apiLevel) {
- if (Binder.getCallingUid() != Process.CAMERASERVER_UID) {
+ if (Binder.getCallingUid() != Process.CAMERASERVER_UID
+ && (!mAllowMediaUid || Binder.getCallingUid() != Process.MEDIA_UID)) {
Slog.e(TAG, "Calling UID: " + Binder.getCallingUid() + " doesn't match expected " +
" camera service UID!");
return;
@@ -213,6 +216,8 @@
// Don't keep any extra logging threads if not needed
mLogWriterService.setKeepAliveTime(1, TimeUnit.SECONDS);
mLogWriterService.allowCoreThreadTimeOut(true);
+ mAllowMediaUid = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_allowMediaUidForCameraServiceProxy);
}
@Override
diff --git a/services/core/java/com/android/server/connectivity/NetworkDiagnostics.java b/services/core/java/com/android/server/connectivity/NetworkDiagnostics.java
index 49c16ad..a25fd65 100644
--- a/services/core/java/com/android/server/connectivity/NetworkDiagnostics.java
+++ b/services/core/java/com/android/server/connectivity/NetworkDiagnostics.java
@@ -97,9 +97,9 @@
public class NetworkDiagnostics {
private static final String TAG = "NetworkDiagnostics";
- private static final InetAddress TEST_DNS4 = NetworkUtils.numericToInetAddress("8.8.8.8");
+ private static final InetAddress TEST_DNS4 = NetworkUtils.numericToInetAddress("1.0.0.1");
private static final InetAddress TEST_DNS6 = NetworkUtils.numericToInetAddress(
- "2001:4860:4860::8888");
+ "2606:4700:4700::1001");
// For brevity elsewhere.
private static final long now() {
diff --git a/services/core/java/com/android/server/display/ExtendedRemoteDisplayHelper.java b/services/core/java/com/android/server/display/ExtendedRemoteDisplayHelper.java
new file mode 100644
index 0000000..d6306a3
--- /dev/null
+++ b/services/core/java/com/android/server/display/ExtendedRemoteDisplayHelper.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.android.server.display;
+
+import android.content.Context;
+import android.media.RemoteDisplay;
+import android.os.Handler;
+import android.util.Slog;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+class ExtendedRemoteDisplayHelper {
+ private static final String TAG = "ExtendedRemoteDisplayHelper";
+ private static final boolean DEBUG = false;
+
+ // ExtendedRemoteDisplay class
+ // ExtendedRemoteDisplay is an enhanced RemoteDisplay.
+ // It has similar interface as RemoteDisplay class.
+ private static Class sExtRemoteDisplayClass;
+
+ // Method object for the API ExtendedRemoteDisplay.Listen
+ // ExtendedRemoteDisplay.Listen has the same API signature as RemoteDisplay.Listen
+ // except for an additional argument to pass the Context.
+ private static Method sExtRemoteDisplayListen;
+
+ // Method Object for the API ExtendedRemoteDisplay.Dispose
+ // ExtendedRemoteDisplay.Dispose follows the same API signature as RemoteDisplay.Dispose.
+ private static Method sExtRemoteDisplayDispose;
+
+ static {
+ // Check availability of ExtendedRemoteDisplay runtime
+ try {
+ sExtRemoteDisplayClass = Class.forName("com.qualcomm.wfd.ExtendedRemoteDisplay");
+ } catch (Throwable t) {
+ Slog.i(TAG, "ExtendedRemoteDisplay: not available");
+ }
+
+ if (sExtRemoteDisplayClass != null) {
+ // If ExtendedRemoteDisplay is available find the methods
+ Slog.i(TAG, "ExtendedRemoteDisplay: is available, finding methods");
+ try {
+ Class args[] = { String.class, RemoteDisplay.Listener.class,
+ Handler.class, Context.class };
+ sExtRemoteDisplayListen =
+ sExtRemoteDisplayClass.getDeclaredMethod("listen", args);
+ } catch (Throwable t) {
+ Slog.i(TAG, "ExtendedRemoteDisplay.listen: not available");
+ }
+
+ try {
+ Class args[] = {};
+ sExtRemoteDisplayDispose =
+ sExtRemoteDisplayClass.getDeclaredMethod("dispose", args);
+ } catch (Throwable t) {
+ Slog.i(TAG, "ExtendedRemoteDisplay.dispose: not available");
+ }
+ }
+ }
+
+ /**
+ * Starts listening for displays to be connected on the specified interface.
+ *
+ * @param iface The interface address and port in the form "x.x.x.x:y".
+ * @param listener The listener to invoke when displays are connected or disconnected.
+ * @param handler The handler on which to invoke the listener.
+ * @param context The current service context.
+ * */
+ public static Object listen(String iface, RemoteDisplay.Listener listener,
+ Handler handler, Context context) {
+ Object extRemoteDisplay = null;
+ if (DEBUG) Slog.i(TAG, "ExtendedRemoteDisplay.listen");
+
+ if (sExtRemoteDisplayListen != null && sExtRemoteDisplayDispose != null) {
+ try {
+ extRemoteDisplay = sExtRemoteDisplayListen.invoke(null,
+ iface, listener, handler, context);
+ } catch (InvocationTargetException e) {
+ Slog.e(TAG, "ExtendedRemoteDisplay.listen: InvocationTargetException");
+ Throwable cause = e.getCause();
+ if (cause instanceof RuntimeException) {
+ throw (RuntimeException) cause;
+ } else if (cause instanceof Error) {
+ throw (Error) cause;
+ } else {
+ throw new RuntimeException(e);
+ }
+ } catch (IllegalAccessException e) {
+ Slog.e(TAG, "ExtendedRemoteDisplay.listen: IllegalAccessException", e);
+ }
+ }
+ return extRemoteDisplay;
+ }
+
+ /**
+ * Disconnects the remote display and stops listening for new connections.
+ */
+ public static void dispose(Object extRemoteDisplay) {
+ if (DEBUG) Slog.i(TAG, "ExtendedRemoteDisplay.dispose");
+ try {
+ sExtRemoteDisplayDispose.invoke(extRemoteDisplay);
+ } catch (InvocationTargetException e) {
+ Slog.e(TAG, "ExtendedRemoteDisplay.dispose: InvocationTargetException");
+ Throwable cause = e.getCause();
+ if (cause instanceof RuntimeException) {
+ throw (RuntimeException) cause;
+ } else if (cause instanceof Error) {
+ throw (Error) cause;
+ } else {
+ throw new RuntimeException(e);
+ }
+ } catch (IllegalAccessException e) {
+ Slog.e(TAG, "ExtendedRemoteDisplay.dispose: IllegalAccessException", e);
+ }
+ }
+
+ /**
+ * Checks if ExtendedRemoteDisplay is available
+ */
+ public static boolean isAvailable() {
+ return (sExtRemoteDisplayClass != null && sExtRemoteDisplayDispose != null &&
+ sExtRemoteDisplayListen != null);
+ }
+}
diff --git a/services/core/java/com/android/server/display/RampAnimator.java b/services/core/java/com/android/server/display/RampAnimator.java
index 7916d81..3247b83 100644
--- a/services/core/java/com/android/server/display/RampAnimator.java
+++ b/services/core/java/com/android/server/display/RampAnimator.java
@@ -62,7 +62,7 @@
public boolean animateTo(float target, float rate) {
// Immediately jump to the target the first time.
- if (mFirstTime || rate <= 0) {
+ if (mFirstTime || rate <= 0 || mCurrentValue == 0) {
if (mFirstTime || target != mCurrentValue) {
mFirstTime = false;
mRate = 0;
diff --git a/services/core/java/com/android/server/display/WifiDisplayController.java b/services/core/java/com/android/server/display/WifiDisplayController.java
index a7e1a28..1b381af 100644
--- a/services/core/java/com/android/server/display/WifiDisplayController.java
+++ b/services/core/java/com/android/server/display/WifiDisplayController.java
@@ -136,6 +136,10 @@
// Number of connection retries remaining.
private int mConnectionRetriesLeft;
+ // The Extended remote display that is listening on the connection.
+ // Created after the Wifi P2P network is connected.
+ private Object mExtRemoteDisplay;
+
// The remote display that is listening on the connection.
// Created after the Wifi P2P network is connected.
private RemoteDisplay mRemoteDisplay;
@@ -367,7 +371,8 @@
}
private void updateScanState() {
- if (mScanRequested && mWfdEnabled && mDesiredDevice == null) {
+ if (mScanRequested && mWfdEnabled && mDesiredDevice == null &&
+ mConnectedDevice == null && mDisconnectingDevice == null) {
if (!mDiscoverPeersInProgress) {
Slog.i(TAG, "Starting Wifi display scan.");
mDiscoverPeersInProgress = true;
@@ -543,6 +548,10 @@
return;
}
+ if (handlePreExistingConnection(device)) {
+ Slog.i(TAG, "Already handle the preexisting P2P connection status");
+ return;
+ }
mDesiredDevice = device;
mConnectionRetriesLeft = CONNECT_MAX_RETRIES;
updateConnection();
@@ -573,14 +582,21 @@
// Step 1. Before we try to connect to a new device, tell the system we
// have disconnected from the old one.
- if (mRemoteDisplay != null && mConnectedDevice != mDesiredDevice) {
- Slog.i(TAG, "Stopped listening for RTSP connection on " + mRemoteDisplayInterface
- + " from Wifi display: " + mConnectedDevice.deviceName);
+ if ((mRemoteDisplay != null || mExtRemoteDisplay != null) &&
+ mConnectedDevice != mDesiredDevice ||
+ (mRemoteDisplayInterface != null && mConnectedDevice == null)) {
+ Slog.i(TAG, "Stopped listening for RTSP connection on "
+ + mRemoteDisplayInterface);
- mRemoteDisplay.dispose();
+ if (mRemoteDisplay != null) {
+ mRemoteDisplay.dispose();
+ } else if (mExtRemoteDisplay != null) {
+ ExtendedRemoteDisplayHelper.dispose(mExtRemoteDisplay);
+ }
+
+ mExtRemoteDisplay = null;
mRemoteDisplay = null;
mRemoteDisplayInterface = null;
- mRemoteDisplayConnected = false;
mHandler.removeCallbacks(mRtspTimeout);
mWifiP2pManager.setMiracastMode(WifiP2pManager.MIRACAST_DISABLED);
@@ -590,7 +606,7 @@
}
// Step 2. Before we try to connect to a new device, disconnect from the old one.
- if (mDisconnectingDevice != null) {
+ if (mRemoteDisplayConnected || mDisconnectingDevice != null) {
return; // wait for asynchronous callback
}
if (mConnectedDevice != null && mConnectedDevice != mDesiredDevice) {
@@ -674,6 +690,51 @@
return; // done
}
+ //Before we connect, we need to set the oldDevice to the desiredDevice to check
+ //the device on receiving callbacks from the Remote display modules
+ final WifiP2pDevice oldDevice = mDesiredDevice;
+ RemoteDisplay.Listener listener = new RemoteDisplay.Listener() {
+ @Override
+ public void onDisplayConnected(Surface surface,
+ int width, int height, int flags, int session) {
+ if (mConnectedDevice == oldDevice && !mRemoteDisplayConnected) {
+ Slog.i(TAG, "Opened RTSP connection with Wifi display: "
+ + mConnectedDevice.deviceName);
+ mRemoteDisplayConnected = true;
+ mHandler.removeCallbacks(mRtspTimeout);
+
+ if (mWifiDisplayCertMode) {
+ mListener.onDisplaySessionInfo(
+ getSessionInfo(mConnectedDeviceGroupInfo, session));
+ }
+
+ final WifiDisplay display = createWifiDisplay(mConnectedDevice);
+ advertiseDisplay(display, surface, width, height, flags);
+ }
+ }
+
+ @Override
+ public void onDisplayDisconnected() {
+ if (mConnectedDevice == oldDevice) {
+ Slog.i(TAG, "Closed RTSP connection with Wifi display: "
+ + mConnectedDevice.deviceName);
+ mHandler.removeCallbacks(mRtspTimeout);
+ mRemoteDisplayConnected = false;
+ disconnect();
+ }
+ }
+
+ @Override
+ public void onDisplayError(int error) {
+ if (mConnectedDevice == oldDevice) {
+ Slog.i(TAG, "Lost RTSP connection with Wifi display due to error "
+ + error + ": " + mConnectedDevice.deviceName);
+ mHandler.removeCallbacks(mRtspTimeout);
+ handleConnectionFailure(false);
+ }
+ }
+ };
+
// Step 5. Try to connect.
if (mConnectedDevice == null && mConnectingDevice == null) {
Slog.i(TAG, "Connecting to Wifi display: " + mDesiredDevice.deviceName);
@@ -699,6 +760,18 @@
WifiDisplay display = createWifiDisplay(mConnectingDevice);
advertiseDisplay(display, null, 0, 0, 0);
+ if (ExtendedRemoteDisplayHelper.isAvailable() && mExtRemoteDisplay == null) {
+ final int port = getPortNumber(mDesiredDevice);
+ //IP is superfluous for WFD source, and we don't have one at this stage anyway since
+ //P2P connection hasn't been established yet
+ final String iface = "255.255.255.255:" + port;
+ mRemoteDisplayInterface = iface;
+ Slog.i(TAG, "Listening for RTSP connection on " + iface
+ + " from Wifi display: " + mDesiredDevice.deviceName);
+ mExtRemoteDisplay = ExtendedRemoteDisplayHelper.listen(iface,
+ listener, mHandler, mContext);
+ }
+
final WifiP2pDevice newDevice = mDesiredDevice;
mWifiP2pManager.connect(mWifiP2pChannel, config, new ActionListener() {
@Override
@@ -736,54 +809,16 @@
mWifiP2pManager.setMiracastMode(WifiP2pManager.MIRACAST_SOURCE);
- final WifiP2pDevice oldDevice = mConnectedDevice;
final int port = getPortNumber(mConnectedDevice);
final String iface = addr.getHostAddress() + ":" + port;
mRemoteDisplayInterface = iface;
- Slog.i(TAG, "Listening for RTSP connection on " + iface
- + " from Wifi display: " + mConnectedDevice.deviceName);
-
- mRemoteDisplay = RemoteDisplay.listen(iface, new RemoteDisplay.Listener() {
- @Override
- public void onDisplayConnected(Surface surface,
- int width, int height, int flags, int session) {
- if (mConnectedDevice == oldDevice && !mRemoteDisplayConnected) {
- Slog.i(TAG, "Opened RTSP connection with Wifi display: "
- + mConnectedDevice.deviceName);
- mRemoteDisplayConnected = true;
- mHandler.removeCallbacks(mRtspTimeout);
-
- if (mWifiDisplayCertMode) {
- mListener.onDisplaySessionInfo(
- getSessionInfo(mConnectedDeviceGroupInfo, session));
- }
-
- final WifiDisplay display = createWifiDisplay(mConnectedDevice);
- advertiseDisplay(display, surface, width, height, flags);
- }
- }
-
- @Override
- public void onDisplayDisconnected() {
- if (mConnectedDevice == oldDevice) {
- Slog.i(TAG, "Closed RTSP connection with Wifi display: "
- + mConnectedDevice.deviceName);
- mHandler.removeCallbacks(mRtspTimeout);
- disconnect();
- }
- }
-
- @Override
- public void onDisplayError(int error) {
- if (mConnectedDevice == oldDevice) {
- Slog.i(TAG, "Lost RTSP connection with Wifi display due to error "
- + error + ": " + mConnectedDevice.deviceName);
- mHandler.removeCallbacks(mRtspTimeout);
- handleConnectionFailure(false);
- }
- }
- }, mHandler, mContext.getOpPackageName());
+ if (!ExtendedRemoteDisplayHelper.isAvailable()) {
+ Slog.i(TAG, "Listening for RTSP connection on " + iface
+ + " from Wifi display: " + mConnectedDevice.deviceName);
+ mRemoteDisplay = RemoteDisplay.listen(iface, listener,
+ mHandler, mContext.getOpPackageName());
+ }
// Use extended timeout value for certification, as some tests require user inputs
int rtspTimeout = mWifiDisplayCertMode ?
@@ -794,7 +829,7 @@
}
private WifiDisplaySessionInfo getSessionInfo(WifiP2pGroup info, int session) {
- if (info == null) {
+ if (info == null || info.getOwner() == null) {
return null;
}
Inet4Address addr = getInterfaceAddress(info);
@@ -835,6 +870,10 @@
mWifiP2pManager.requestGroupInfo(mWifiP2pChannel, new GroupInfoListener() {
@Override
public void onGroupInfoAvailable(WifiP2pGroup info) {
+ if (info == null) {
+ return;
+ }
+
if (DEBUG) {
Slog.d(TAG, "Received group info: " + describeWifiP2pGroup(info));
}
@@ -854,8 +893,9 @@
}
if (mWifiDisplayCertMode) {
- boolean owner = info.getOwner().deviceAddress
- .equals(mThisDevice.deviceAddress);
+ boolean owner = info.getOwner() != null ?
+ info.getOwner().deviceAddress.equals(
+ mThisDevice.deviceAddress) : false;
if (owner && info.getClientList().isEmpty()) {
// this is the case when we started Autonomous GO,
// and no client has connected, save group info
@@ -893,6 +933,12 @@
disconnect();
}
+ if (mDesiredDevice != null) {
+ Slog.i(TAG, "Reconnect new device: " + mDesiredDevice.deviceName);
+ updateConnection();
+ return;
+ }
+
// After disconnection for a group, for some reason we have a tendency
// to get a peer change notification with an empty list of peers.
// Perform a fresh scan.
@@ -925,7 +971,8 @@
@Override
public void run() {
if (mConnectedDevice != null
- && mRemoteDisplay != null && !mRemoteDisplayConnected) {
+ && (mRemoteDisplay != null || mExtRemoteDisplay != null)
+ && !mRemoteDisplayConnected) {
Slog.i(TAG, "Timed out waiting for Wifi display RTSP connection after "
+ RTSP_TIMEOUT_SECONDS + " seconds: "
+ mConnectedDevice.deviceName);
@@ -1009,6 +1056,42 @@
mAdvertisedDisplayFlags);
}
+ private boolean handlePreExistingConnection(final WifiP2pDevice device) {
+ if (mNetworkInfo == null || !mNetworkInfo.isConnected() || mWifiDisplayCertMode) {
+ return false;
+ }
+ if (DEBUG) Slog.i(TAG, "Handle the preexisting P2P connection status");
+ mWifiP2pManager.requestGroupInfo(mWifiP2pChannel, new GroupInfoListener() {
+ @Override
+ public void onGroupInfoAvailable(WifiP2pGroup info) {
+ if (info == null) {
+ return;
+ }
+ if (contains(info, device)) {
+ if (DEBUG) Slog.i(TAG, "Already connected to the desired device: "
+ + device.deviceName);
+ updateConnection();
+ handleConnectionChanged(mNetworkInfo);
+ } else {
+ mWifiP2pManager.removeGroup(mWifiP2pChannel, new ActionListener() {
+ @Override
+ public void onSuccess() {
+ Slog.i(TAG, "Disconnect the old device");
+ }
+
+ @Override
+ public void onFailure(int reason) {
+ Slog.w(TAG, "Failed to disconnect the old device: reason=" + reason);
+ }
+ });
+ }
+ }
+ });
+ mDesiredDevice = device;
+ mConnectionRetriesLeft = CONNECT_MAX_RETRIES;
+ return true;
+ }
+
private static Inet4Address getInterfaceAddress(WifiP2pGroup info) {
NetworkInterface iface;
try {
diff --git a/services/core/java/com/android/server/dreams/DreamManagerService.java b/services/core/java/com/android/server/dreams/DreamManagerService.java
index e3eeb6c4..d2387b9 100644
--- a/services/core/java/com/android/server/dreams/DreamManagerService.java
+++ b/services/core/java/com/android/server/dreams/DreamManagerService.java
@@ -193,6 +193,12 @@
}
}
+ private boolean isDozingInternal() {
+ synchronized (mLock) {
+ return mCurrentDreamIsDozing;
+ }
+ }
+
private void requestDreamInternal() {
// Ask the power manager to nap. It will eventually call back into
// startDream() if/when it is appropriate to start dreaming.
@@ -617,6 +623,18 @@
}
@Override // Binder call
+ public boolean isDozing() {
+ checkPermission(android.Manifest.permission.READ_DREAM_STATE);
+
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ return isDozingInternal();
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override // Binder call
public void dream() {
checkPermission(android.Manifest.permission.WRITE_DREAM_STATE);
@@ -743,6 +761,11 @@
public ComponentName getActiveDreamComponent(boolean doze) {
return getActiveDreamComponentInternal(doze);
}
+
+ @Override
+ public boolean isDozing() {
+ return isDozingInternal();
+ }
}
private final Runnable mSystemPropertiesChanged = new Runnable() {
diff --git a/services/core/java/com/android/server/location/gnss/GnssMeasurementsProvider.java b/services/core/java/com/android/server/location/gnss/GnssMeasurementsProvider.java
index b426701..68e4ef1 100644
--- a/services/core/java/com/android/server/location/gnss/GnssMeasurementsProvider.java
+++ b/services/core/java/com/android/server/location/gnss/GnssMeasurementsProvider.java
@@ -72,7 +72,7 @@
private boolean getMergedFullTracking() {
int devOptions = Settings.Secure.getInt(mContext.getContentResolver(),
- Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0);
+ Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1);
int enableFullTracking = Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.ENABLE_GNSS_RAW_MEAS_FULL_TRACKING, 0);
boolean enableFullTrackingBySetting = (devOptions == 1 /* Developer Mode enabled */)
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index f630820..9fe919b 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -203,6 +203,7 @@
// Order of holding lock: mSeparateChallengeLock -> mSpManager -> this
// Do not call into ActivityManager while holding mSpManager lock.
private final Object mSeparateChallengeLock = new Object();
+ private static final String DEFAULT_PASSWORD = "default_password";
private final DeviceProvisionedObserver mDeviceProvisionedObserver =
new DeviceProvisionedObserver();
@@ -223,6 +224,7 @@
private final SyntheticPasswordManager mSpManager;
private final KeyStore mKeyStore;
+ private static String mSavePassword = DEFAULT_PASSWORD;
private final RecoverableKeyStoreManager mRecoverableKeyStoreManager;
private ManagedProfilePasswordCache mManagedProfilePasswordCache;
@@ -1255,6 +1257,45 @@
return getCredentialTypeInternal(userId) != CREDENTIAL_TYPE_NONE;
}
+ public void retainPassword(String password) {
+ if (LockPatternUtils.isDeviceEncryptionEnabled()) {
+ if (password != null)
+ mSavePassword = password;
+ else
+ mSavePassword = DEFAULT_PASSWORD;
+ }
+ }
+
+ public void sanitizePassword() {
+ if (LockPatternUtils.isDeviceEncryptionEnabled()) {
+ mSavePassword = DEFAULT_PASSWORD;
+ }
+ }
+
+ private boolean checkCryptKeeperPermissions() {
+ boolean permission_err = false;
+ try {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.CRYPT_KEEPER,
+ "no permission to get the password");
+ } catch (SecurityException e) {
+ permission_err = true;
+ }
+ return permission_err;
+ }
+
+ public String getPassword() {
+ /** if calling process does't have crypt keeper or admin permissions,
+ * throw the exception.
+ */
+ if (checkCryptKeeperPermissions())
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE,
+ "no crypt_keeper or admin permission to get the password");
+
+ return mSavePassword;
+ }
+
private void setKeystorePassword(byte[] password, int userHandle) {
final KeyStore ks = KeyStore.getInstance();
// TODO(b/120484642): Update keystore to accept byte[] passwords
@@ -1969,7 +2010,15 @@
ICheckCredentialProgressCallback progressCallback) {
checkPasswordReadPermission(userId);
try {
- return doVerifyCredential(credential, CHALLENGE_NONE, 0, userId, progressCallback);
+ VerifyCredentialResponse response = doVerifyCredential(credential, CHALLENGE_NONE,
+ 0, userId, progressCallback);
+ if ((response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) &&
+ (userId == UserHandle.USER_OWNER)) {
+ //TODO(b/127810705): Update to credentials to use byte[]
+ String credentialString = credential.isNone() ? null : new String(credential.getCredential());
+ retainPassword(credentialString);
+ }
+ return response;
} finally {
scheduleGc();
}
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 803eb86..6dd7ac3 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -36,6 +36,7 @@
import android.content.pm.PackageManager;
import android.content.pm.ParceledListSlice;
import android.content.pm.UserInfo;
+import android.content.res.Configuration;
import android.database.ContentObserver;
import android.media.AudioManager;
import android.media.AudioManagerInternal;
@@ -79,7 +80,10 @@
import android.util.SparseArray;
import android.util.SparseIntArray;
import android.view.KeyEvent;
+import android.view.Surface;
+import android.view.View;
import android.view.ViewConfiguration;
+import android.view.WindowManager;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
@@ -105,7 +109,7 @@
private static final String TAG = "MediaSessionService";
static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
// Leave log for key event always.
- static final boolean DEBUG_KEY_EVENT = true;
+ static final boolean DEBUG_KEY_EVENT = false;
private static final int WAKELOCK_TIMEOUT = 5000;
private static final int MEDIA_KEY_LISTENER_TIMEOUT = 1000;
@@ -1742,6 +1746,21 @@
break;
}
if (down || up) {
+ final WindowManager windowService = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
+ if (windowService != null) {
+ final int rotation = windowService.getDefaultDisplay().getRotation();
+ final Configuration config = getContext().getResources().getConfiguration();
+ final boolean swapKeys = Settings.System.getIntForUser(getContext().getContentResolver(),
+ Settings.System.SWAP_VOLUME_BUTTONS, 0, UserHandle.USER_CURRENT) == 1;
+
+ if (swapKeys
+ && (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_180)
+ && config.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR) {
+ direction = keyEvent.getKeyCode() == KeyEvent.KEYCODE_VOLUME_UP
+ ? AudioManager.ADJUST_LOWER
+ : AudioManager.ADJUST_RAISE;
+ }
+ }
int flags = AudioManager.FLAG_FROM_KEY;
if (musicOnly) {
// This flag is used when the screen is off to only affect active media.
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index ffa518e..fa0a3174 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -3891,7 +3891,7 @@
// quick check: if this uid doesn't have INTERNET permission, it
// doesn't have network access anyway, so it is a waste to mess
// with it here.
- if (hasInternetPermissionUL(uid)) {
+ if (hasInternetPermissionUL(uid) && !isUidForegroundOnRestrictPowerUL(uid)) {
uidRules.put(uid, FIREWALL_RULE_DENY);
}
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 4772fcc..14b4ff4 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -5967,7 +5967,7 @@
private void doChannelWarningToast(CharSequence toastText) {
Binder.withCleanCallingIdentity(() -> {
- final int defaultWarningEnabled = Build.IS_DEBUGGABLE ? 1 : 0;
+ final int defaultWarningEnabled = Build.IS_ENG ? 1 : 0;
final boolean warningEnabled = Settings.Global.getInt(getContext().getContentResolver(),
Settings.Global.SHOW_NOTIFICATION_CHANNEL_WARNINGS, defaultWarningEnabled) != 0;
if (warningEnabled) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 7a8d1f9..db7863c 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -1479,6 +1479,8 @@
filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
}
+ ArrayList<ComponentName> mDisabledComponentsList;
+
// Set of pending broadcasts for aggregating enable/disable of components.
@VisibleForTesting(visibility = Visibility.PACKAGE)
public static class PendingPackageBroadcasts {
@@ -1653,6 +1655,8 @@
private final PackageUsage mPackageUsage = new PackageUsage();
private final CompilerStats mCompilerStats = new CompilerStats();
+ private Signature[] mVendorPlatformSignatures = new Signature[0];
+
class PackageHandler extends Handler {
PackageHandler(Looper looper) {
@@ -2819,6 +2823,14 @@
mPackages.putAll(testParams.packages);
}
+ private static Signature[] createSignatures(String[] hexBytes) {
+ Signature[] sigs = new Signature[hexBytes.length];
+ for (int i = 0; i < sigs.length; i++) {
+ sigs[i] = new Signature(hexBytes[i]);
+ }
+ return sigs;
+ }
+
public PackageManagerService(Injector injector, boolean onlyCore, boolean factoryTest) {
PackageManager.disableApplicationInfoCache();
PackageManager.disablePackageInfoCache();
@@ -2850,6 +2862,9 @@
mMetrics = new DisplayMetrics();
mInstaller = injector.getInstaller();
+ mVendorPlatformSignatures = createSignatures(mContext.getResources().getStringArray(
+ com.android.internal.R.array.config_vendorPlatformSignatures));
+
// Create sub-components that provide services / data. Order here is important.
t.traceBegin("createSubComponents");
@@ -3043,10 +3058,10 @@
File frameworkDir = new File(Environment.getRootDirectory(), "framework");
final VersionInfo ver = mSettings.getInternalVersion();
- mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
+ mIsUpgrade = !Build.DATE.equals(ver.fingerprint);
if (mIsUpgrade) {
logCriticalInfo(Log.INFO,
- "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
+ "Upgrading from " + ver.fingerprint + " to " + Build.DATE);
}
// when upgrading from pre-M, promote system app permissions from install to runtime
@@ -3069,7 +3084,7 @@
}
}
- mCacheDir = preparePackageParserCache();
+ mCacheDir = preparePackageParserCache(mIsUpgrade);
// Set flag to monitor and not change apk file paths when
// scanning install directories.
@@ -3496,6 +3511,38 @@
Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
}, "prepareAppData");
+ // Disable components marked for disabling at build-time
+ mDisabledComponentsList = new ArrayList<ComponentName>();
+ for (String name : mContext.getResources().getStringArray(
+ com.android.internal.R.array.config_disabledComponents)) {
+ ComponentName cn = ComponentName.unflattenFromString(name);
+ mDisabledComponentsList.add(cn);
+ Slog.v(TAG, "Disabling " + name);
+ String className = cn.getClassName();
+ PackageSetting pkgSetting = mSettings.mPackages.get(cn.getPackageName());
+ if (pkgSetting == null || pkgSetting.pkg == null
+ || !AndroidPackageUtils.hasComponentClassName(pkgSetting.pkg, className)) {
+ Slog.w(TAG, "Unable to disable " + name);
+ continue;
+ }
+ pkgSetting.disableComponentLPw(className, UserHandle.USER_OWNER);
+ }
+
+ // Enable components marked for forced-enable at build-time
+ for (String name : mContext.getResources().getStringArray(
+ com.android.internal.R.array.config_forceEnabledComponents)) {
+ ComponentName cn = ComponentName.unflattenFromString(name);
+ Slog.v(TAG, "Enabling " + name);
+ String className = cn.getClassName();
+ PackageSetting pkgSetting = mSettings.mPackages.get(cn.getPackageName());
+ if (pkgSetting == null || pkgSetting.pkg == null
+ || !AndroidPackageUtils.hasComponentClassName(pkgSetting.pkg, className)) {
+ Slog.w(TAG, "Unable to enable " + name);
+ continue;
+ }
+ pkgSetting.enableComponentLPw(className, UserHandle.USER_OWNER);
+ }
+
// 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
@@ -3513,7 +3560,7 @@
| Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES);
}
}
- ver.fingerprint = Build.FINGERPRINT;
+ ver.fingerprint = Build.DATE;
}
// Grandfather existing (installed before Q) non-system apps to hide
@@ -3886,7 +3933,7 @@
setUpInstantAppInstallerActivityLP(getInstantAppInstallerLPr());
}
- private static @Nullable File preparePackageParserCache() {
+ private static @Nullable File preparePackageParserCache(boolean isUpgrade) {
if (!FORCE_PACKAGE_PARSED_CACHE_ENABLED) {
if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
return null;
@@ -3914,14 +3961,14 @@
// feature flags should cause us to invalidate any caches.
final String cacheName = FORCE_PACKAGE_PARSED_CACHE_ENABLED ? "debug"
: SystemProperties.digestOf(
- "ro.build.fingerprint",
+ "ro.build.date",
StorageManager.PROP_ISOLATED_STORAGE,
StorageManager.PROP_ISOLATED_STORAGE_SNAPSHOT
);
// Reconcile cache directories, keeping only what we'd actually use.
for (File cacheDir : FileUtils.listFilesOrEmpty(cacheBaseDir)) {
- if (Objects.equals(cacheName, cacheDir.getName())) {
+ if (!isUpgrade && Objects.equals(cacheName, cacheDir.getName())) {
Slog.d(TAG, "Keeping known cache " + cacheDir.getName());
} else {
Slog.d(TAG, "Destroying unknown cache " + cacheDir.getName());
@@ -9186,6 +9233,20 @@
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
parsedPackage.setSigningDetails(
ParsingPackageUtils.getSigningDetails(parsedPackage, skipVerify));
+ if (compareSignatures(ParsingPackageUtils.getSigningDetails(
+ parsedPackage, skipVerify).signatures, mVendorPlatformSignatures) ==
+ PackageManager.SIGNATURE_MATCH) {
+ // Overwrite package signature with our platform signature
+ // if the signature is the vendor's platform signature
+ if (mPlatformPackage != null) {
+ parsedPackage.setSigningDetails(ParsingPackageUtils.getSigningDetails(
+ mPlatformPackage, skipVerify));
+ parsedPackage.setSeInfo(SELinuxMMAC.getSeInfo(
+ parsedPackage,
+ parsedPackage.isPrivileged(),
+ parsedPackage.getTargetSdkVersion()));
+ }
+ }
} catch (PackageParserException e) {
throw PackageManagerException.from(e);
} finally {
@@ -9383,7 +9444,8 @@
null, disabledPkgSetting /* pkgSetting */,
null /* disabledPkgSetting */, null /* originalPkgSetting */,
null, parseFlags, scanFlags, isPlatformPackage, user, null);
- applyPolicy(parsedPackage, parseFlags, scanFlags, mPlatformPackage, true);
+ applyPolicy(parsedPackage, parseFlags, scanFlags, mPlatformPackage, true,
+ mVendorPlatformSignatures);
final ScanResult scanResult =
scanPackageOnlyLI(request, mInjector, mFactoryTest, -1L);
if (scanResult.existingSettingCopied && scanResult.request.pkgSetting != null) {
@@ -11022,7 +11084,8 @@
} else {
isUpdatedSystemApp = disabledPkgSetting != null;
}
- applyPolicy(parsedPackage, parseFlags, scanFlags, mPlatformPackage, isUpdatedSystemApp);
+ applyPolicy(parsedPackage, parseFlags, scanFlags, mPlatformPackage, isUpdatedSystemApp,
+ mVendorPlatformSignatures);
assertPackageIsValid(parsedPackage, parseFlags, scanFlags);
SharedUserSetting sharedUserSetting = null;
@@ -11783,7 +11846,7 @@
*/
private static void applyPolicy(ParsedPackage parsedPackage, final @ParseFlags int parseFlags,
final @ScanFlags int scanFlags, AndroidPackage platformPkg,
- boolean isUpdatedSystemApp) {
+ boolean isUpdatedSystemApp, Signature[] vendorPlatformSignatures) {
if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
parsedPackage.setSystem(true);
// TODO(b/135203078): Can this be done in PackageParser? Or just inferred when the flag
@@ -11822,10 +11885,12 @@
// Check if the package is signed with the same key as the platform package.
parsedPackage.setSignedWithPlatformKey(
(PLATFORM_PACKAGE_NAME.equals(parsedPackage.getPackageName())
- || (platformPkg != null && compareSignatures(
+ || (platformPkg != null && (compareSignatures(
platformPkg.getSigningDetails().signatures,
parsedPackage.getSigningDetails().signatures
- ) == PackageManager.SIGNATURE_MATCH))
+ ) == PackageManager.SIGNATURE_MATCH) || (compareSignatures(
+ vendorPlatformSignatures, parsedPackage.getSigningDetails().signatures) ==
+ PackageManager.SIGNATURE_MATCH)))
);
if (!parsedPackage.isSystem()) {
@@ -20954,6 +21019,12 @@
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;
+ }
setEnabledSetting(componentName.getPackageName(),
componentName.getClassName(), newState, flags, userId, null);
}
@@ -22551,7 +22622,7 @@
Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
}
- if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
+ if (!Build.DATE.equals(ver.fingerprint)) {
clearAppDataLIF(ps.pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE
| FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY
| Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES);
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index a7164f9..4276a5a 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -357,7 +357,7 @@
public void forceCurrent() {
sdkVersion = Build.VERSION.SDK_INT;
databaseVersion = CURRENT_DATABASE_VERSION;
- fingerprint = Build.FINGERPRINT;
+ fingerprint = Build.DATE;
}
}
@@ -3146,7 +3146,7 @@
// on update drop the files before loading them.
if (PackageManagerService.CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE) {
final VersionInfo internal = getInternalVersion();
- if (!Build.FINGERPRINT.equals(internal.fingerprint)) {
+ if (!Build.DATE.equals(internal.fingerprint)) {
for (UserInfo user : users) {
mRuntimePermissionsPersistence.deleteUserRuntimePermissionsFile(user.id);
}
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 0c42ff6..9903c2d 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -4790,7 +4790,7 @@
// Injection point.
String injectBuildFingerprint() {
- return Build.FINGERPRINT;
+ return Build.DATE;
}
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 f5d7d9e..a768e8e 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -3488,7 +3488,7 @@
userInfo.creationTime = getCreationTime();
userInfo.partial = true;
userInfo.preCreated = preCreate;
- userInfo.lastLoggedInFingerprint = Build.FINGERPRINT;
+ userInfo.lastLoggedInFingerprint = Build.DATE;
if (userTypeDetails.hasBadge() && parentId != UserHandle.USER_NULL) {
userInfo.profileBadge = getFreeProfileBadgeLU(parentId, userType);
}
@@ -4414,7 +4414,7 @@
t.traceBegin("onBeforeStartUser-" + userId);
final int userSerial = userInfo.serialNumber;
// Migrate only if build fingerprints mismatch
- boolean migrateAppsData = !Build.FINGERPRINT.equals(userInfo.lastLoggedInFingerprint);
+ boolean migrateAppsData = !Build.DATE.equals(userInfo.lastLoggedInFingerprint);
t.traceBegin("prepareUserData");
mUserDataPreparer.prepareUserData(userId, userSerial, StorageManager.FLAG_STORAGE_DE);
t.traceEnd();
@@ -4443,7 +4443,7 @@
}
final int userSerial = userInfo.serialNumber;
// Migrate only if build fingerprints mismatch
- boolean migrateAppsData = !Build.FINGERPRINT.equals(userInfo.lastLoggedInFingerprint);
+ boolean migrateAppsData = !Build.DATE.equals(userInfo.lastLoggedInFingerprint);
mUserDataPreparer.prepareUserData(userId, userSerial, StorageManager.FLAG_STORAGE_CE);
mPm.reconcileAppsData(userId, StorageManager.FLAG_STORAGE_CE, migrateAppsData);
}
@@ -4476,7 +4476,7 @@
if (now > EPOCH_PLUS_30_YEARS) {
userData.info.lastLoggedInTime = now;
}
- userData.info.lastLoggedInFingerprint = Build.FINGERPRINT;
+ userData.info.lastLoggedInFingerprint = Build.DATE;
scheduleWriteUser(userData);
}
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index cd53fb9..b24f2c1 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -203,6 +203,12 @@
STORAGE_PERMISSIONS.add(Manifest.permission.ACCESS_MEDIA_LOCATION);
}
+ private static final Set<String> WALLPAPER_PERMISSIONS = new ArraySet<>();
+ static {
+ WALLPAPER_PERMISSIONS.add(Manifest.permission.BIND_WALLPAPER);
+ WALLPAPER_PERMISSIONS.add(Manifest.permission.SET_WALLPAPER_COMPONENT);
+ }
+
private static final int MSG_READ_DEFAULT_PERMISSION_EXCEPTIONS = 1;
private static final String ACTION_TRACK = "com.android.fitness.TRACK";
@@ -694,6 +700,10 @@
grantPermissionsToPackage(pm, browserPackage, userId, false /* ignoreSystemPackage */,
true /*whitelistRestrictedPermissions*/, FOREGROUND_LOCATION_PERMISSIONS);
+ // Google prebuilt WP picker
+ String wpPickerPackageName = "com.android.wallpaper.livepicker";
+ grantPermissionsToSystemPackage(pm, wpPickerPackageName, userId, WALLPAPER_PERMISSIONS);
+
// Voice interaction
if (voiceInteractPackageNames != null) {
for (String voiceInteractPackageName : voiceInteractPackageNames) {
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index b500e16..86c633e 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -121,6 +121,7 @@
import android.util.SparseArray;
import android.util.SparseBooleanArray;
+import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.compat.IPlatformCompat;
@@ -1400,6 +1401,17 @@
}
}
+ private boolean isCustomPermission(String pkg) {
+ String[] apps = mContext.getResources().getStringArray(
+ R.array.config_customPermissionsList);
+ for(String app : apps) {
+ if (pkg.equals(app)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
@Override
public void grantRuntimePermission(String packageName, String permName, final int userId) {
final int callingUid = Binder.getCallingUid();
@@ -1454,7 +1466,9 @@
throw new IllegalArgumentException("Unknown package: " + packageName);
}
- bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg, ps);
+ if (!isCustomPermission(packageName)) {
+ bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg, ps);
+ }
// If a permission review is required for legacy apps we represent
// their permissions as always granted runtime ones since we need
diff --git a/services/core/java/com/android/server/policy/AlertSliderObserver.java b/services/core/java/com/android/server/policy/AlertSliderObserver.java
new file mode 100644
index 0000000..4f63e99
--- /dev/null
+++ b/services/core/java/com/android/server/policy/AlertSliderObserver.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2016-2020, 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.server.policy;
+
+import android.app.NotificationManager;
+import android.content.Context;
+import android.media.AudioManager;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
+import android.os.UEventObserver;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.Slog;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+
+public class AlertSliderObserver extends UEventObserver {
+ private static final String TAG = AlertSliderObserver.class.getSimpleName();
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+ private int mState;
+
+ private final Context mContext;
+ private final AudioManager mAudioManager;
+ private final WakeLock mWakeLock;
+
+ public AlertSliderObserver(Context context) {
+ mContext = context;
+ mAudioManager = context.getSystemService(AudioManager.class);
+ PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+ mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "AlertSliderObserver");
+ init();
+ }
+
+ protected void startObserving(int pathId) {
+ String matchPath = mContext.getResources().getString(pathId);
+ if (!TextUtils.isEmpty(matchPath)) {
+ super.startObserving(matchPath);
+ }
+ }
+
+ @Override
+ public void onUEvent(UEventObserver.UEvent event) {
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Slog.v(TAG, "Switch UEVENT: " + event.toString());
+ }
+
+ try {
+ int state = Integer.parseInt(event.get("SWITCH_STATE"));
+ if (state != mState) {
+ mState = state;
+ update();
+ }
+ } catch (NumberFormatException e) {
+ Slog.e(TAG, "Could not parse switch state from event " + event);
+ }
+ }
+
+ private void init() {
+ try {
+ final String path = mContext.getResources().getString(
+ com.android.internal.R.string.alert_slider_state_path);
+ FileReader file = new FileReader(path);
+ BufferedReader br = new BufferedReader(file);
+ String value = br.readLine();
+ file.close();
+ br.close();
+ mState = Integer.valueOf(value);
+ update();
+ } catch (IOException e) {
+ Slog.w(TAG, "This device does not have an Alert Slider");
+ stopObserving();
+ }
+ }
+
+ protected void update() {
+ // Acquire wakelock when slider state changes.
+ mWakeLock.acquire();
+ mHandler.sendEmptyMessageDelayed(mState, 100);
+ }
+
+ private Handler mHandler = new Handler(Looper.myLooper(), null, true) {
+ @Override
+ public void handleMessage(Message msg) {
+ final boolean inverted = isOrderInverted();
+ switch (mState) {
+ case 1:
+ mAudioManager.setRingerModeInternal(AudioManager.RINGER_MODE_SILENT);
+ break;
+ case 2:
+ mAudioManager.setRingerModeInternal(AudioManager.RINGER_MODE_VIBRATE);
+ break;
+ case 3:
+ mAudioManager.setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL);
+ break;
+ }
+ if (mWakeLock.isHeld()) {
+ mWakeLock.release();
+ }
+ }
+ };
+
+ // Check if ordered has been set to inverted.
+ private boolean isOrderInverted() {
+ return Settings.System.getIntForUser(
+ mContext.getContentResolver(), Settings.System.ALERT_SLIDER_ORDER, 0,
+ UserHandle.USER_CURRENT) != 0;
+ }
+}
diff --git a/services/core/java/com/android/server/policy/HardkeyActionHandler.java b/services/core/java/com/android/server/policy/HardkeyActionHandler.java
new file mode 100644
index 0000000..4ff9eb16
--- /dev/null
+++ b/services/core/java/com/android/server/policy/HardkeyActionHandler.java
@@ -0,0 +1,735 @@
+/**
+ * Copyright (C) 2014 The TeamEos Project
+ * Copyright (C) 2016 The DirtyUnicorns Project
+ *
+ * @author Randall Rushing <randall.rushing@gmail.com>
+ *
+ * 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.
+ *
+ * Single tap, double tap, and long press logic for hardware key events
+ * Monitors user configuration changes, sets sane defaults, executes actions,
+ * lets PhoneWindowManager know relevant configuration changes. This handler
+ * fully consumes all key events it watches
+ *
+ */
+
+package com.android.server.policy;
+
+import java.util.ArrayList;
+
+import com.android.internal.util.hwkeys.ActionConstants;
+import com.android.internal.util.hwkeys.ActionHandler;
+import com.android.internal.util.hwkeys.ActionUtils;
+import com.android.internal.util.hwkeys.Config;
+import com.android.internal.util.hwkeys.Config.ActionConfig;
+import com.android.internal.util.hwkeys.Config.ButtonConfig;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.os.Handler;
+import android.os.Message;
+import android.os.PowerManager;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.telecom.TelecomManager;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.ViewConfiguration;
+import android.view.IWindowManager;
+import android.view.WindowManager;
+import android.view.WindowManagerGlobal;
+import com.android.server.policy.WindowManagerPolicy.WindowState;
+
+public class HardkeyActionHandler {
+ private interface ActionReceiver {
+ public void onActionDispatched(HardKeyButton button, String task);
+ }
+
+ private static final String TAG = HardkeyActionHandler.class.getSimpleName();
+
+ // messages to PWM to do some actions we can't really do here
+ public static final int MSG_FIRE_HOME = 7102;
+ public static final int MSG_UPDATE_MENU_KEY = 7106;
+ public static final int MSG_DO_HAPTIC_FB = 7107;
+
+ // fire rocket boosters
+ private static final int BOOST_LEVEL = 1000 * 1000;
+
+ private static final int KEY_MASK_HOME = 0x01;
+ private static final int KEY_MASK_BACK = 0x02;
+ private static final int KEY_MASK_MENU = 0x04;
+ private static final int KEY_MASK_ASSIST = 0x08;
+ private static final int KEY_MASK_APP_SWITCH = 0x10;
+ private static final int KEY_MASK_CAMERA = 0x20;
+ private static final int KEY_MASK_VOLUME = 0x40;
+
+ // lock our configuration changes
+ private final Object mLock = new Object();
+
+ private HardKeyButton mBackButton;
+ private HardKeyButton mHomeButton;
+ private HardKeyButton mRecentButton;
+ private HardKeyButton mMenuButton;
+ private HardKeyButton mAssistButton;
+
+ // Behavior of HOME button during incomming call ring.
+ // (See Settings.Secure.RING_HOME_BUTTON_BEHAVIOR.)
+// int mRingHomeBehavior;
+
+ private ActionReceiver mActionReceiver = new ActionReceiver() {
+ @Override
+ public void onActionDispatched(HardKeyButton button, String task) {
+ if (task.equals(ActionHandler.SYSTEMUI_TASK_HOME)) {
+ mHandler.sendEmptyMessage(MSG_FIRE_HOME);
+ return;
+ } else if (task.equals(ActionHandler.SYSTEMUI_TASK_SCREENOFF)) {
+ // can't consume UP event if screen is off, do it manually
+ button.setPressed(false);
+ button.setWasConsumed(false);
+ }
+ ActionHandler.performTask(mContext, task);
+ }
+ };
+
+ private int mDeviceHardwareKeys;
+
+ private SettingsObserver mObserver;
+ private Handler mHandler;
+// private PowerManager mPm;
+ private Context mContext;
+ private boolean mHwKeysDisabled = false;
+
+ public HardkeyActionHandler(Context context, Handler handler) {
+ mContext = context;
+ mHandler = handler;
+// mPm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+
+ mDeviceHardwareKeys = ActionUtils.getInt(context, "config_deviceHardwareKeys",
+ ActionUtils.PACKAGE_ANDROID);
+
+ mBackButton = new HardKeyButton(mActionReceiver, handler);
+ mHomeButton = new HardKeyButton(mActionReceiver, handler);
+ mRecentButton = new HardKeyButton(mActionReceiver, handler);
+ mMenuButton = new HardKeyButton(mActionReceiver, handler);
+ mAssistButton = new HardKeyButton(mActionReceiver, handler);
+
+ mObserver = new SettingsObserver(mHandler);
+ mObserver.observe();
+ }
+
+ void fireBooster(HardKeyButton button) {
+// if (!button.isDoubleTapPending()) {
+// mPm.cpuBoost(BOOST_LEVEL);
+// }
+ }
+
+ public boolean isHwKeysDisabled() {
+ return mHwKeysDisabled;
+ }
+
+ private boolean filterDisabledKey(int keyCode) {
+ return mHwKeysDisabled && (keyCode == KeyEvent.KEYCODE_HOME
+ || keyCode == KeyEvent.KEYCODE_MENU
+ || keyCode == KeyEvent.KEYCODE_APP_SWITCH
+ || keyCode == KeyEvent.KEYCODE_ASSIST
+ || keyCode == KeyEvent.KEYCODE_BACK);
+ }
+
+ public boolean handleKeyEvent(WindowState win, int keyCode, int repeatCount, boolean down,
+ boolean canceled,
+ boolean longPress, boolean keyguardOn) {
+ if (filterDisabledKey(keyCode)) {
+ return true;
+ }
+
+ if (keyCode == KeyEvent.KEYCODE_HOME) {
+ if (!down && mHomeButton.isPressed()) {
+ mHomeButton.setPressed(false);
+ if (mHomeButton.wasConsumed()) {
+ mHomeButton.setWasConsumed(false);
+ return true;
+ }
+
+ if (!mHomeButton.keyHasDoubleTapRecents()) {
+ ActionHandler.cancelPreloadRecentApps();
+ }
+
+ if (canceled) {
+ return true;
+ }
+/*
+ // If an incoming call is ringing, HOME is totally disabled.
+ // (The user is already on the InCallUI at this point,
+ // and his ONLY options are to answer or reject the call.)
+ TelecomManager telecomManager = getTelecommService();
+ if (telecomManager != null && telecomManager.isRinging()) {
+ if ((mRingHomeBehavior
+ & Settings.Secure.RING_HOME_BUTTON_BEHAVIOR_ANSWER) != 0) {
+ Log.i(TAG, "Answering with HOME button.");
+ telecomManager.acceptRingingCall();
+ return true;
+ } else {
+ Log.i(TAG, "Ignoring HOME; there's a ringing incoming call.");
+ return true;
+ }
+ }
+*/
+
+ // If an incoming call is ringing, HOME is totally disabled.
+ // (The user is already on the InCallUI at this point,
+ // and his ONLY options are to answer or reject the call.)
+ TelecomManager telecomManager = getTelecommService();
+ if (telecomManager != null && telecomManager.isRinging()) {
+ Log.i(TAG, "Ignoring HOME; there's a ringing incoming call.");
+ return true;
+ }
+
+ if (mHomeButton.isDoubleTapEnabled()) {
+ mHomeButton.cancelDTTimeout();
+ mHomeButton.setDoubleTapPending(true);
+ mHomeButton.postDTTimeout();
+ return true;
+ }
+
+ mHomeButton.fireSingleTap();
+ return true;
+ }
+
+ // If a system window has focus, then it doesn't make sense
+ // right now to interact with applications.
+ //
+ // NOTE: I don't think this code block is reachable here anyways because
+ // we don't intercept any key events if keyguard is showing
+ // However, "WINDOW_TYPES_WHERE_HOME_DOESNT_WORK" is reachable
+ //
+ WindowManager.LayoutParams attrs = win != null ? win.getAttrs() : null;
+ if (attrs != null) {
+ final int type = attrs.type;
+ if (type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG
+ /*|| mWm.mPolicy.isKeyguardShowing()*/) {
+ // the "app" is keyguard, so give it the key
+ // NOTE: if somehow we ever get here, send it back and let the event
+ // pass through to AOSP handling. Which, in this case, does the same
+ // thing we just did.
+ return false;
+ }
+ final int typeCount = WINDOW_TYPES_WHERE_HOME_DOESNT_WORK.length;
+ for (int i=0; i<typeCount; i++) {
+ if (type == WINDOW_TYPES_WHERE_HOME_DOESNT_WORK[i]) {
+ // don't do anything, but also don't pass it to the app
+ return true;
+ }
+ }
+ }
+
+
+ if (!down) {
+ return true;
+ }
+
+ if (repeatCount == 0) {
+ mHomeButton.setPressed(true);
+ fireBooster(mHomeButton);
+ if (mHomeButton.isDoubleTapPending()) {
+ mHomeButton.setDoubleTapPending(false);
+ mHomeButton.cancelDTTimeout();
+ mHomeButton.fireDoubleTap();
+ mHomeButton.setWasConsumed(true);
+ } else if (mHomeButton.keyHasLongPressRecents()
+ || mHomeButton.keyHasDoubleTapRecents()) {
+ ActionHandler.preloadRecentApps();
+ }
+ } else if (longPress) {
+ if (!keyguardOn
+ && !mHomeButton.wasConsumed()
+ && mHomeButton.isLongTapEnabled()) {
+ mHomeButton.setPressed(true);
+ if (!mHomeButton.keyHasLongPressRecents()) {
+ ActionHandler.cancelPreloadRecentApps();
+ }
+ mHandler.sendEmptyMessage(MSG_DO_HAPTIC_FB);
+ mHomeButton.fireLongPress();
+ mHomeButton.setWasConsumed(true);
+ }
+ }
+ return true;
+ } else if (keyCode == KeyEvent.KEYCODE_MENU) {
+ if (!down && mMenuButton.isPressed()) {
+ mMenuButton.setPressed(false);
+
+ if (mMenuButton.wasConsumed()) {
+ mMenuButton.setWasConsumed(false);
+ return true;
+ }
+
+ if (!mMenuButton.keyHasDoubleTapRecents()) {
+ ActionHandler.cancelPreloadRecentApps();
+ }
+
+ if (canceled || keyguardOn) {
+ return true;
+ }
+
+ if (mMenuButton.isDoubleTapEnabled()) {
+ mMenuButton.setDoubleTapPending(true);
+ mMenuButton.cancelDTTimeout();
+ mMenuButton.postDTTimeout();
+ return true;
+ }
+
+ if (!mMenuButton.keyHasSingleTapRecent()) {
+ ActionHandler.cancelPreloadRecentApps();
+ }
+
+ mMenuButton.fireSingleTap();
+ return true;
+ }
+
+ if (!down) {
+ return true;
+ }
+
+ if (repeatCount == 0) {
+ mMenuButton.setPressed(true);
+ fireBooster(mMenuButton);
+ if (mMenuButton.isDoubleTapPending()) {
+ mMenuButton.setDoubleTapPending(false);
+ mMenuButton.cancelDTTimeout();
+ mMenuButton.fireDoubleTap();
+ mMenuButton.setWasConsumed(true);
+ } else if (mMenuButton.keyHasLongPressRecents()
+ || mMenuButton.keyHasDoubleTapRecents()
+ || mMenuButton.keyHasSingleTapRecent()) {
+ ActionHandler.preloadRecentApps();
+ }
+ } else if (longPress) {
+ if (!keyguardOn
+ && !mMenuButton.wasConsumed()
+ && mMenuButton.isLongTapEnabled()) {
+ mMenuButton.setPressed(true);
+ if (!mMenuButton.keyHasLongPressRecents()) {
+ ActionHandler.cancelPreloadRecentApps();
+ }
+ mHandler.sendEmptyMessage(MSG_DO_HAPTIC_FB);
+ mMenuButton.fireLongPress();
+ mMenuButton.setWasConsumed(true);
+ }
+ }
+ return true;
+ } else if (keyCode == KeyEvent.KEYCODE_APP_SWITCH) {
+ if (!down && mRecentButton.isPressed()) {
+ mRecentButton.setPressed(false);
+
+ if (mRecentButton.wasConsumed()) {
+ mRecentButton.setWasConsumed(false);
+ return true;
+ }
+
+ if (!mRecentButton.keyHasDoubleTapRecents()) {
+ ActionHandler.cancelPreloadRecentApps();
+ }
+
+ if (canceled || keyguardOn) {
+ return true;
+ }
+
+ if (mRecentButton.isDoubleTapEnabled()) {
+ mRecentButton.setDoubleTapPending(true);
+ mRecentButton.cancelDTTimeout();
+ mRecentButton.postDTTimeout();
+ return true;
+ }
+
+ if (!mRecentButton.keyHasSingleTapRecent()) {
+ ActionHandler.cancelPreloadRecentApps();
+ }
+
+ mRecentButton.fireSingleTap();
+ return true;
+ }
+
+ if (!down) {
+ return true;
+ }
+
+ if (repeatCount == 0) {
+ mRecentButton.setPressed(true);
+ fireBooster(mRecentButton);
+ if (mRecentButton.isDoubleTapPending()) {
+ mRecentButton.setDoubleTapPending(false);
+ mRecentButton.cancelDTTimeout();
+ mRecentButton.fireDoubleTap();
+ mRecentButton.setWasConsumed(true);
+ } else if (mRecentButton.keyHasLongPressRecents()
+ || mRecentButton.keyHasDoubleTapRecents()
+ || mRecentButton.keyHasSingleTapRecent()) {
+ ActionHandler.preloadRecentApps();
+ }
+ } else if (longPress) {
+ if (!keyguardOn
+ && !mRecentButton.wasConsumed()
+ && mRecentButton.isLongTapEnabled()) {
+ mRecentButton.setPressed(true);
+ if (!mRecentButton.keyHasLongPressRecents()) {
+ ActionHandler.cancelPreloadRecentApps();
+ }
+ mHandler.sendEmptyMessage(MSG_DO_HAPTIC_FB);
+ mRecentButton.fireLongPress();
+ mRecentButton.setWasConsumed(true);
+ }
+ }
+ return true;
+ } else if (keyCode == KeyEvent.KEYCODE_ASSIST) {
+ if (!down && mAssistButton.isPressed()) {
+ mAssistButton.setPressed(false);
+
+ if (mAssistButton.wasConsumed()) {
+ mAssistButton.setWasConsumed(false);
+ return true;
+ }
+
+ if (!mAssistButton.keyHasDoubleTapRecents()) {
+ ActionHandler.cancelPreloadRecentApps();
+ }
+
+ if (canceled || keyguardOn) {
+ return true;
+ }
+
+ if (mAssistButton.isDoubleTapEnabled()) {
+ mAssistButton.setDoubleTapPending(true);
+ mAssistButton.cancelDTTimeout();
+ mAssistButton.postDTTimeout();
+ return true;
+ }
+
+ if (!mAssistButton.keyHasSingleTapRecent()) {
+ ActionHandler.cancelPreloadRecentApps();
+ }
+ mAssistButton.fireSingleTap();
+ return true;
+ }
+
+ if (!down) {
+ return true;
+ }
+
+ if (repeatCount == 0) {
+ mAssistButton.setPressed(true);
+ fireBooster(mAssistButton);
+ if (mAssistButton.isDoubleTapPending()) {
+ mAssistButton.setDoubleTapPending(false);
+ mAssistButton.cancelDTTimeout();
+ mAssistButton.fireDoubleTap();
+ mAssistButton.setWasConsumed(true);
+ } else if (mAssistButton.keyHasLongPressRecents()
+ || mAssistButton.keyHasDoubleTapRecents()
+ || mAssistButton.keyHasSingleTapRecent()) {
+ ActionHandler.preloadRecentApps();
+ }
+ } else if (longPress) {
+ if (!keyguardOn
+ && !mAssistButton.wasConsumed()
+ && mAssistButton.isLongTapEnabled()) {
+ mAssistButton.setPressed(true);
+ if (!mAssistButton.keyHasLongPressRecents()) {
+ ActionHandler.cancelPreloadRecentApps();
+ }
+ mHandler.sendEmptyMessage(MSG_DO_HAPTIC_FB);
+ mAssistButton.fireLongPress();
+ mAssistButton.setWasConsumed(true);
+ }
+ }
+ return true;
+ } else if (keyCode == KeyEvent.KEYCODE_BACK) {
+ if (!down && mBackButton.isPressed()) {
+ mBackButton.setPressed(false);
+
+ if (mBackButton.wasConsumed()) {
+ mBackButton.setWasConsumed(false);
+ return true;
+ }
+
+ if (!mBackButton.keyHasDoubleTapRecents()) {
+ ActionHandler.cancelPreloadRecentApps();
+ }
+
+ if (canceled || keyguardOn) {
+ return true;
+ }
+
+ if (mBackButton.isDoubleTapEnabled()) {
+ mBackButton.setDoubleTapPending(true);
+ mBackButton.cancelDTTimeout();
+ mBackButton.postDTTimeout();
+ return true;
+ }
+
+ mBackButton.fireSingleTap();
+ return true;
+ }
+
+ if (!down) {
+ return true;
+ }
+
+ if (repeatCount == 0) {
+ mBackButton.setPressed(true);
+ fireBooster(mBackButton);
+ if (mBackButton.isDoubleTapPending()) {
+ mBackButton.setDoubleTapPending(false);
+ mBackButton.cancelDTTimeout();
+ mBackButton.fireDoubleTap();
+ mBackButton.setWasConsumed(true);
+ } else if (mBackButton.keyHasLongPressRecents()
+ || mBackButton.keyHasDoubleTapRecents()) {
+ ActionHandler.preloadRecentApps();
+ }
+ } else if (longPress) {
+ if (!keyguardOn
+ && !mBackButton.wasConsumed()) {
+ mBackButton.setPressed(true);
+/* if (ActionHandler.isLockTaskOn()) {
+ ActionHandler.turnOffLockTask();
+ mHandler.sendEmptyMessage(MSG_DO_HAPTIC_FB);
+ mBackButton.setWasConsumed(true);
+ } else {
+*/
+ if (mBackButton.isLongTapEnabled()) {
+ if (!mBackButton.keyHasLongPressRecents()) {
+ ActionHandler.cancelPreloadRecentApps();
+ }
+ mBackButton.fireLongPress();
+ mHandler.sendEmptyMessage(MSG_DO_HAPTIC_FB);
+ mBackButton.setWasConsumed(true);
+ }
+// }
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ private class HardKeyButton {
+ private ButtonConfig mConfig;
+ private ActionReceiver mActionReceiver;
+ private Handler mHandler;
+
+ private boolean mDoubleTapPending = false;
+ private boolean mIsPressed = false;
+ private boolean mWasConsumed = false;
+
+ public HardKeyButton(ActionReceiver receiver, Handler handler) {
+ mHandler = handler;
+ mActionReceiver = receiver;
+ }
+
+ void setConfig(ButtonConfig config) {
+ mConfig = config;
+ }
+
+ final Runnable mDoubleTapTimeout = new Runnable() {
+ public void run() {
+ if (mDoubleTapPending) {
+ mDoubleTapPending = false;
+ if (!keyHasSingleTapRecent()) {
+ ActionHandler.cancelPreloadRecentApps();
+ }
+ mActionReceiver.onActionDispatched(HardKeyButton.this, mConfig.getActionConfig(ActionConfig.PRIMARY).getAction());
+ }
+ }
+ };
+
+ final Runnable mSTRunnable = new Runnable() {
+ public void run() {
+ mActionReceiver.onActionDispatched(HardKeyButton.this, mConfig.getActionConfig(ActionConfig.PRIMARY).getAction());
+ }
+ };
+
+ final Runnable mDTRunnable = new Runnable() {
+ public void run() {
+ mActionReceiver.onActionDispatched(HardKeyButton.this, mConfig.getActionConfig(ActionConfig.THIRD).getAction());
+ }
+ };
+
+ final Runnable mLPRunnable = new Runnable() {
+ public void run() {
+ mActionReceiver.onActionDispatched(HardKeyButton.this, mConfig.getActionConfig(ActionConfig.SECOND).getAction());
+ }
+ };
+
+ boolean keyHasSingleTapRecent() {
+ return mConfig.getActionConfig(ActionConfig.PRIMARY).isActionRecents();
+ }
+
+ boolean keyHasLongPressRecents() {
+ return mConfig.getActionConfig(ActionConfig.SECOND).isActionRecents();
+ }
+
+ boolean keyHasDoubleTapRecents() {
+ return mConfig.getActionConfig(ActionConfig.THIRD).isActionRecents();
+ }
+
+ boolean keyHasMenuAction() {
+ return ActionHandler.SYSTEMUI_TASK_MENU.equals(mConfig.getActionConfig(ActionConfig.PRIMARY).getAction())
+ || ActionHandler.SYSTEMUI_TASK_MENU.equals(mConfig.getActionConfig(ActionConfig.SECOND).getAction())
+ || ActionHandler.SYSTEMUI_TASK_MENU.equals(mConfig.getActionConfig(ActionConfig.THIRD).getAction());
+ }
+
+ boolean isDoubleTapEnabled() {
+ return !mConfig.getActionConfig(ActionConfig.THIRD).hasNoAction();
+ }
+
+ boolean isLongTapEnabled() {
+ return !mConfig.getActionConfig(ActionConfig.SECOND).hasNoAction();
+ }
+
+ void setDoubleTapPending(boolean pending) {
+ mDoubleTapPending = pending;
+ }
+
+ boolean isDoubleTapPending() {
+ return mDoubleTapPending;
+ }
+
+ void setPressed(boolean pressed) {
+ mIsPressed = pressed;
+ }
+
+ boolean isPressed() {
+ return mIsPressed;
+ }
+
+ void setWasConsumed(boolean consumed) {
+ mWasConsumed = consumed;
+ }
+
+ boolean wasConsumed() {
+ return mWasConsumed;
+ }
+
+ void fireDoubleTap() {
+ mHandler.post(mDTRunnable);
+ }
+
+ void fireLongPress() {
+ mHandler.post(mLPRunnable);
+ }
+
+ void fireSingleTap() {
+ mHandler.post(mSTRunnable);
+ }
+
+ void cancelDTTimeout() {
+ mHandler.removeCallbacks(mDoubleTapTimeout);
+ }
+
+ void postDTTimeout() {
+ mHandler.postDelayed(mDoubleTapTimeout, ViewConfiguration.getDoubleTapTimeout());
+ }
+ }
+
+ private TelecomManager getTelecommService() {
+ return (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
+ }
+
+ private static final int[] WINDOW_TYPES_WHERE_HOME_DOESNT_WORK = {
+ WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
+ WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
+ };
+
+ private class SettingsObserver extends ContentObserver {
+ SettingsObserver(Handler handler) {
+ super(handler);
+ }
+
+ void observe() {
+ // Observe all users' changes
+ ContentResolver resolver = mContext.getContentResolver();
+ resolver.registerContentObserver(
+ Settings.Secure.getUriFor(ActionConstants.getDefaults(ActionConstants.HWKEYS)
+ .getUri()), false,
+ this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.HARDWARE_KEYS_DISABLE), false, this,
+ UserHandle.USER_ALL);
+ updateKeyAssignments();
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ updateKeyAssignments();
+ }
+ }
+
+ private void updateKeyAssignments() {
+ ContentResolver cr = mContext.getContentResolver();
+ synchronized (mLock) {
+ mHwKeysDisabled = Settings.System.getIntForUser(mContext.getContentResolver(),
+ Settings.System.HARDWARE_KEYS_DISABLE, 0,
+ UserHandle.USER_CURRENT) != 0;
+
+ final boolean hasMenu = (mDeviceHardwareKeys & KEY_MASK_MENU) != 0;
+ final boolean hasHome = (mDeviceHardwareKeys & KEY_MASK_HOME) != 0;
+ final boolean hasAssist = (mDeviceHardwareKeys & KEY_MASK_ASSIST) != 0;
+ final boolean hasAppSwitch = (mDeviceHardwareKeys & KEY_MASK_APP_SWITCH) != 0;
+
+ ArrayList<ButtonConfig> configs = Config.getConfig(mContext,
+ ActionConstants.getDefaults(ActionConstants.HWKEYS));
+
+ ButtonConfig config = Config.getButtonConfigFromTag(configs, ActionConstants.Hwkeys.BACK_BUTTON_TAG);
+ mBackButton.setConfig(config);
+
+ config = Config.getButtonConfigFromTag(configs, ActionConstants.Hwkeys.HOME_BUTTON_TAG);
+ mHomeButton.setConfig(config);
+
+ config = Config.getButtonConfigFromTag(configs, ActionConstants.Hwkeys.OVERVIEW_BUTTON_TAG);
+ mRecentButton.setConfig(config);
+
+ config = Config.getButtonConfigFromTag(configs, ActionConstants.Hwkeys.MENU_BUTTON_TAG);
+ mMenuButton.setConfig(config);
+
+ config = Config.getButtonConfigFromTag(configs, ActionConstants.Hwkeys.ASSIST_BUTTON_TAG);
+ mAssistButton.setConfig(config);
+
+ boolean hasMenuKeyEnabled = false;
+
+ if (hasHome) {
+ hasMenuKeyEnabled = mHomeButton.keyHasMenuAction();
+ }
+ if (hasMenu) {
+ hasMenuKeyEnabled |= mMenuButton.keyHasMenuAction();
+ }
+ if (hasAssist) {
+ hasMenuKeyEnabled |= mAssistButton.keyHasMenuAction();
+ }
+ if (hasAppSwitch) {
+ hasMenuKeyEnabled |= mRecentButton.keyHasMenuAction();
+ }
+ hasMenuKeyEnabled |= mBackButton.keyHasMenuAction();
+
+ // let PWM know to update menu key settings
+ Message msg = mHandler.obtainMessage(MSG_UPDATE_MENU_KEY);
+ msg.arg1 = hasMenuKeyEnabled ? 1 : 0;
+ mHandler.sendMessage(msg);
+
+// mRingHomeBehavior = Settings.Secure.getIntForUser(cr,
+// Settings.Secure.RING_HOME_BUTTON_BEHAVIOR,
+// Settings.Secure.RING_HOME_BUTTON_BEHAVIOR_DEFAULT,
+// UserHandle.USER_CURRENT);
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/policy/LegacyGlobalActions.java b/services/core/java/com/android/server/policy/LegacyGlobalActions.java
index 9c3a394..95712fd 100644
--- a/services/core/java/com/android/server/policy/LegacyGlobalActions.java
+++ b/services/core/java/com/android/server/policy/LegacyGlobalActions.java
@@ -265,7 +265,7 @@
mItems = new ArrayList<Action>();
String[] defaultActions = mContext.getResources().getStringArray(
- com.android.internal.R.array.config_globalActionsList);
+ com.android.internal.R.array.custom_config_globalActionsList);
ArraySet<String> addedKeys = new ArraySet<String>();
for (int i = 0; i < defaultActions.length; i++) {
diff --git a/services/core/java/com/android/server/policy/OPGesturesListener.java b/services/core/java/com/android/server/policy/OPGesturesListener.java
new file mode 100644
index 0000000..e4af1a0
--- /dev/null
+++ b/services/core/java/com/android/server/policy/OPGesturesListener.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2015 The Euphoria-OS Project
+ * Copyright (C) 2015 The SudaMod Project
+ * Copyright (C) 2013 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.server.policy;
+
+import android.content.Context;
+import android.util.Slog;
+import android.view.MotionEvent;
+import android.view.WindowManagerPolicyConstants.PointerEventListener;
+
+public class OPGesturesListener implements PointerEventListener {
+ private static final String TAG = "OPGestures";
+ private static final boolean DEBUG = false;
+ private static final int NUM_POINTER_SCREENSHOT = 3;
+ private static final long SWIPE_TIMEOUT_MS = 500;
+ private static final int MAX_TRACKED_POINTERS = 32;
+ private static final int UNTRACKED_POINTER = -1;
+ private static final int THREE_SWIPE_DISTANCE = 350;
+ private final int GESTURE_THREE_SWIPE_MASK = 15;
+ private final int POINTER_1_MASK = 2;
+ private final int POINTER_2_MASK = 4;
+ private final int POINTER_3_MASK = 8;
+ private final int POINTER_NONE_MASK = 1;
+ private final Callbacks mCallbacks;
+ private final int[] mDownPointerId = new int[MAX_TRACKED_POINTERS];
+ private final float[] mDownX = new float[MAX_TRACKED_POINTERS];
+ private final float[] mDownY = new float[MAX_TRACKED_POINTERS];
+ private final long[] mDownTime = new long[MAX_TRACKED_POINTERS];
+ private int mDownPointers;
+ private boolean mSwipeFireable = false;
+ private int mSwipeMask = 1;
+
+ public OPGesturesListener(Context paramContext, Callbacks callbacks) {
+ mCallbacks = checkNull("callbacks", callbacks);
+ }
+
+ private static <T> T checkNull(String name, T arg) {
+ if (arg == null) {
+ throw new IllegalArgumentException(name + " must not be null");
+ }
+ return arg;
+ }
+
+ @Override
+ public void onPointerEvent(MotionEvent event) {
+ switch (event.getActionMasked()) {
+ case MotionEvent.ACTION_DOWN:
+ mSwipeFireable = true;
+ mDownPointers = 0;
+ captureDown(event, 0);
+ break;
+ case MotionEvent.ACTION_POINTER_DOWN:
+ captureDown(event, event.getActionIndex());
+ break;
+ case MotionEvent.ACTION_MOVE:
+ if (DEBUG) Slog.d(TAG, "count3" + event.getPointerCount());
+ if (mSwipeFireable) {
+ detectSwipe(event);
+ }
+ break;
+ case MotionEvent.ACTION_UP:
+ if (mSwipeMask == GESTURE_THREE_SWIPE_MASK) {
+ mSwipeMask = 1;
+ mCallbacks.onSwipeThreeFinger();
+ }
+ break;
+ case MotionEvent.ACTION_CANCEL:
+ mSwipeFireable = false;
+ break;
+ case MotionEvent.ACTION_POINTER_UP:
+ break;
+ default:
+ if (DEBUG) Slog.d(TAG, "Ignoring " + event);
+ }
+ }
+
+ private void captureDown(MotionEvent event, int pointerIndex) {
+ final int pointerId = event.getPointerId(pointerIndex);
+ final int i = findIndex(pointerId);
+ final int pointerCount = event.getPointerCount();
+ if (DEBUG) Slog.d(TAG, "pointer " + pointerId +
+ " down pointerIndex=" + pointerIndex + " trackingIndex=" + i);
+ if (i != UNTRACKED_POINTER) {
+ mDownX[i] = event.getX(pointerIndex);
+ mDownY[i] = event.getY(pointerIndex);
+ mDownTime[i] = event.getEventTime();
+ if (DEBUG) Slog.d(TAG, "pointer " + pointerId +
+ " down x=" + mDownX[i] + " y=" + mDownY[i]);
+ }
+ if (pointerCount == NUM_POINTER_SCREENSHOT) {
+ mSwipeFireable = true;
+ return;
+ }
+ mSwipeFireable = false;
+ }
+
+ private int findIndex(int pointerId) {
+ for (int i = 0; i < mDownPointers; i++) {
+ if (mDownPointerId[i] == pointerId) {
+ return i;
+ }
+ }
+ if (mDownPointers == MAX_TRACKED_POINTERS || pointerId == MotionEvent.INVALID_POINTER_ID) {
+ return UNTRACKED_POINTER;
+ }
+ mDownPointerId[mDownPointers++] = pointerId;
+ return mDownPointers - 1;
+ }
+
+ private void detectSwipe(MotionEvent move) {
+ move.getHistorySize();
+ final int pointerCount = move.getPointerCount();
+ for (int p = 0; p < pointerCount; p++) {
+ final int pointerId = move.getPointerId(p);
+ final int i = findIndex(pointerId);
+ if (i != UNTRACKED_POINTER) {
+ detectSwipe(i, move.getEventTime(), move.getX(p), move.getY(p));
+ }
+ }
+ }
+
+ private void detectSwipe(int i, long time, float x, float y) {
+ final float fromX = mDownX[i];
+ final float fromY = mDownY[i];
+ final long elapsed = time - mDownTime[i];
+ if (DEBUG) Slog.d(TAG, "pointer " + mDownPointerId[i]
+ + " moved (" + fromX + "->" + x + "," + fromY + "->" + y + ") in " + elapsed);
+ if (mSwipeMask < GESTURE_THREE_SWIPE_MASK
+ && y > fromY + THREE_SWIPE_DISTANCE
+ && elapsed < SWIPE_TIMEOUT_MS) {
+ mSwipeMask |= 1 << i + 1;
+ if (DEBUG) Slog.d(TAG, "swipe mask = " + mSwipeMask);
+ }
+ }
+
+ interface Callbacks {
+ void onSwipeThreeFinger();
+ }
+}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 5e5a53d..c8e3b2e 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -18,6 +18,7 @@
import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
import static android.Manifest.permission.SYSTEM_ALERT_WINDOW;
+import static android.Manifest.permission.ACCESS_SURFACE_FLINGER;
import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
import static android.app.AppOpsManager.OP_TOAST_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
@@ -128,6 +129,7 @@
import android.media.AudioSystem;
import android.media.IAudioService;
import android.media.session.MediaSessionLegacyHelper;
+import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.FactoryTest;
@@ -158,6 +160,7 @@
import android.service.vr.IPersistentVrStateCallbacks;
import android.speech.RecognizerIntent;
import android.telecom.TelecomManager;
+import android.text.TextUtils;
import android.util.Log;
import android.util.LongSparseArray;
import android.util.MutableBoolean;
@@ -192,6 +195,7 @@
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;
@@ -199,8 +203,13 @@
import com.android.internal.policy.PhoneWindow;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.bliss.LineageButtons;
import com.android.server.ExtconStateObserver;
import com.android.server.ExtconUEventObserver;
+import com.android.internal.util.bliss.BlissUtils;
+import com.android.internal.util.hwkeys.ActionHandler;
+import com.android.internal.util.hwkeys.ActionUtils;
+import com.android.internal.util.ScreenshotHelper;
import com.android.server.GestureLauncherService;
import com.android.server.LocalServices;
import com.android.server.SystemServiceManager;
@@ -217,11 +226,15 @@
import com.android.server.wm.WindowManagerInternal;
import com.android.server.wm.WindowManagerInternal.AppTransitionListener;
+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;
@@ -263,6 +276,7 @@
static final int LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM = 3;
static final int LONG_PRESS_POWER_GO_TO_VOICE_ASSIST = 4;
static final int LONG_PRESS_POWER_ASSISTANT = 5; // Settings.Secure.ASSISTANT
+ static final int LONG_PRESS_POWER_TORCH = 10;
// must match: config_veryLongPresOnPowerBehavior in config.xml
static final int VERY_LONG_PRESS_POWER_NOTHING = 0;
@@ -295,6 +309,8 @@
static final int PENDING_KEY_NULL = -1;
+ static final int TORCH_DOUBLE_TAP_DELAY = 170;
+
static public final String SYSTEM_DIALOG_REASON_KEY = "reason";
static public final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
static public final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
@@ -375,6 +391,7 @@
AppOpsManager mAppOpsManager;
PackageManager mPackageManager;
private boolean mHasFeatureAuto;
+ AlertSliderObserver mAlertSliderObserver;
private boolean mHasFeatureWatch;
private boolean mHasFeatureLeanback;
private boolean mHasFeatureHdmiCec;
@@ -487,8 +504,13 @@
boolean mWakeOnAssistKeyPress;
boolean mWakeOnBackKeyPress;
+ private HardkeyActionHandler mKeyHandler;
+
private boolean mHandleVolumeKeysInWM;
+ // Volume rocker wake
+ boolean mVolumeRockerWake;
+
private boolean mPendingKeyguardOccluded;
private boolean mKeyguardOccludedChanged;
@@ -528,6 +550,9 @@
DisplayRotation mDefaultDisplayRotation;
DisplayPolicy mDefaultDisplayPolicy;
+ // The home button wake
+ boolean mHomeWakeButton;
+
// What we do when the user long presses on home
private int mLongPressOnHomeBehavior;
@@ -546,6 +571,9 @@
// Whether to support long press from power button in non-interactive mode
private boolean mSupportLongPressPowerWhenNonInteractive;
+ // Power long press action saved on key down that should happen on key up
+ private int mResolvedLongPressOnPowerBehavior;
+
// Whether to go to sleep entering theater mode from power button
private boolean mGoToSleepOnButtonPressTheaterMode;
@@ -588,10 +616,16 @@
boolean mHavePendingMediaKeyRepeatWithWakeLock;
private int mCurrentUserId;
+ private boolean haveEnableGesture = false;
// Maps global key codes to the components that will handle them.
private GlobalKeyManager mGlobalKeyManager;
+ private boolean mVolumeMusicControlActive;
+ private boolean mVolumeMusicControl;
+ private boolean mVolumeWakeActive;
+ private boolean mGlobalActionsOnLockDisable;
+
// Fallback actions by key code.
private final SparseArray<KeyCharacterMap.FallbackAction> mFallbackActions =
new SparseArray<KeyCharacterMap.FallbackAction>();
@@ -608,6 +642,12 @@
private int mPowerButtonSuppressionDelayMillis = POWER_BUTTON_SUPPRESSION_DELAY_DEFAULT_MILLIS;
+ private final List<DeviceKeyHandler> mDeviceKeyHandlers = new ArrayList<>();
+
+ private int mTorchActionMode;
+
+ private LineageButtons mLineageButtons;
+
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;
@@ -631,6 +671,12 @@
private static final int MSG_LAUNCH_ASSIST_LONG_PRESS = 24;
private static final int MSG_POWER_VERY_LONG_PRESS = 25;
private static final int MSG_RINGER_TOGGLE_CHORD = 26;
+ private static final int MSG_TOGGLE_TORCH = 50;
+ private static final int MSG_CLEAR_PROXIMITY = 51;
+ private OPGesturesListener mOPGestures;
+ private static final int MSG_DISPATCH_VOLKEY_WITH_WAKE_LOCK = 29;
+
+ private boolean mHasAlertSlider = false;
private class PolicyHandler extends Handler {
@Override
@@ -713,10 +759,35 @@
case MSG_RINGER_TOGGLE_CHORD:
handleRingerChordGesture();
break;
+ case MSG_TOGGLE_TORCH:
+ toggleFlashLight();
+ break;
+ case MSG_DISPATCH_VOLKEY_WITH_WAKE_LOCK:
+ KeyEvent event = (KeyEvent) msg.obj;
+ dispatchMediaKeyWithWakeLockToAudioService(event);
+ dispatchMediaKeyWithWakeLockToAudioService(
+ KeyEvent.changeAction(event, KeyEvent.ACTION_UP));
+ mVolumeMusicControlActive = true;
+ case HardkeyActionHandler.MSG_FIRE_HOME:
+ launchHomeFromHotKey(DEFAULT_DISPLAY);
+ break;
+// case HardkeyActionHandler.MSG_UPDATE_MENU_KEY:
+// synchronized (mLock) {
+// mHasPermanentMenuKey = msg.arg1 == 1;
+// }
+// break;
+ case HardkeyActionHandler.MSG_DO_HAPTIC_FB:
+ performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, false, "Hardkey Long-Press");
+ break;
}
}
}
+ private void toggleFlashLight() {
+ performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, true, "Flashlight toggle");
+ BlissUtils.toggleCameraFlash(true/*proximity check*/);
+ }
+
private UEventObserver mHDMIObserver = new UEventObserver() {
@Override
public void onUEvent(UEventObserver.UEvent event) {
@@ -725,6 +796,9 @@
};
class SettingsObserver extends ContentObserver {
+ private final Uri SWAP_ALERT_SLIDER_ORDER_URI =
+ Settings.System.getUriFor(Settings.System.ALERT_SLIDER_ORDER);
+
SettingsObserver(Handler handler) {
super(handler);
}
@@ -765,12 +839,39 @@
resolver.registerContentObserver(Settings.Global.getUriFor(
Settings.Global.POWER_BUTTON_SUPPRESSION_DELAY_AFTER_GESTURE_WAKE), false, this,
UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.Secure.getUriFor(
+ Settings.Secure.TORCH_POWER_BUTTON_GESTURE), false, this,
+ UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.THREE_FINGER_GESTURE), false, this,
+ UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.VOLUME_ROCKER_WAKE), false, this,
+ UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.VOLUME_BUTTON_MUSIC_CONTROL), false, this,
+ UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.LOCK_POWER_MENU_DISABLED), false, this,
+ UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.ALERT_SLIDER_ORDER), false, this,
+ UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.HOME_WAKE_BUTTON), false, this,
+ UserHandle.USER_ALL);
updateSettings();
}
- @Override public void onChange(boolean selfChange) {
- updateSettings();
- updateRotation(false);
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ if (SWAP_ALERT_SLIDER_ORDER_URI.equals(uri)
+ && mSystemReady && mAlertSliderObserver != null) {
+ mAlertSliderObserver.update();
+ } else {
+ updateSettings();
+ updateRotation(false);
+ }
}
}
@@ -963,6 +1064,7 @@
// When interactive, we're already awake.
// Wait for a long press or for the button to be released to decide what to do.
if (hasLongPressOnPowerBehavior()) {
+ mResolvedLongPressOnPowerBehavior = getResolvedLongPressOnPowerBehavior();
if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) {
powerLongPress();
} else {
@@ -979,9 +1081,12 @@
}
}
} else {
- wakeUpFromPowerKey(event.getDownTime());
-
- if (mSupportLongPressPowerWhenNonInteractive && hasLongPressOnPowerBehavior()) {
+ if ((mTorchActionMode == 2) || (mSupportLongPressPowerWhenNonInteractive
+ && hasLongPressOnPowerBehavior())) {
+ mResolvedLongPressOnPowerBehavior = getResolvedLongPressOnPowerBehavior();
+ if (mResolvedLongPressOnPowerBehavior != LONG_PRESS_POWER_TORCH) {
+ wakeUpFromPowerKey(event.getDownTime());
+ }
if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) {
powerLongPress();
} else {
@@ -999,6 +1104,10 @@
mBeganFromNonInteractive = true;
} else {
+ if ((mTorchActionMode != 1) ||
+ (mTorchActionMode == 1 && isScreenOn() && !isDozeMode())) {
+ wakeUpFromPowerKey(event.getDownTime());
+ }
final int maxCount = getMaxMultiPressPowerCount();
if (maxCount <= 1) {
@@ -1011,6 +1120,18 @@
}
}
+ private boolean isDozeMode() {
+ IDreamManager dreamManager = getDreamManager();
+ try {
+ if (dreamManager != null && dreamManager.isDreaming()) {
+ return true;
+ }
+ } catch (RemoteException e) {
+ return false;
+ }
+ return false;
+ }
+
private void interceptPowerKeyUp(KeyEvent event, boolean interactive, boolean canceled) {
final boolean handled = canceled || mPowerKeyHandled;
mScreenshotChordPowerKeyTriggered = false;
@@ -1034,7 +1155,8 @@
Message msg = mHandler.obtainMessage(MSG_POWER_DELAYED_PRESS,
interactive ? 1 : 0, mPowerKeyPressCounter, eventTime);
msg.setAsynchronous(true);
- mHandler.sendMessageDelayed(msg, ViewConfiguration.getMultiPressTimeout());
+ mHandler.sendMessageDelayed(msg, (mTorchActionMode == 1)
+ ? TORCH_DOUBLE_TAP_DELAY : ViewConfiguration.getMultiPressTimeout());
return;
}
@@ -1058,6 +1180,11 @@
if (!mPowerKeyHandled) {
mPowerKeyHandled = true;
mHandler.removeMessages(MSG_POWER_LONG_PRESS);
+ // See if we deferred screen wake because long press power for torch is enabled
+ if (mResolvedLongPressOnPowerBehavior == LONG_PRESS_POWER_TORCH
+ && (!isScreenOn() || isDozeMode())) {
+ wakeUpFromPowerKey(SystemClock.uptimeMillis());
+ }
}
if (hasVeryLongPressOnPowerBehavior()) {
mHandler.removeMessages(MSG_POWER_VERY_LONG_PRESS);
@@ -1073,7 +1200,7 @@
}
private void powerPress(long eventTime, boolean interactive, int count) {
- if (mDefaultDisplayPolicy.isScreenOnEarly() && !mDefaultDisplayPolicy.isScreenOnFully()) {
+ if (!isDozeMode() && mDefaultDisplayPolicy.isScreenOnEarly() && !mDefaultDisplayPolicy.isScreenOnFully()) {
Slog.i(TAG, "Suppressed redundant power key press while "
+ "already in the process of turning the screen on.");
return;
@@ -1121,6 +1248,8 @@
break;
}
}
+ } else if ((mTorchActionMode == 1) && (!isScreenOn() || isDozeMode())) {
+ wakeUpFromPowerKey(eventTime);
}
}
@@ -1171,6 +1300,9 @@
private void powerMultiPressAction(long eventTime, boolean interactive, int behavior) {
switch (behavior) {
case MULTI_PRESS_POWER_NOTHING:
+ if ((mTorchActionMode == 1) && (!isScreenOn() || isDozeMode())) {
+ toggleFlashLight();
+ }
break;
case MULTI_PRESS_POWER_THEATER_MODE:
if (!isUserSetupComplete()) {
@@ -1214,14 +1346,14 @@
if (mTriplePressOnPowerBehavior != MULTI_PRESS_POWER_NOTHING) {
return 3;
}
- if (mDoublePressOnPowerBehavior != MULTI_PRESS_POWER_NOTHING) {
+ if (mDoublePressOnPowerBehavior != MULTI_PRESS_POWER_NOTHING || (mTorchActionMode == 1)) {
return 2;
}
return 1;
}
private void powerLongPress() {
- final int behavior = getResolvedLongPressOnPowerBehavior();
+ final int behavior = mResolvedLongPressOnPowerBehavior;
switch (behavior) {
case LONG_PRESS_POWER_NOTHING:
break;
@@ -1255,6 +1387,15 @@
final int powerKeyDeviceId = Integer.MIN_VALUE;
launchAssistAction(null, powerKeyDeviceId);
break;
+ case LONG_PRESS_POWER_TORCH:
+ mPowerKeyHandled = true;
+ // Toggle torch state asynchronously to help protect against
+ // a misbehaving cameraservice from blocking systemui.
+ mHandler.removeMessages(MSG_TOGGLE_TORCH);
+ Message msg = mHandler.obtainMessage(MSG_TOGGLE_TORCH);
+ msg.setAsynchronous(true);
+ msg.sendToTarget();
+ break;
}
}
@@ -1308,6 +1449,9 @@
if (FactoryTest.isLongPressOnPowerOffEnabled()) {
return LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM;
}
+ if ((mTorchActionMode == 2) && (!isScreenOn() || isDozeMode())) {
+ return LONG_PRESS_POWER_TORCH;
+ }
return mLongPressOnPowerBehavior;
}
@@ -1445,10 +1589,14 @@
}
void showGlobalActionsInternal() {
+ final boolean keyguardShowing = isKeyguardShowingAndNotOccluded();
+ if (keyguardShowing && isKeyguardSecure(mCurrentUserId) &&
+ mGlobalActionsOnLockDisable) {
+ return;
+ }
if (mGlobalActions == null) {
mGlobalActions = new GlobalActions(mContext, mWindowManagerFuncs);
}
- final boolean keyguardShowing = isKeyguardShowingAndNotOccluded();
mGlobalActions.showDialog(keyguardShowing, isDeviceProvisioned());
// since it took two seconds of long press to bring this up,
// poke the wake lock so they have some time to see the dialog.
@@ -1765,6 +1913,11 @@
mWakeOnBackKeyPress =
res.getBoolean(com.android.internal.R.bool.config_wakeOnBackKeyPress);
+ // Init alert slider
+ mHasAlertSlider = mContext.getResources().getBoolean(R.bool.config_hasAlertSlider)
+ && !TextUtils.isEmpty(mContext.getResources().getString(R.string.alert_slider_state_path))
+ && !TextUtils.isEmpty(mContext.getResources().getString(R.string.alert_slider_uevent_match_path));
+
// Init display burn-in protection
boolean burnInProtectionEnabled = context.getResources().getBoolean(
com.android.internal.R.bool.config_enableBurnInProtection);
@@ -1801,7 +1954,18 @@
}
mHandler = new PolicyHandler();
+ mOPGestures = new OPGesturesListener(context, new OPGesturesListener.Callbacks() {
+ @Override
+ public void onSwipeThreeFinger() {
+ mHandler.post(mScreenshotRunnable);
+ }
+ });
mWakeGestureListener = new MyWakeGestureListener(mContext, mHandler);
+ // only for hwkey devices
+ if (!mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_showNavigationBar)) {
+ mKeyHandler = new HardkeyActionHandler(mContext, mHandler);
+ }
mSettingsObserver = new SettingsObserver(mHandler);
mSettingsObserver.observe();
mShortcutManager = new ShortcutManager(context);
@@ -1950,6 +2114,7 @@
finishedGoingToSleep(WindowManagerPolicy.OFF_BECAUSE_OF_USER);
}
+
mWindowManagerInternal.registerAppTransitionListener(new AppTransitionListener() {
@Override
public int onAppTransitionStartingLocked(int transit, long duration,
@@ -1974,6 +2139,41 @@
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");
+ }
+ }
+
+ private void enableSwipeThreeFingerGesture(boolean enable){
+ if (enable) {
+ if (haveEnableGesture) return;
+ haveEnableGesture = true;
+ mWindowManagerFuncs.registerPointerEventListener(mOPGestures, DEFAULT_DISPLAY);
+ } else {
+ if (!haveEnableGesture) return;
+ haveEnableGesture = false;
+ mWindowManagerFuncs.unregisterPointerEventListener(mOPGestures, DEFAULT_DISPLAY);
+ }
}
/**
@@ -2034,6 +2234,18 @@
mRingerToggleChord = Settings.Secure.VOLUME_HUSH_OFF;
}
+ //Three Finger Gesture
+ boolean threeFingerGesture = Settings.System.getIntForUser(resolver,
+ Settings.System.THREE_FINGER_GESTURE, 0, UserHandle.USER_CURRENT) == 1;
+ enableSwipeThreeFingerGesture(threeFingerGesture);
+ // volume rocker wake
+ mVolumeRockerWake = Settings.System.getIntForUser(resolver,
+ Settings.System.VOLUME_ROCKER_WAKE, 0, UserHandle.USER_CURRENT) != 0;
+
+ // home wake button
+ mHomeWakeButton = Settings.System.getIntForUser(resolver,
+ Settings.System.HOME_WAKE_BUTTON, 0, UserHandle.USER_CURRENT) != 0;
+
// Configure wake gesture.
boolean wakeGestureEnabledSetting = Settings.Secure.getIntForUser(resolver,
Settings.Secure.WAKE_GESTURE_ENABLED, 0,
@@ -2062,6 +2274,15 @@
Settings.Global.POWER_BUTTON_VERY_LONG_PRESS,
mContext.getResources().getInteger(
com.android.internal.R.integer.config_veryLongPressOnPowerBehavior));
+ mTorchActionMode = Settings.Secure.getIntForUser(resolver,
+ Settings.Secure.TORCH_POWER_BUTTON_GESTURE, 0,
+ UserHandle.USER_CURRENT);
+ mVolumeMusicControl = Settings.System.getIntForUser(resolver,
+ Settings.System.VOLUME_BUTTON_MUSIC_CONTROL,
+ 0, UserHandle.USER_CURRENT) != 0;
+ mGlobalActionsOnLockDisable = Settings.System.getIntForUser(resolver,
+ Settings.System.LOCK_POWER_MENU_DISABLED, 1,
+ UserHandle.USER_CURRENT) != 0;
}
if (updateRotation) {
updateRotation(true);
@@ -2571,12 +2792,29 @@
final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
final boolean canceled = event.isCanceled();
final int displayId = event.getDisplayId();
+ final boolean longPress = (flags & KeyEvent.FLAG_LONG_PRESS) != 0;
+ final boolean virtualKey = event.getDeviceId() == KeyCharacterMap.VIRTUAL_KEYBOARD;
if (DEBUG_INPUT) {
Log.d(TAG, "interceptKeyTi keyCode=" + keyCode + " down=" + down + " repeatCount="
+ repeatCount + " keyguardOn=" + keyguardOn + " canceled=" + canceled);
}
+ // we only handle events from hardware key devices that originate from
+ // real button
+ // pushes. We ignore virtual key events as well since it didn't come
+ // from a hard key or
+ // it's the key handler synthesizing a back or menu key event for
+ // dispatch
+ // if keyguard is showing and secure, don't intercept and let aosp keycode
+ // implementation handle event
+ if (mKeyHandler != null && !keyguardOn && !virtualKey) {
+ boolean handled = mKeyHandler.handleKeyEvent(mKeyguardCandidate, keyCode, repeatCount, down, canceled,
+ longPress, keyguardOn);
+ if (handled)
+ return -1;
+ }
+
// If we think we might have a volume down & power key chord on the way
// but we're not sure, then tell the dispatcher to wait a little while and
// try again later before dispatching.
@@ -2961,6 +3199,11 @@
return -1;
}
+ // Specific device key handling
+ if (dispatchKeyToKeyHandlers(event)) {
+ return -1;
+ }
+
if (down) {
long shortcutCode = keyCode;
if (event.isCtrlPressed()) {
@@ -3056,7 +3299,7 @@
private void requestBugreportForTv() {
if ("1".equals(SystemProperties.get("ro.debuggable"))
|| Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) == 1) {
+ Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1) == 1) {
try {
if (!ActivityManager.getService().launchBugReportHandlerApp()) {
ActivityManager.getService().requestInteractiveBugReport();
@@ -3067,6 +3310,23 @@
}
}
+ 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
@@ -3591,6 +3851,10 @@
mDefaultDisplayPolicy.setHdmiPlugged(plugged, true /* force */);
}
+ private boolean isHwKeysDisabled() {
+ return mKeyHandler != null ? mKeyHandler.isHwKeysDisabled() : false;
+ }
+
// TODO(b/117479243): handle it in InputPolicy
/** {@inheritDoc} */
@Override
@@ -3623,9 +3887,12 @@
}
// Basic policy based on interactive state.
+ final boolean isVolumeRockerWake = !isScreenOn()
+ && mVolumeRockerWake
+ && (keyCode == KeyEvent.KEYCODE_VOLUME_UP || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN);
int result;
boolean isWakeKey = (policyFlags & WindowManagerPolicy.FLAG_WAKE) != 0
- || event.isWakeKey();
+ || event.isWakeKey() || isVolumeRockerWake;
if (interactive || (isInjected && !isWakeKey)) {
// When the device is interactive or the key is injected pass the
// key to the application.
@@ -3679,7 +3946,13 @@
boolean useHapticFeedback = down
&& (policyFlags & WindowManagerPolicy.FLAG_VIRTUAL) != 0
&& (!isNavBarVirtKey || mNavBarVirtualKeyHapticFeedbackEnabled)
- && event.getRepeatCount() == 0;
+ && event.getRepeatCount() == 0
+ && !isHwKeysDisabled();
+
+ // Specific device key handling
+ if (dispatchKeyToKeyHandlers(event)) {
+ return 0;
+ }
// Handle special keys.
switch (keyCode) {
@@ -3700,6 +3973,27 @@
case KeyEvent.KEYCODE_VOLUME_DOWN:
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_VOLUME_MUTE: {
+ if (mUseTvRouting) {
+ // On TVs volume keys never go to the foreground app
+ result &= ~ACTION_PASS_TO_USER;
+ }
+ if (!interactive && isWakeKey && down) {
+ mVolumeWakeActive = true;
+ break;
+ }
+ if (!down && mVolumeWakeActive) {
+ isWakeKey = false;
+ result &= ~ACTION_PASS_TO_USER;
+ mVolumeWakeActive = false;
+ break;
+ }
+ // we come back from a handled music control event - ignore the up event
+ if (!interactive && !down && mVolumeMusicControlActive) {
+ isWakeKey = false;
+ result &= ~ACTION_PASS_TO_USER;
+ mVolumeMusicControlActive = false;
+ break;
+ }
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
if (down) {
// Any activity on the vol down button stops the ringer toggle shortcut
@@ -3793,15 +4087,57 @@
// {@link interceptKeyBeforeDispatching()}.
result |= ACTION_PASS_TO_USER;
} else if ((result & ACTION_PASS_TO_USER) == 0) {
+ if (mLineageButtons.handleVolumeKey(event, interactive)) {
+ break;
+ }
+
// If we aren't passing to the user and no one else
// handled it send it to the session manager to
// figure out.
MediaSessionLegacyHelper.getHelper(mContext).sendVolumeKeyEvent(
event, AudioManager.USE_DEFAULT_STREAM_TYPE, true);
+
+ boolean notHandledMusicControl = false;
+ if (!interactive && mVolumeMusicControl && isMusicActive()) {
+ if (down) {
+ if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
+ scheduleLongPressKeyEvent(event, KeyEvent.KEYCODE_MEDIA_PREVIOUS);
+ break;
+ } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
+ scheduleLongPressKeyEvent(event, KeyEvent.KEYCODE_MEDIA_NEXT);
+ break;
+ }
+ } else {
+ mHandler.removeMessages(MSG_DISPATCH_VOLKEY_WITH_WAKE_LOCK);
+ notHandledMusicControl = true;
+ }
+ }
+ if (down || notHandledMusicControl) {
+ KeyEvent newEvent = event;
+ if (!down) {
+ // Rewrite the event to use key-down if required
+ newEvent = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
+ }
+ if (mUseTvRouting) {
+ dispatchDirectAudioEvent(newEvent);
+ } else {
+ // If we aren't passing to the user and no one else
+ // handled it send it to the session manager to
+ // figure out.
+ MediaSessionLegacyHelper.getHelper(mContext)
+ .sendVolumeKeyEvent(newEvent, AudioManager.USE_DEFAULT_STREAM_TYPE, true);
+ }
+ }
}
break;
}
+ case KeyEvent.KEYCODE_HOME:
+ if (down && !interactive && mHomeWakeButton) {
+ isWakeKey = true;
+ }
+ break;
+
case KeyEvent.KEYCODE_ENDCALL: {
result &= ~ACTION_PASS_TO_USER;
if (down) {
@@ -3843,6 +4179,11 @@
EventLogTags.writeInterceptPower(
KeyEvent.actionToString(event.getAction()),
mPowerKeyHandled ? 1 : 0, mPowerKeyPressCounter);
+ if ((mDefaultDisplayPolicy.getTopFullscreenOpaqueWindowStatePrivateFlags()
+ & WindowManager.LayoutParams.PRIVATE_FLAG_PREVENT_POWER_KEY) != 0
+ && mDefaultDisplayPolicy.isScreenOnFully()) {
+ return result;
+ }
// Any activity on the power button stops the accessibility shortcut
cancelPendingAccessibilityShortcutAction();
result &= ~ACTION_PASS_TO_USER;
@@ -4111,6 +4452,9 @@
switch (keyCode) {
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_VOLUME_DOWN:
+ if (mVolumeRockerWake) {
+ return true;
+ }
case KeyEvent.KEYCODE_VOLUME_MUTE:
return mDefaultDisplayPolicy.getDockMode() != Intent.EXTRA_DOCK_STATE_UNDOCKED;
@@ -4186,6 +4530,13 @@
return false;
}
+ final boolean isDozing = isDozeMode();
+
+ if ((keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP)
+ && isDozing) {
+ return false;
+ }
+
// Send events to keyguard while the screen is on and it's showing.
if (isKeyguardShowingAndNotOccluded() && !displayOff) {
return true;
@@ -4201,14 +4552,8 @@
if (isDefaultDisplay) {
// Send events to a dozing dream even if the screen is off since the dream
// is in control of the state of the screen.
- IDreamManager dreamManager = getDreamManager();
-
- try {
- if (dreamManager != null && dreamManager.isDreaming()) {
- return true;
- }
- } catch (RemoteException e) {
- Slog.e(TAG, "RemoteException when checking if dreaming", e);
+ if (isDozing) {
+ return true;
}
}
// Otherwise, consume events since the user can't see what is being
@@ -4794,6 +5139,11 @@
mVrManagerInternal.addPersistentVrModeStateListener(mPersistentVrModeListener);
}
+ if (mHasAlertSlider) {
+ mAlertSliderObserver = new AlertSliderObserver(mContext);
+ mAlertSliderObserver.startObserving(com.android.internal.R.string.alert_slider_uevent_match_path);
+ }
+
readCameraLensCoverState();
updateUiMode();
mDefaultDisplayRotation.updateOrientationListener();
@@ -4812,6 +5162,8 @@
}
}
+ mLineageButtons = new LineageButtons(mContext);
+
mAutofillManagerInternal = LocalServices.getService(AutofillManagerInternal.class);
}
@@ -5322,6 +5674,26 @@
}
@Override
+ public void sendCustomAction(Intent intent) {
+ String action = intent.getAction();
+ if (action != null) {
+ if (BlissUtils.INTENT_SCREENSHOT.equals(action)) {
+ mContext.enforceCallingOrSelfPermission(ACCESS_SURFACE_FLINGER,
+ TAG + "sendCustomAction permission denied");
+ mHandler.removeCallbacks(mScreenshotRunnable);
+ mScreenshotRunnable.setScreenshotType(TAKE_SCREENSHOT_FULLSCREEN);
+ mHandler.post(mScreenshotRunnable);
+ } else if (BlissUtils.INTENT_REGION_SCREENSHOT.equals(action)) {
+ mContext.enforceCallingOrSelfPermission(ACCESS_SURFACE_FLINGER,
+ TAG + "sendCustomAction permission denied");
+ mHandler.removeCallbacks(mScreenshotRunnable);
+ mScreenshotRunnable.setScreenshotType(TAKE_SCREENSHOT_SELECTED_REGION);
+ mHandler.post(mScreenshotRunnable);
+ }
+ }
+ }
+
+ @Override
public void setDismissImeOnBackKeyPressed(boolean newValue) {
mDismissImeOnBackKeyPressed = newValue;
}
@@ -5687,4 +6059,25 @@
}
}
+ /**
+ * @return Whether music is being played right now "locally" (e.g. on the device's speakers
+ * or wired headphones) or "remotely" (e.g. on a device using the Cast protocol and
+ * controlled by this device, or through remote submix).
+ */
+ private boolean isMusicActive() {
+ final AudioManager am = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE);
+ if (am == null) {
+ Log.w(TAG, "isMusicActive: couldn't get AudioManager reference");
+ return false;
+ }
+ return am.isMusicActive();
+ }
+
+ private void scheduleLongPressKeyEvent(KeyEvent origEvent, int keyCode) {
+ KeyEvent event = new KeyEvent(origEvent.getDownTime(), origEvent.getEventTime(),
+ origEvent.getAction(), keyCode, 0);
+ Message msg = mHandler.obtainMessage(MSG_DISPATCH_VOLKEY_WITH_WAKE_LOCK, event);
+ msg.setAsynchronous(true);
+ mHandler.sendMessageDelayed(msg, ViewConfiguration.getLongPressTimeout());
+ }
}
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index b9431a6..d40526a 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -70,6 +70,7 @@
import android.annotation.Nullable;
import android.app.WindowConfiguration;
import android.content.Context;
+import android.content.Intent;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.graphics.Rect;
@@ -1468,4 +1469,9 @@
* @return whether the value was changed.
*/
boolean setAodShowing(boolean aodShowing);
+
+ /**
+ * Send some ActionHandler commands to WindowManager.
+ */
+ public void sendCustomAction(Intent intent);
}
diff --git a/services/core/java/com/android/server/policy/WindowOrientationListener.java b/services/core/java/com/android/server/policy/WindowOrientationListener.java
index 0157706..235c419 100644
--- a/services/core/java/com/android/server/policy/WindowOrientationListener.java
+++ b/services/core/java/com/android/server/policy/WindowOrientationListener.java
@@ -59,6 +59,8 @@
private boolean mEnabled;
private int mRate;
private String mSensorType;
+ private boolean mUseDefaultBatchingForAccel;
+ private boolean mUseSystemClockforRotationSensor;
private Sensor mSensor;
private OrientationJudge mOrientationJudge;
private int mCurrentRotation = -1;
@@ -114,6 +116,12 @@
mSensor = nonWakeUpDeviceOrientationSensor;
}
+ mUseDefaultBatchingForAccel = context.getResources().getBoolean(
+ com.android.internal.R.bool.config_useDefaultBatchingForAccel);
+
+ mUseSystemClockforRotationSensor = context.getResources().getBoolean(
+ com.android.internal.R.bool.config_useSystemClockforRotationSensor);
+
if (mSensor != null) {
mOrientationJudge = new OrientationSensorJudge();
}
@@ -157,7 +165,7 @@
+ clearCurrentRotation);
}
mOrientationJudge.resetLocked(clearCurrentRotation);
- if (mSensor.getType() == Sensor.TYPE_ACCELEROMETER) {
+ if (mSensor.getType() == Sensor.TYPE_ACCELEROMETER && mUseDefaultBatchingForAccel) {
mSensorManager.registerListener(
mOrientationJudge, mSensor, mRate, DEFAULT_BATCH_LATENCY, mHandler);
} else {
@@ -400,22 +408,22 @@
// the low-pass filter already suppresses most of the noise so we're really just
// looking for quick confirmation that the last few samples are in agreement as to
// the desired orientation.
- private static final long PROPOSAL_SETTLE_TIME_NANOS = 40 * NANOS_PER_MS;
+ private static final long PROPOSAL_SETTLE_TIME_NANOS = 25 * NANOS_PER_MS;
// The minimum amount of time that must have elapsed since the device last exited
// the flat state (time since it was picked up) before the proposed rotation
// can change.
- private static final long PROPOSAL_MIN_TIME_SINCE_FLAT_ENDED_NANOS = 500 * NANOS_PER_MS;
+ private static final long PROPOSAL_MIN_TIME_SINCE_FLAT_ENDED_NANOS = 250 * NANOS_PER_MS;
// The minimum amount of time that must have elapsed since the device stopped
// swinging (time since device appeared to be in the process of being put down
// or put away into a pocket) before the proposed rotation can change.
- private static final long PROPOSAL_MIN_TIME_SINCE_SWING_ENDED_NANOS = 300 * NANOS_PER_MS;
+ private static final long PROPOSAL_MIN_TIME_SINCE_SWING_ENDED_NANOS = 150 * NANOS_PER_MS;
// The minimum amount of time that must have elapsed since the device stopped
// undergoing external acceleration before the proposed rotation can change.
private static final long PROPOSAL_MIN_TIME_SINCE_ACCELERATION_ENDED_NANOS =
- 500 * NANOS_PER_MS;
+ 250 * NANOS_PER_MS;
// If the tilt angle remains greater than the specified angle for a minimum of
// the specified time, then the device is deemed to be lying flat
@@ -645,7 +653,8 @@
// Reset the orientation listener state if the samples are too far apart in time
// or when we see values of (0, 0, 0) which indicates that we polled the
// accelerometer too soon after turning it on and we don't have any data yet.
- final long now = event.timestamp;
+ final long now = mUseSystemClockforRotationSensor
+ ? SystemClock.elapsedRealtimeNanos() : event.timestamp;
final long then = mLastFilteredTimestampNanos;
final float timeDeltaMS = (now - then) * 0.000001f;
final boolean skipSample;
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index dee604a..b8a7a69 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -141,8 +141,10 @@
// Message: Sent when an attentive timeout occurs to update the power state.
private static final int MSG_ATTENTIVE_TIMEOUT = 5;
+ private static final int MSG_BUTTON_TIMEOUT = 6;
+
// Dirty bit: mWakeLocks changed
- private static final int DIRTY_WAKE_LOCKS = 1 << 0;
+ protected static final int DIRTY_WAKE_LOCKS = 1 << 0;
// Dirty bit: mWakefulness changed
private static final int DIRTY_WAKEFULNESS = 1 << 1;
// Dirty bit: user activity was poked or may have timed out
@@ -275,7 +277,7 @@
// A bitfield that indicates what parts of the power state have
// changed and need to be recalculated.
- private int mDirty;
+ protected int mDirty;
// Indicates whether the device is awake or asleep or somewhere in between.
// This is distinct from the screen power state, which is managed separately.
@@ -295,7 +297,7 @@
private final ArrayList<SuspendBlocker> mSuspendBlockers = new ArrayList<SuspendBlocker>();
// Table of all wake locks acquired by applications.
- private final ArrayList<WakeLock> mWakeLocks = new ArrayList<WakeLock>();
+ protected final ArrayList<WakeLock> mWakeLocks = new ArrayList<WakeLock>();
// A bitfield that summarizes the state of all active wakelocks.
private int mWakeLockSummary;
@@ -486,6 +488,9 @@
// A bitfield of battery conditions under which to make the screen stay on.
private int mStayOnWhilePluggedInSetting;
+ // True if the device should wake up when plugged or unplugged
+ private int mWakeUpWhenPluggedOrUnpluggedSetting;
+
// True if the device should stay on.
private boolean mStayOn;
@@ -566,6 +571,8 @@
// Some uids have actually changed while mUidsChanging was true.
private boolean mUidsChanged;
+ private QCNsrmPowerExtension qcNsrmPowExt;
+
// True if theater mode is enabled
private boolean mTheaterModeEnabled;
@@ -632,6 +639,23 @@
}
}
+ // button brightness suppport enablement
+ private boolean mButtonBrightnessSupport = false;
+ private int mCurrentButtonBrightness = 0;
+ // value to use in manual mode
+ // if -1 screen brightness will be used
+ private int mCustomButtonBrightness = -1;
+ // always use screen brightness also for buttons
+ private boolean mButtonUseScreenBrightness = true;
+ // overrule and disable brightness for buttons
+ private boolean mButtonBacklightEnable = true;
+ // button on touch
+ private boolean mButtonBacklightOnTouchOnly;
+ // timeout for button backlight automatic turning off
+ private int mButtonTimeout;
+ private boolean mButtonTimeoutEnabled;
+ private int mEvent;
+
/**
* All times are in milliseconds. These constants are kept synchronized with the system
* global Settings. Any access to this class or its fields should be done while
@@ -982,6 +1006,7 @@
mScreenBrightnessDefaultVr = vrDef;
}
+ qcNsrmPowExt = new QCNsrmPowerExtension(this);
synchronized (mLock) {
mWakeLockSuspendBlocker =
mInjector.createSuspendBlocker(this, "PowerManagerService.WakeLocks");
@@ -1141,6 +1166,9 @@
resolver.registerContentObserver(Settings.Global.getUriFor(
Settings.Global.DEVICE_DEMO_MODE),
false, mSettingsObserver, UserHandle.USER_SYSTEM);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.WAKE_WHEN_PLUGGED_OR_UNPLUGGED),
+ false, mSettingsObserver, UserHandle.USER_ALL);
IVrManager vrManager = IVrManager.Stub.asInterface(getBinderService(Context.VR_SERVICE));
if (vrManager != null) {
try {
@@ -1168,6 +1196,27 @@
filter = new IntentFilter();
filter.addAction(Intent.ACTION_DOCK_EVENT);
mContext.registerReceiver(new DockReceiver(), filter, null, mHandler);
+
+ if (mButtonBrightnessSupport){
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.CUSTOM_BUTTON_BRIGHTNESS),
+ false, mSettingsObserver, UserHandle.USER_ALL);
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.CUSTOM_BUTTON_USE_SCREEN_BRIGHTNESS),
+ false, mSettingsObserver, UserHandle.USER_ALL);
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.BUTTON_BACKLIGHT_ENABLE),
+ false, mSettingsObserver, UserHandle.USER_ALL);
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.HARDWARE_KEYS_DISABLE),
+ false, mSettingsObserver, UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.BUTTON_BACKLIGHT_TIMEOUT),
+ false, mSettingsObserver, UserHandle.USER_ALL);
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.BUTTON_BACKLIGHT_ON_TOUCH_ONLY),
+ false, mSettingsObserver, UserHandle.USER_ALL);
+ }
}
@VisibleForTesting
@@ -1214,6 +1263,10 @@
com.android.internal.R.fraction.config_maximumScreenDimRatio, 1, 1);
mSupportsDoubleTapWakeConfig = resources.getBoolean(
com.android.internal.R.bool.config_supportDoubleTapWake);
+ mButtonBrightnessSupport = resources.getBoolean(
+ com.android.internal.R.bool.config_button_brightness_support);
+ mCustomButtonBrightness = resources.getInteger(
+ com.android.internal.R.integer.config_button_brightness_default);
}
private void updateSettingsLocked() {
@@ -1245,6 +1298,9 @@
mTheaterModeEnabled = Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.THEATER_MODE_ON, 0) == 1;
mAlwaysOnEnabled = mAmbientDisplayConfiguration.alwaysOnEnabled(UserHandle.USER_CURRENT);
+ mWakeUpWhenPluggedOrUnpluggedSetting = Settings.System.getIntForUser(resolver,
+ Settings.System.WAKE_WHEN_PLUGGED_OR_UNPLUGGED, 1,
+ UserHandle.USER_CURRENT);
if (mSupportsDoubleTapWakeConfig) {
boolean doubleTapWakeEnabled = Settings.Secure.getIntForUser(resolver,
@@ -1267,6 +1323,7 @@
Settings.System.SCREEN_BRIGHTNESS_MODE,
Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, UserHandle.USER_CURRENT);
+ updateButtonLightSettings();
mDirty |= DIRTY_SETTINGS;
}
@@ -1313,6 +1370,7 @@
}
mWakeLocks.add(wakeLock);
setWakeLockDisabledStateLocked(wakeLock);
+ qcNsrmPowExt.checkPmsBlockedWakelocks(uid, pid, flags, tag, wakeLock);
notifyAcquire = true;
}
@@ -1487,7 +1545,7 @@
return -1;
}
- private void notifyWakeLockAcquiredLocked(WakeLock wakeLock) {
+ protected void notifyWakeLockAcquiredLocked(WakeLock wakeLock) {
if (mSystemReady && !wakeLock.mDisabled) {
wakeLock.mNotifiedAcquired = true;
mNotifier.onWakeLockAcquired(wakeLock.mFlags, wakeLock.mTag, wakeLock.mPackageName,
@@ -1543,7 +1601,7 @@
}
}
- private void notifyWakeLockReleasedLocked(WakeLock wakeLock) {
+ protected void notifyWakeLockReleasedLocked(WakeLock wakeLock) {
if (mSystemReady && wakeLock.mNotifiedAcquired) {
wakeLock.mNotifiedAcquired = false;
wakeLock.mAcquireTime = 0;
@@ -1611,6 +1669,7 @@
Trace.traceBegin(Trace.TRACE_TAG_POWER, "userActivity");
try {
+ mEvent = event;
if (eventTime > mLastInteractivePowerHintTime) {
powerHintInternal(PowerHint.INTERACTION, 0);
mLastInteractivePowerHintTime = eventTime;
@@ -1906,7 +1965,7 @@
* each time something important changes, and ensure that we do it the same
* way each time. The point is to gather all of the transition logic here.
*/
- private void updatePowerStateLocked() {
+ protected void updatePowerStateLocked() {
if (!mSystemReady || mDirty == 0) {
return;
}
@@ -2046,7 +2105,7 @@
private boolean shouldWakeUpWhenPluggedOrUnpluggedLocked(
boolean wasPowered, int oldPlugType, boolean dockedOnWirelessCharger) {
// Don't wake when powered unless configured to do so.
- if (!mWakeUpWhenPluggedOrUnpluggedConfig) {
+ if (mWakeUpWhenPluggedOrUnpluggedSetting == 0) {
return false;
}
@@ -2272,6 +2331,14 @@
| DIRTY_WAKEFULNESS | DIRTY_SETTINGS)) != 0) {
mHandler.removeMessages(MSG_USER_ACTIVITY_TIMEOUT);
+ boolean wakeLocksValue = (dirty & DIRTY_WAKE_LOCKS) != 0;
+ boolean userActivityValue = (dirty & DIRTY_USER_ACTIVITY) != 0;
+ boolean wakefullnessValue = (dirty & DIRTY_WAKEFULNESS) != 0;
+ boolean settingsValue = (dirty & DIRTY_SETTINGS) != 0;
+
+ if (DEBUG) {
+ Slog.d(TAG, "DIRTY_WAKE_LOCKS=" + wakeLocksValue + " DIRTY_USER_ACTIVITY=" + userActivityValue + " DIRTY_WAKEFULNESS=" + wakefullnessValue + " DIRTY_SETTINGS=" + settingsValue);
+ }
long nextTimeout = 0;
if (getWakefulnessLocked() == WAKEFULNESS_AWAKE
|| getWakefulnessLocked() == WAKEFULNESS_DREAMING
@@ -2285,10 +2352,20 @@
final long nextProfileTimeout = getNextProfileTimeoutLocked(now);
mUserActivitySummary = 0;
- if (mLastUserActivityTime >= mLastWakeTime) {
+ if (getWakefulnessLocked() == WAKEFULNESS_AWAKE && mLastUserActivityTime >= mLastWakeTime) {
nextTimeout = mLastUserActivityTime
+ screenOffTimeout - screenDimDuration;
if (now < nextTimeout) {
+ if (mButtonTimeoutEnabled && (userActivityValue || settingsValue)){
+ final boolean buttonPressed = mEvent == PowerManager.USER_ACTIVITY_EVENT_BUTTON;
+ if (mButtonBacklightOnTouchOnly) {
+ if (buttonPressed) {
+ triggerButtonTimeoutEvent(now);
+ }
+ } else {
+ triggerButtonTimeoutEvent(now);
+ }
+ }
mUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT;
} else {
nextTimeout = mLastUserActivityTime + screenOffTimeout;
@@ -2877,6 +2954,12 @@
PowerManager.BRIGHTNESS_INVALID_FLOAT;
}
+ if (mButtonBrightnessSupport) {
+ if ((dirty & ( DIRTY_USER_ACTIVITY | DIRTY_SETTINGS | DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED)) != 0) {
+ updateButtonLight(false);
+ }
+ }
+
mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest,
mRequestWaitForNegativeProximity);
mRequestWaitForNegativeProximity = false;
@@ -3710,6 +3793,12 @@
}
}
+ private void setTemporaryButtonBrightnessSettingOverrideInternal(int brightness) {
+ if (mButtonBrightnessSupport){
+ mLightsManager.getLight(LightsManager.LIGHT_ID_BUTTONS).setBrightness(brightnessIntToFloat(brightness));
+ }
+ }
+
/**
* Low-level function turn the device off immediately, without trying
* to be clean. Most people should use {@link ShutdownThread} for a clean shutdown.
@@ -4435,6 +4524,12 @@
case MSG_ATTENTIVE_TIMEOUT:
handleAttentiveTimeout();
break;
+ case MSG_BUTTON_TIMEOUT:
+ if (DEBUG) {
+ Slog.d(TAG, "button timeout triggered");
+ }
+ updateButtonLight(true);
+ break;
}
return true;
@@ -4444,7 +4539,7 @@
/**
* Represents a wake lock that has been acquired by an application.
*/
- /* package */ final class WakeLock implements IBinder.DeathRecipient {
+ protected final class WakeLock implements IBinder.DeathRecipient {
public final IBinder mLock;
public int mFlags;
public String mTag;
@@ -5397,6 +5492,40 @@
Binder.restoreCallingIdentity(ident);
}
}
+
+ @Override
+ /* updates the blocked uids, so if a wake lock is acquired for it
+ * can be released.
+ */
+ public void updateBlockedUids(int uid, boolean isBlocked) {
+ synchronized(mLock) {
+ qcNsrmPowExt.processPmsBlockedUid(uid, isBlocked,
+ mWakeLocks);
+ }
+ }
+
+ /**
+ * Used by the settings application and brightness control widgets to
+ * temporarily override the current button brightness setting so that the
+ * user can observe the effect of an intended settings change without applying
+ * it immediately.
+ *
+ * The override will be canceled when the setting value is next updated.
+ *
+ * @param brightness The overridden brightness.
+ */
+ @Override // Binder call
+ public void setTemporaryButtonBrightnessSettingOverride(int brightness) {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.DEVICE_POWER, null);
+
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ setTemporaryButtonBrightnessSettingOverrideInternal(brightness);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
}
@VisibleForTesting
@@ -5607,4 +5736,114 @@
return interceptPowerKeyDownInternal(event);
}
}
+
+ private void updateButtonLightSettings() {
+ final ContentResolver resolver = mContext.getContentResolver();
+ if (mButtonBrightnessSupport){
+ mCustomButtonBrightness = Settings.System.getIntForUser(
+ mContext.getContentResolver(), Settings.System.CUSTOM_BUTTON_BRIGHTNESS,
+ mCustomButtonBrightness, UserHandle.USER_CURRENT);
+ mButtonUseScreenBrightness = Settings.System.getIntForUser(
+ mContext.getContentResolver(), Settings.System.CUSTOM_BUTTON_USE_SCREEN_BRIGHTNESS,
+ 0, UserHandle.USER_CURRENT) != 0;
+ mButtonBacklightEnable = Settings.System.getIntForUser(
+ mContext.getContentResolver(), Settings.System.BUTTON_BACKLIGHT_ENABLE,
+ 1, UserHandle.USER_CURRENT) != 0;
+
+ boolean hardwareKeysDisable = Settings.System.getIntForUser(
+ mContext.getContentResolver(), Settings.System.HARDWARE_KEYS_DISABLE,
+ 0, UserHandle.USER_CURRENT) != 0;
+
+ mButtonBacklightEnable = mButtonBacklightEnable && !hardwareKeysDisable;
+ mButtonBacklightOnTouchOnly = Settings.System.getIntForUser(
+ mContext.getContentResolver(), Settings.System.BUTTON_BACKLIGHT_ON_TOUCH_ONLY,
+ 0, UserHandle.USER_CURRENT) != 0;
+ mButtonTimeout = Settings.System.getIntForUser(resolver,
+ Settings.System.BUTTON_BACKLIGHT_TIMEOUT,
+ 0, UserHandle.USER_CURRENT) * 1000;
+
+ mButtonTimeoutEnabled = mButtonTimeout != 0 && mButtonBacklightEnable;
+ // prevent remaining timout to be triggered
+ mHandler.removeMessages(MSG_BUTTON_TIMEOUT);
+ // force it off - it will come back if needed later
+ updateButtonLight(true);
+ }
+ }
+
+ private void updateButtonLight(boolean timeoutEvent) {
+ if (mDisplayPowerRequest == null){
+ return;
+ }
+
+ if (!mButtonBacklightEnable){
+ mCurrentButtonBrightness = 0;
+ mLightsManager.getLight(LightsManager.LIGHT_ID_BUTTONS).setBrightness(brightnessIntToFloat(mCurrentButtonBrightness));
+ return;
+ }
+
+ if (timeoutEvent) {
+ if (DEBUG) {
+ Slog.d(TAG, "button timeout handled");
+ }
+ mCurrentButtonBrightness = 0;
+ mLightsManager.getLight(LightsManager.LIGHT_ID_BUTTONS).setBrightness(brightnessIntToFloat(mCurrentButtonBrightness));
+ return;
+ }
+
+ final boolean buttonPressed = mEvent == PowerManager.USER_ACTIVITY_EVENT_BUTTON;
+ boolean buttonlight_on = mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_BRIGHT;
+ int currentButtonBrightness = 0;
+
+ if (buttonlight_on){
+ if (mButtonBacklightOnTouchOnly && mButtonTimeoutEnabled) {
+ if (buttonPressed) {
+ currentButtonBrightness = calcButtonLight();
+ } else {
+ currentButtonBrightness = mCurrentButtonBrightness;
+ }
+ } else {
+ currentButtonBrightness = calcButtonLight();
+ }
+ } else {
+ currentButtonBrightness = 0;
+ }
+ mCurrentButtonBrightness = currentButtonBrightness;
+
+ if (DEBUG) {
+ Slog.d(TAG, "mCurrentButtonBrightness="+mCurrentButtonBrightness);
+ }
+
+ mLightsManager.getLight(LightsManager.LIGHT_ID_BUTTONS).setBrightness(brightnessIntToFloat(mCurrentButtonBrightness));
+ }
+
+ private int calcButtonLight() {
+ int buttonBrightness = 0;
+
+ if (mCustomButtonBrightness == -1 || mButtonUseScreenBrightness){
+ // use same value as screen
+ buttonBrightness = Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.SCREEN_BRIGHTNESS, 60);
+ } else {
+ buttonBrightness = mCustomButtonBrightness;
+ }
+ return buttonBrightness;
+ }
+
+ private void triggerButtonTimeoutEvent(long now) {
+ mHandler.removeMessages(MSG_BUTTON_TIMEOUT);
+ if (DEBUG) {
+ Slog.d(TAG, "button timeout set to " + (now + mButtonTimeout));
+ }
+ Message msg = mHandler.obtainMessage(MSG_BUTTON_TIMEOUT);
+ msg.setAsynchronous(true);
+ mHandler.sendMessageAtTime(msg, now + mButtonTimeout);
+ }
+
+
+ private float brightnessIntToFloat(int brightness) {
+ return BrightnessSynchronizer.brightnessIntToFloat(
+ brightness,
+ PowerManager.BRIGHTNESS_OFF + 1, PowerManager.BRIGHTNESS_ON,
+ PowerManager.BRIGHTNESS_MIN, PowerManager.BRIGHTNESS_MAX);
+ }
}
diff --git a/services/core/java/com/android/server/power/QCNsrmPowerExtension.java b/services/core/java/com/android/server/power/QCNsrmPowerExtension.java
new file mode 100644
index 0000000..70425ea
--- /dev/null
+++ b/services/core/java/com/android/server/power/QCNsrmPowerExtension.java
@@ -0,0 +1,159 @@
+/*
+ *Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *
+ *Redistribution and use in source and binary forms, with or without
+ *modification, are permitted provided that the following conditions are
+ *met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ *THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ *WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ *ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ *BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ *CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ *WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ *OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ *IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.android.server.power;
+
+import java.util.ArrayList;
+
+import android.os.Binder;
+import android.os.PowerManager;
+import android.os.Process;
+import android.util.Slog;
+
+public final class QCNsrmPowerExtension {
+ static final String TAG = "QCNsrmPowerExtn";
+ static final boolean localLOGV = false;
+ private PowerManagerService pmHandle;
+
+ //track the blocked uids in PowerManagerService.
+ private final ArrayList<Integer> mPmsBlockedUids = new ArrayList<Integer>();
+
+ public QCNsrmPowerExtension (PowerManagerService handle) {
+ pmHandle = handle ;
+ }
+
+ protected void checkPmsBlockedWakelocks (
+ int uid, int pid, int flags,
+ String tag, PowerManagerService.WakeLock pMwakeLock
+ ) {
+ if(mPmsBlockedUids.contains(new Integer(uid)) && uid != Process.myUid()) {
+ // wakelock acquisition for blocked uid, disable it.
+ if (localLOGV) {
+ Slog.d(TAG, "uid is blocked disabling wakeLock flags=0x" +
+ Integer.toHexString(flags) + " tag=" + tag + " uid=" +
+ uid + " pid =" + pid);
+ }
+ updatePmsBlockedWakelock(pMwakeLock, true);
+ }
+ }
+
+ private boolean checkWorkSourceObjectId (
+ int uid, PowerManagerService.WakeLock wl
+ ) {
+ try {
+ for (int index = 0; index < wl.mWorkSource.size(); index++) {
+ if (uid == wl.mWorkSource.get(index)) {
+ if (localLOGV) Slog.v(TAG, "WS uid matched");
+ return true;
+ }
+ }
+ }
+ catch (Exception e) {
+ return false;
+ }
+ return false;
+ }
+
+ protected boolean processPmsBlockedUid (
+ int uid, boolean isBlocked,
+ ArrayList<PowerManagerService.WakeLock> mWakeLocks
+ ) {
+ boolean changed = false;
+ if (updatePmsBlockedUidAllowed(uid, isBlocked))
+ return changed;
+
+ for (int index = 0; index < mWakeLocks.size(); index++) {
+ PowerManagerService.WakeLock wl = mWakeLocks.get(index);
+ if(wl != null) {
+ // update the wakelock for the blocked uid
+ if ((wl.mOwnerUid == uid || checkWorkSourceObjectId(uid, wl))
+ || (wl.mTag.startsWith("*sync*") && wl.mOwnerUid ==
+ Process.SYSTEM_UID)) {
+ if(updatePmsBlockedWakelock(wl, isBlocked)) {
+ changed = true;
+ }
+ }
+ }
+ }
+ if(changed) {
+ pmHandle.mDirty |= pmHandle.DIRTY_WAKE_LOCKS;
+ pmHandle.updatePowerStateLocked();
+ }
+ return changed;
+ }
+
+ protected boolean updatePmsBlockedUidAllowed (
+ int uid, boolean isBlocked
+ ) {
+ if (localLOGV) Slog.v(TAG, "updateBlockedUids: uid = " + uid +
+ "isBlocked = " + isBlocked);
+ if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+ if (localLOGV) Slog.v(TAG, "UpdateBlockedUids is not allowed");
+ return true;
+ }
+ updatePmsBlockedUids(uid, isBlocked);
+ return false;
+ }
+
+ private void updatePmsBlockedUids (int uid, boolean isBlocked) {
+ if(isBlocked) {
+ if (localLOGV) Slog.v(TAG, "adding powerMgr mPmBlockedUids "+
+ "with uid "+ uid);
+ mPmsBlockedUids.add(new Integer(uid));
+ }
+ else {
+ if (localLOGV) Slog.v(TAG, "clearing powerMgr mPmBlockedUids ");
+ mPmsBlockedUids.clear();
+ }
+ }
+
+ private boolean updatePmsBlockedWakelock (
+ PowerManagerService.WakeLock wakeLock, boolean update
+ ) {
+ if (wakeLock != null && ((wakeLock.mFlags &
+ PowerManager.WAKE_LOCK_LEVEL_MASK
+ ) == PowerManager.PARTIAL_WAKE_LOCK )) {
+ if (wakeLock.mDisabled != update && pmHandle != null) {
+ wakeLock.mDisabled = update;
+ if (localLOGV) Slog.v(TAG, "updatePmsBlockWakelock pmHandle "+pmHandle);
+ if (wakeLock.mDisabled) {
+ // This wake lock is no longer being respected.
+ pmHandle.notifyWakeLockReleasedLocked(wakeLock);
+ } else {
+ pmHandle.notifyWakeLockAcquiredLocked(wakeLock);
+ }
+ return true;
+ }
+ else {
+ if (localLOGV) Slog.v(TAG, "updatePmsBlockWakelock pmHandle "+pmHandle );
+ }
+ }
+ return false;
+ }
+}
diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java
index bc722f1..a359087 100644
--- a/services/core/java/com/android/server/power/ShutdownThread.java
+++ b/services/core/java/com/android/server/power/ShutdownThread.java
@@ -76,7 +76,7 @@
private static final int MOUNT_SERVICE_STOP_PERCENT = 20;
// length of vibration before shutting down
- private static final int SHUTDOWN_VIBRATE_MS = 500;
+ private static final int SHUTDOWN_VIBRATE_MS = 250;
// state tracking
private static final Object sIsStartedGuard = new Object();
@@ -318,12 +318,30 @@
pd.setMessage(context.getText(com.android.internal.R.string.shutdown_progress));
pd.setIndeterminate(true);
} else {
+ if (showSysuiReboot()) {
+ return null;
+ }
// Factory reset path. Set the dialog message accordingly.
- pd.setTitle(context.getText(com.android.internal.R.string.reboot_to_reset_title));
+ pd.setTitle(context.getText(com.android.internal.R.string.reboot_to_recovery_title));
pd.setMessage(context.getText(
- com.android.internal.R.string.reboot_to_reset_message));
+ com.android.internal.R.string.reboot_to_recovery_message));
pd.setIndeterminate(true);
}
+ } else if (mReason != null && mReason.equals(PowerManager.REBOOT_BOOTLOADER)) {
+ if (showSysuiReboot()) {
+ return null;
+ }
+ pd.setTitle(context.getText(com.android.internal.R.string.reboot_to_bootloader_title));
+ pd.setMessage(context.getText(
+ com.android.internal.R.string.reboot_to_bootloader_message));
+ pd.setIndeterminate(true);
+ } else if (mReboot) {
+ if (showSysuiReboot()) {
+ return null;
+ }
+ pd.setTitle(context.getText(com.android.internal.R.string.reboot_title));
+ pd.setMessage(context.getText(com.android.internal.R.string.reboot_message));
+ pd.setIndeterminate(true);
} else {
if (showSysuiReboot()) {
return null;
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 39e839d..4d03e0a 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -588,6 +588,18 @@
}
@Override
+ public void toggleSettingsPanel() {
+ enforceExpandStatusBar();
+
+ if (mBar != null) {
+ try {
+ mBar.toggleSettingsPanel();
+ } catch (RemoteException ex) {
+ }
+ }
+ }
+
+ @Override
public void expandSettingsPanel(String subPanel) {
enforceExpandStatusBar();
@@ -599,6 +611,66 @@
}
}
+ @Override
+ public void toggleRecentApps() {
+ enforceStatusBarService();
+
+ if (mBar != null) {
+ try {
+ mBar.toggleRecentApps();
+ } catch (RemoteException ex) {
+ }
+ }
+ }
+
+ @Override
+ public void toggleSplitScreen() {
+ enforceStatusBarService();
+
+ if (mBar != null) {
+ try {
+ mBar.toggleSplitScreen();
+ } catch (RemoteException ex) {
+ }
+ }
+ }
+
+ @Override
+ public void preloadRecentApps() {
+ enforceStatusBarService();
+
+ if (mBar != null) {
+ try {
+ mBar.preloadRecentApps();
+ } catch (RemoteException ex) {
+ }
+ }
+ }
+
+ @Override
+ public void cancelPreloadRecentApps() {
+ enforceStatusBarService();
+
+ if (mBar != null) {
+ try {
+ mBar.cancelPreloadRecentApps();
+ } catch (RemoteException ex) {
+ }
+ }
+ }
+
+ @Override
+ public void startAssist(Bundle args) {
+ enforceStatusBarService();
+
+ if (mBar != null) {
+ try {
+ mBar.startAssist(args);
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
public void addTile(ComponentName component) {
enforceStatusBarOrShell();
@@ -747,8 +819,50 @@
return mTracingEnabled;
}
+ @Override
+ public void showInDisplayFingerprintView() {
+ if (mBar != null) {
+ try {
+ mBar.showInDisplayFingerprintView();
+ } catch (RemoteException ex) {
+ // do nothing
+ }
+ }
+ }
+
+ @Override
+ public void hideInDisplayFingerprintView() {
+ if (mBar != null) {
+ try {
+ mBar.hideInDisplayFingerprintView();
+ } catch (RemoteException ex) {
+ // do nothing
+ }
+ }
+ }
+
// TODO(b/117478341): make it aware of multi-display if needed.
@Override
+ public void toggleCameraFlash(boolean proximityCheck) {
+ if (mBar != null) {
+ try {
+ mBar.toggleCameraFlash(proximityCheck);
+ } catch (RemoteException ex) {
+ }
+ }
+ }
+
+ @Override
+ public void triggerElmyraAction(String action) {
+ if (mBar != null) {
+ try {
+ mBar.triggerElmyraAction(action);
+ } catch (RemoteException ex) {
+ }
+ }
+ }
+
+ @Override
public void disable(int what, IBinder token, String pkg) {
disableForUser(what, token, pkg, mCurrentUserId);
}
@@ -1206,6 +1320,24 @@
}
}
+ /**
+ * Allows the status bar to reboot the device to recovery or bootloader.
+ */
+ @Override
+ public void advancedReboot(String mode) {
+ enforceStatusBarService();
+ long identity = Binder.clearCallingIdentity();
+ try {
+ mHandler.post(() -> {
+ // ShutdownThread displays UI, so give it a UI context.
+ ShutdownThread.reboot(getUiContext(),
+ mode, false/*don't ask for confirmation*/);
+ });
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
@Override
public void onGlobalActionsShown() {
enforceStatusBarService();
diff --git a/services/core/java/com/android/server/webkit/SystemImpl.java b/services/core/java/com/android/server/webkit/SystemImpl.java
index 2018940..39f25d4 100644
--- a/services/core/java/com/android/server/webkit/SystemImpl.java
+++ b/services/core/java/com/android/server/webkit/SystemImpl.java
@@ -232,7 +232,7 @@
@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/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index dc4caf8..741cad3 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -749,6 +749,12 @@
}
};
+ private final float mFullScreenAspectRatio = Resources.getSystem().getFloat(
+ com.android.internal.R.dimen.config_screenAspectRatio);
+
+ private final boolean higherAspectRatio = Resources.getSystem().getBoolean(
+ com.android.internal.R.bool.config_haveHigherAspectRatioScreen);
+
private static String startingWindowStateToString(int state) {
switch (state) {
case STARTING_WINDOW_NOT_SHOWN:
@@ -6401,10 +6407,14 @@
// The rest of the condition is that only one side is smaller than the parent, but it still
// needs to exclude the cases where the size is limited by the fixed aspect ratio.
- if (info.maxAspectRatio > 0) {
+ float maxAspectRatio = (higherAspectRatio && info.applicationInfo.targetSdkVersion
+ < android.os.Build.VERSION_CODES.O) ? mFullScreenAspectRatio
+ : info.maxAspectRatio;
+
+ if (maxAspectRatio > 0) {
final float aspectRatio = (0.5f + Math.max(appWidth, appHeight))
/ Math.min(appWidth, appHeight);
- if (aspectRatio >= info.maxAspectRatio) {
+ if (aspectRatio >= maxAspectRatio) {
// The current size has reached the max aspect ratio.
return false;
}
@@ -6837,7 +6847,11 @@
// TODO(b/36505427): Consider moving this method and similar ones to ConfigurationContainer.
private void applyAspectRatio(Rect outBounds, Rect containingAppBounds,
Rect containingBounds) {
- final float maxAspectRatio = info.maxAspectRatio;
+
+ final float maxAspectRatio = (higherAspectRatio && info.applicationInfo.targetSdkVersion
+ < android.os.Build.VERSION_CODES.O) ? mFullScreenAspectRatio
+ : info.maxAspectRatio;
+
final ActivityStack stack = getRootTask();
final float minAspectRatio = info.minAspectRatio;
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index 7e6b7cd..dcc09d8 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -1639,8 +1639,13 @@
if (wasTrimmed) {
// Task was trimmed from the recent tasks list -- remove the active task record as well
// since the user won't really be able to go back to it
- removeTaskById(task.mTaskId, killProcess, false /* removeFromRecents */,
+ boolean res = removeTaskById(task.mTaskId, killProcess, false /* removeFromRecents */,
"recent-task-trimmed");
+
+ // Notify task stack changes for the non-existent task
+ if (!res) {
+ mService.getTaskChangeNotificationController().notifyTaskStackChanged();
+ }
}
task.removedFromRecents();
}
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 29881cc..0b64b25 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -795,6 +795,11 @@
return mScreenOnListener;
}
+ public int getTopFullscreenOpaqueWindowStatePrivateFlags() {
+ return mTopFullscreenOpaqueWindowState != null ?
+ mTopFullscreenOpaqueWindowState.getAttrs().privateFlags : 0;
+ }
+
public void screenTurnedOn(ScreenOnListener screenOnListener) {
synchronized (mLock) {
mScreenOnEarly = true;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index b7a2eb3..f4a53b2 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -8272,4 +8272,9 @@
Binder.restoreCallingIdentity(origId);
}
}
+
+ @Override
+ public void sendCustomAction(Intent intent) {
+ mPolicy.sendCustomAction(intent);
+ }
}
diff --git a/services/core/jni/com_android_server_fingerprint_FingerprintService.cpp b/services/core/jni/com_android_server_fingerprint_FingerprintService.cpp
index 503f0cf..478eb86 100644
--- a/services/core/jni/com_android_server_fingerprint_FingerprintService.cpp
+++ b/services/core/jni/com_android_server_fingerprint_FingerprintService.cpp
@@ -53,6 +53,7 @@
static sp<Looper> gLooper;
static jobject gCallback;
+static sp<IKeystoreService> gService;
class CallbackHandler : public MessageHandler {
int type;
@@ -70,12 +71,13 @@
static void notifyKeystore(uint8_t *auth_token, size_t auth_token_length) {
if (auth_token != NULL && auth_token_length > 0) {
- // TODO: cache service?
- sp<IServiceManager> sm = defaultServiceManager();
- sp<IBinder> binder = sm->getService(String16("android.security.keystore"));
- sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
- if (service != NULL) {
- status_t ret = service->addAuthToken(auth_token, auth_token_length);
+ if(gService == NULL) {
+ sp<IServiceManager> sm = defaultServiceManager();
+ sp<IBinder> binder = sm->getService(String16("android.security.keystore"));
+ gService = interface_cast<IKeystoreService>(binder);
+ }
+ if (gService != NULL) {
+ status_t ret = gService->addAuthToken(auth_token, auth_token_length);
if (ret != ResponseCode::NO_ERROR) {
ALOGE("Falure sending auth token to KeyStore: %d", ret);
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index b8a20ed..83c5ac8 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -7881,20 +7881,24 @@
}
enforceFullCrossUsersPermission(userHandle);
- // It's not critical here, but let's make sure the package name is correct, in case
- // we start using it for different purposes.
- ensureCallerPackage(callerPackage);
-
- final ApplicationInfo ai;
- try {
- ai = mIPackageManager.getApplicationInfo(callerPackage, 0, userHandle);
- } catch (RemoteException e) {
- throw new SecurityException(e);
- }
-
boolean legacyApp = false;
- if (ai.targetSdkVersion <= Build.VERSION_CODES.M) {
- legacyApp = true;
+ // callerPackage can only be null if we were called from within the system,
+ // which means that we are not a legacy app.
+ if (callerPackage != null) {
+ // It's not critical here, but let's make sure the package name is correct, in case
+ // we start using it for different purposes.
+ ensureCallerPackage(callerPackage);
+
+ final ApplicationInfo ai;
+ try {
+ ai = mIPackageManager.getApplicationInfo(callerPackage, 0, userHandle);
+ } catch (RemoteException e) {
+ throw new SecurityException(e);
+ }
+
+ if (ai.targetSdkVersion <= Build.VERSION_CODES.M) {
+ legacyApp = true;
+ }
}
final int rawStatus = getEncryptionStatus();
diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp
index e355a20..37b4a39 100644
--- a/services/incremental/IncrementalService.cpp
+++ b/services/incremental/IncrementalService.cpp
@@ -2009,7 +2009,7 @@
mHealthCheckParams.blockedTimeoutMs < mHealthCheckParams.unhealthyTimeoutMs;
}
-void IncrementalService::DataLoaderStub::onHealthStatus(StorageHealthListener healthListener,
+void IncrementalService::DataLoaderStub::onHealthStatus(StorageHealthListener &healthListener,
int healthStatus) {
LOG(DEBUG) << id() << ": healthStatus: " << healthStatus;
if (healthListener) {
diff --git a/services/incremental/IncrementalService.h b/services/incremental/IncrementalService.h
index a6cc946..a4aceb0 100644
--- a/services/incremental/IncrementalService.h
+++ b/services/incremental/IncrementalService.h
@@ -209,7 +209,7 @@
bool fsmStep();
bool fsmStep(int currentStatus, int targetStatus);
- void onHealthStatus(StorageHealthListener healthListener, int healthStatus);
+ void onHealthStatus(StorageHealthListener &healthListener, int healthStatus);
void updateHealthStatus(bool baseline = false);
bool isValid() const { return id() != kInvalidStorageId; }
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 7595e3f..a7a51a1 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -60,6 +60,7 @@
import android.hidl.manager.V1_0.IServiceManager;
import android.hidl.manager.V1_0.IServiceNotification;
import android.os.BatteryManager;
+import android.os.Build;
import android.os.Environment;
import android.os.FileUtils;
import android.os.Handler;
@@ -1144,7 +1145,7 @@
}
Notification.Builder builder = new Notification.Builder(mContext, channel)
- .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
+ .setSmallIcon(com.android.internal.R.drawable.stat_sys_data_usb)
.setWhen(0)
.setOngoing(true)
.setTicker(title)
@@ -1154,6 +1155,7 @@
.system_notification_accent_color))
.setContentTitle(title)
.setContentText(message)
+ .setSubText(Build.ID)
.setContentIntent(pi)
.setVisibility(Notification.VISIBILITY_PUBLIC);
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 7bd5bdf..5bcf3f3 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -186,6 +186,17 @@
"android.telecom.action.DEFAULT_DIALER_CHANGED";
/**
+ *@hide Broadcast intent action indicating the call type(CS call or Non-CS call).
+ * The string extra {@link #EXTRA_CALL_TYPE_CS} will contain the
+ * boolean value true if call is CS call else false.
+ *
+ * @see #EXTRA_CALL_TYPE_CS
+ */
+ public static final String ACTION_CALL_TYPE =
+ "codeaurora.telecom.action.CALL_TYPE";
+
+
+ /**
* Extra value used to provide the package name for {@link #ACTION_CHANGE_DEFAULT_DIALER}.
*/
public static final String EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME =
@@ -413,6 +424,12 @@
"android.telecom.extra.CALL_NETWORK_TYPE";
/**
+ *@hide Extra value used to provide the call type for {@link #ACTION_CALL_TYPE}.
+ */
+ public static final String EXTRA_CALL_TYPE_CS =
+ "codeaurora.telecom.extra.CALL_TYPE_CS";
+
+ /**
* An optional {@link android.content.Intent#ACTION_CALL} intent extra denoting the
* package name of the app specifying an alternative gateway for the call.
* The value is a string.
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 757939d..00e093b 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -4252,7 +4252,7 @@
sDefaults.putBoolean(KEY_NOTIFY_VT_HANDOVER_TO_WIFI_FAILURE_BOOL, false);
sDefaults.putStringArray(KEY_FILTERED_CNAP_NAMES_STRING_ARRAY, null);
sDefaults.putBoolean(KEY_EDITABLE_WFC_ROAMING_MODE_BOOL, false);
- sDefaults.putBoolean(KEY_SHOW_BLOCKING_PAY_PHONE_OPTION_BOOL, false);
+ sDefaults.putBoolean(KEY_SHOW_BLOCKING_PAY_PHONE_OPTION_BOOL, true);
sDefaults.putBoolean(KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL, false);
sDefaults.putBoolean(KEY_STK_DISABLE_LAUNCH_BROWSER_BOOL, false);
sDefaults.putBoolean(KEY_ALLOW_METERED_NETWORK_FOR_CERT_DOWNLOAD_BOOL, false);
@@ -4294,7 +4294,7 @@
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.putBoolean(KEY_NR_ENABLED_BOOL, true);
sDefaults.putBoolean(KEY_LTE_ENABLED_BOOL, true);
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 9e2ba68..f1314da 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -1771,6 +1771,13 @@
}
/** @hide */
+ public static boolean isPsTech(int radioTechnology) {
+ return radioTechnology == RIL_RADIO_TECHNOLOGY_LTE ||
+ radioTechnology == RIL_RADIO_TECHNOLOGY_LTE_CA ||
+ radioTechnology == RIL_RADIO_TECHNOLOGY_NR;
+ }
+
+ /** @hide */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
public static boolean bearerBitmapHasCdma(int networkTypeBitmask) {
return (RIL_RADIO_CDMA_TECHNOLOGY_BITMASK
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index f633df2..e7ac87b 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -25,6 +25,7 @@
import android.annotation.SuppressAutoDoc;
import android.annotation.SystemApi;
import android.annotation.TestApi;
+import android.app.ActivityThread;
import android.app.PendingIntent;
import android.compat.Compatibility;
import android.compat.annotation.ChangeId;
@@ -2002,6 +2003,14 @@
*/
public boolean isImsSmsSupported() {
boolean boSupported = false;
+ final Context mContext = ActivityThread.currentApplication().getApplicationContext();
+ boolean mSmsCapable = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_sms_capable);
+ if (!mSmsCapable) {
+ Log.d(TAG, "isImsSmsSupported: false");
+ return false;
+ }
+
try {
ISms iSms = getISmsService();
if (iSms != null) {
diff --git a/tools/aapt/Images.cpp b/tools/aapt/Images.cpp
index 627a231..7a6a97d 100644
--- a/tools/aapt/Images.cpp
+++ b/tools/aapt/Images.cpp
@@ -1460,7 +1460,7 @@
png_structp read_ptr = NULL;
png_infop read_info = NULL;
- FILE* fp;
+ FILE*volatile fp;
image_info imageInfo;
diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp
index 2f2ef92..6e05acf 100644
--- a/tools/aapt/Main.cpp
+++ b/tools/aapt/Main.cpp
@@ -281,8 +281,8 @@
int result = 1; // pessimistically assume an error.
int tolerance = 0;
- /* default to compression */
- bundle.setCompressionMethod(ZipEntry::kCompressDeflated);
+ /* default to 0 compression */
+ bundle.setCompressionMethod(ZipEntry::kCompressStored);
if (argc < 2) {
wantUsage = true;
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index d02f44e..87efab2 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -1470,6 +1470,11 @@
}
}
} else if (strcmp16(block.getElementName(&len), string_array16.string()) == 0) {
+ // Note the existence and locale of every string array we process
+ char rawLocale[RESTABLE_MAX_LOCALE_LEN];
+ curParams.getBcp47Locale(rawLocale);
+ String8 locale(rawLocale);
+ String16 name;
// Check whether these strings need valid formats.
// (simplified form of what string16 does above)
bool isTranslatable = false;
@@ -1480,7 +1485,9 @@
for (size_t i = 0; i < n; i++) {
size_t length;
const char16_t* attr = block.getAttributeName(i, &length);
- if (strcmp16(attr, formatted16.string()) == 0) {
+ if (strcmp16(attr, name16.string()) == 0) {
+ name.setTo(block.getAttributeStringValue(i, &length));
+ } else if (strcmp16(attr, formatted16.string()) == 0) {
const char16_t* value = block.getAttributeStringValue(i, &length);
if (strcmp16(value, false16.string()) == 0) {
curIsFormatted = false;
@@ -1489,6 +1496,15 @@
const char16_t* value = block.getAttributeStringValue(i, &length);
if (strcmp16(value, false16.string()) == 0) {
isTranslatable = false;
+ // Untranslatable string arrays must only exist
+ // in the default [empty] locale
+ if (locale.size() > 0) {
+ SourcePos(in->getPrintableSource(), block.getLineNumber()).warning(
+ "string-array '%s' marked untranslatable but exists"
+ " in locale '%s'\n", String8(name).string(),
+ locale.string());
+ // hasErrors = localHasErrors = true;
+ }
}
}
}
diff --git a/tools/aapt/StringPool.cpp b/tools/aapt/StringPool.cpp
index 37b61bf..63ce802 100644
--- a/tools/aapt/StringPool.cpp
+++ b/tools/aapt/StringPool.cpp
@@ -116,7 +116,7 @@
}
StringPool::StringPool(bool utf8) :
- mUTF8(utf8), mValues(-1)
+ mUTF8(utf8)
{
}
@@ -133,8 +133,8 @@
ssize_t StringPool::add(const String16& value,
bool mergeDuplicates, const String8* configTypeName, const ResTable_config* config)
{
- ssize_t vidx = mValues.indexOfKey(value);
- ssize_t pos = vidx >= 0 ? mValues.valueAt(vidx) : -1;
+ auto it = mValues.find(value);
+ ssize_t pos = it != mValues.end() ? it->second : -1;
ssize_t eidx = pos >= 0 ? mEntryArray.itemAt(pos) : -1;
if (eidx < 0) {
eidx = mEntries.add(entry(value));
@@ -181,21 +181,21 @@
}
}
- const bool first = vidx < 0;
+ const bool first = (it == mValues.end());
const bool styled = (pos >= 0 && (size_t)pos < mEntryStyleArray.size()) ?
mEntryStyleArray[pos].spans.size() : 0;
if (first || styled || !mergeDuplicates) {
pos = mEntryArray.add(eidx);
if (first) {
- vidx = mValues.add(value, pos);
+ mValues[value] = pos;
}
entry& ent = mEntries.editItemAt(eidx);
ent.indices.add(pos);
}
if (kIsDebug) {
- printf("Adding string %s to pool: pos=%zd eidx=%zd vidx=%zd\n",
- String8(value).string(), pos, eidx, vidx);
+ printf("Adding string %s to pool: pos=%zd eidx=%zd\n",
+ String8(value).string(), pos, eidx);
}
return pos;
@@ -338,14 +338,18 @@
// Now trim any entries at the end of the new style array that are
// not needed.
- for (ssize_t i=newEntryStyleArray.size()-1; i>=0; i--) {
+ ssize_t i;
+ for (i=newEntryStyleArray.size()-1; i>=0; i--) {
const entry_style& style = newEntryStyleArray[i];
if (style.spans.size() > 0) {
// That's it.
break;
}
- // This one is not needed; remove.
- newEntryStyleArray.removeAt(i);
+ }
+
+ ssize_t nToRemove=newEntryStyleArray.size()-(i+1);
+ if (nToRemove) {
+ newEntryStyleArray.removeItemsAt(i+1, nToRemove);
}
// All done, install the new data structures and upate mValues with
@@ -356,7 +360,7 @@
mValues.clear();
for (size_t i=0; i<mEntries.size(); i++) {
const entry& ent = mEntries[i];
- mValues.add(ent.value, ent.indices[0]);
+ mValues[ent.value] = ent.indices[0];
}
#if 0
@@ -599,9 +603,10 @@
const Vector<size_t>* StringPool::offsetsForString(const String16& val) const
{
- ssize_t pos = mValues.valueFor(val);
- if (pos < 0) {
+ auto it = mValues.find(val);
+ if (it == mValues.end()) {
return NULL;
}
+ ssize_t pos = it->second;
return &mEntries[mEntryArray[pos]].indices;
}
diff --git a/tools/aapt/StringPool.h b/tools/aapt/StringPool.h
index 253bcca..e17c865e 100644
--- a/tools/aapt/StringPool.h
+++ b/tools/aapt/StringPool.h
@@ -18,6 +18,7 @@
#include <fcntl.h>
#include <ctype.h>
#include <errno.h>
+#include <map>
using namespace android;
@@ -172,7 +173,7 @@
// Unique set of all the strings added to the pool, mapped to
// the first index of mEntryArray where the value was added.
- DefaultKeyedVector<String16, ssize_t> mValues;
+ std::map<String16, ssize_t> mValues;
// This array maps from the original position a string was placed at
// in mEntryArray to its new position after being sorted with sortByConfig().
Vector<size_t> mOriginalPosToNewPos;
diff --git a/tools/velocityplot/velocityplot.py b/tools/velocityplot/velocityplot.py
index 421bed4..948c24b 100755
--- a/tools/velocityplot/velocityplot.py
+++ b/tools/velocityplot/velocityplot.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.6
+#!/usr/bin/env python
#
# Copyright (C) 2011 The Android Open Source Project
#
diff --git a/wifi/java/android/net/wifi/IStaStateCallback.aidl b/wifi/java/android/net/wifi/IStaStateCallback.aidl
new file mode 100644
index 0000000..fc4bd6c
--- /dev/null
+++ b/wifi/java/android/net/wifi/IStaStateCallback.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2020 The Potato Open Sauce 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 android.net.wifi;
+
+/**
+ * @hide
+ */
+oneway interface IStaStateCallback
+{
+ /**
+ * @hide
+ */
+ void onStaToBeOff();
+}
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 5063ad6..aa8b69e 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -33,6 +33,7 @@
import android.net.wifi.IScanResultsCallback;
import android.net.wifi.ISoftApCallback;
import android.net.wifi.ISuggestionConnectionStatusListener;
+import android.net.wifi.IStaStateCallback;
import android.net.wifi.ITrafficStateCallback;
import android.net.wifi.IWifiConnectedNetworkScorer;
import android.net.wifi.ScanResult;
@@ -275,4 +276,8 @@
void setAutoWakeupEnabled(boolean enable);
boolean isAutoWakeupEnabled();
+
+ void registerStaStateCallback(in IBinder binder, in IStaStateCallback callback, int callbackIdentifier);
+
+ void unregisterStaStateCallback(int callbackIdentifier);
}
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 4a61db8..21bdca5 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -5275,6 +5275,71 @@
}
/**
+ * @hide
+ */
+ public interface StaStateCallback {
+ /**
+ * @hide
+ */
+ void onStaToBeOff();
+ }
+
+ /**
+ * @hide
+ */
+ private class StaStateCallbackProxy extends IStaStateCallback.Stub {
+ private final Handler mHandler;
+ private final StaStateCallback mCallback;
+
+ StaStateCallbackProxy(Looper looper, StaStateCallback callback) {
+ mHandler = new Handler(looper);
+ mCallback = callback;
+ }
+
+ @Override
+ public void onStaToBeOff() {
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "StaStateCallbackProxy: onStaToBeOff");
+ }
+ mHandler.post(() -> {
+ mCallback.onStaToBeOff();
+ });
+ }
+ }
+
+ /**
+ * @hide
+ */
+ public void registerStaStateCallback(@NonNull StaStateCallback callback,
+ @Nullable Handler handler) {
+ if (callback == null) throw new IllegalArgumentException("callback cannot be null");
+ Log.v(TAG, "registerStaStateCallback: callback=" + callback + ", handler=" + handler);
+
+ Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper();
+ Binder binder = new Binder();
+ try {
+ mService.registerStaStateCallback(
+ binder, new StaStateCallbackProxy(looper, callback), callback.hashCode());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * @hide
+ */
+ public void unregisterStaStateCallback(@NonNull StaStateCallback callback) {
+ if (callback == null) throw new IllegalArgumentException("callback cannot be null");
+ Log.v(TAG, "unregisterStaStateCallback: callback=" + callback);
+
+ try {
+ mService.unregisterStaStateCallback(callback.hashCode());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Helper method to update the local verbose logging flag based on the verbose logging
* level from wifi service.
*/