summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt1
-rw-r--r--cmds/incident_helper/src/main.cpp2
-rw-r--r--cmds/incidentd/src/Section.cpp2
-rw-r--r--cmds/statsd/src/atoms.proto17
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java1
-rw-r--r--core/java/android/os/GraphicsEnvironment.java61
-rw-r--r--core/java/android/service/notification/ConditionProviderService.java11
-rwxr-xr-xcore/java/android/util/DisplayMetrics.java8
-rw-r--r--core/java/android/view/ViewRootImpl.java13
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java9
-rw-r--r--core/jni/android_os_Trace.cpp31
-rw-r--r--core/jni/com_android_internal_os_ZygoteInit.cpp4
-rw-r--r--core/proto/android/os/incident.proto8
-rw-r--r--core/res/res/values-ar/strings.xml6
-rw-r--r--core/res/res/values-as/strings.xml3
-rw-r--r--core/res/res/values-fa/strings.xml56
-rw-r--r--core/res/res/values-fr-rCA/strings.xml2
-rw-r--r--core/res/res/values-hi/strings.xml2
-rw-r--r--core/res/res/values-ko/strings.xml2
-rw-r--r--core/res/res/values-my/strings.xml4
-rw-r--r--core/res/res/values-sw/strings.xml2
-rw-r--r--core/res/res/values-ta/strings.xml3
-rw-r--r--data/keyboards/Vendor_045e_Product_028e.kl15
-rw-r--r--data/keyboards/Vendor_057e_Product_2009.kl68
-rw-r--r--packages/SystemUI/res/layout/status_bar_notification_section_header.xml1
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/BatteryMeterView.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/ScreenDecorations.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java38
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/PhoneStateMonitor.java45
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java22
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java28
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationContextButton.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowCallback.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java46
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java46
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java30
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/leak/DumpTruck.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java121
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarContextTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java12
-rw-r--r--services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsPerUserService.java14
-rw-r--r--services/core/java/com/android/server/AlarmManagerService.java36
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java13
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java7
-rw-r--r--services/core/java/com/android/server/biometrics/ClientMonitor.java7
-rw-r--r--services/core/java/com/android/server/connectivity/NetworkNotificationManager.java5
-rw-r--r--services/core/java/com/android/server/gpu/GpuService.java8
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java8
-rw-r--r--services/core/java/com/android/server/pm/permission/PermissionManagerService.java7
-rw-r--r--services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java4
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java5
-rw-r--r--services/core/java/com/android/server/wm/ActivityMetricsLogger.java32
-rw-r--r--services/core/java/com/android/server/wm/AppWindowToken.java16
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java3
-rw-r--r--services/java/com/android/server/SystemServer.java9
-rw-r--r--services/net/java/android/net/ipmemorystore/NetworkAttributes.java5
-rw-r--r--services/net/java/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerTests.java95
-rw-r--r--tools/incident_section_gen/main.cpp7
68 files changed, 807 insertions, 314 deletions
diff --git a/api/current.txt b/api/current.txt
index 3ec7f447e8b9..9c90ee67cdf7 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -47843,6 +47843,7 @@ package android.util {
field public static final int DENSITY_400 = 400; // 0x190
field public static final int DENSITY_420 = 420; // 0x1a4
field public static final int DENSITY_440 = 440; // 0x1b8
+ field public static final int DENSITY_450 = 450; // 0x1c2
field public static final int DENSITY_560 = 560; // 0x230
field public static final int DENSITY_600 = 600; // 0x258
field public static final int DENSITY_DEFAULT = 160; // 0xa0
diff --git a/cmds/incident_helper/src/main.cpp b/cmds/incident_helper/src/main.cpp
index 809a77163fb4..ff5fd86cf11e 100644
--- a/cmds/incident_helper/src/main.cpp
+++ b/cmds/incident_helper/src/main.cpp
@@ -72,6 +72,8 @@ static TextParserBase* selectParser(int section) {
return new PsParser();
case 2006:
return new BatteryTypeParser();
+ case 3026: // system_trace is already a serialized protobuf
+ return new NoopParser();
default:
// Return no op parser when no specific ones are implemented.
return new NoopParser();
diff --git a/cmds/incidentd/src/Section.cpp b/cmds/incidentd/src/Section.cpp
index 85c5a20174c3..1572114c639f 100644
--- a/cmds/incidentd/src/Section.cpp
+++ b/cmds/incidentd/src/Section.cpp
@@ -67,6 +67,8 @@ bool section_requires_specific_mention(int sectionId) {
switch (sectionId) {
case 3025: // restricted_images
return true;
+ case 3026: // system_trace
+ return true;
default:
return false;
}
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index e9208437ff07..93e8b9de846b 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -305,6 +305,8 @@ message Atom {
LocationManagerApiUsageReported location_manager_api_usage_reported = 210;
ReviewPermissionsFragmentResultReported review_permissions_fragment_result_reported
= 211 [(log_from_module) = "permissioncontroller"];
+ RuntimePermissionsUpgradeResult runtime_permissions_upgrade_result =
+ 212 [(log_from_module) = "permissioncontroller"];
}
// Pulled events will start at field 10000.
@@ -6567,3 +6569,18 @@ message ReviewPermissionsFragmentResultReported {
// The result of the permission grant
optional bool permission_granted = 5;
}
+
+/**
+* Information about results of permission upgrade by RuntimePermissionsUpgradeController
+* Logged from: RuntimePermissionUpdgradeController
+*/
+message RuntimePermissionsUpgradeResult {
+ // Permission granted as result of upgrade
+ optional string permission_name = 1;
+
+ // UID of package granted permission
+ optional int32 uid = 2 [(is_uid) = true];
+
+ // Name of package granted permission
+ optional string package_name = 3;
+} \ No newline at end of file
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index d082f33cdefe..4b9aebd17794 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -6396,6 +6396,7 @@ public class DevicePolicyManager {
/**
* @hide
*/
+ @UnsupportedAppUsage
public @Nullable ComponentName getProfileOwnerAsUser(final int userId) {
if (mService != null) {
try {
diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java
index 833bb8f6f790..ce1942cc6d91 100644
--- a/core/java/android/os/GraphicsEnvironment.java
+++ b/core/java/android/os/GraphicsEnvironment.java
@@ -33,11 +33,13 @@ import android.widget.Toast;
import dalvik.system.VMRuntime;
+import java.io.BufferedReader;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
+import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -72,16 +74,19 @@ public class GraphicsEnvironment {
"android.app.action.ANGLE_FOR_ANDROID_TOAST_MESSAGE";
private static final String INTENT_KEY_A4A_TOAST_MESSAGE = "A4A Toast Message";
private static final String GAME_DRIVER_WHITELIST_ALL = "*";
+ private static final String GAME_DRIVER_SPHAL_LIBRARIES_FILENAME = "sphal_libraries.txt";
private static final int VULKAN_1_0 = 0x00400000;
private static final int VULKAN_1_1 = 0x00401000;
// GAME_DRIVER_ALL_APPS
// 0: Default (Invalid values fallback to default as well)
// 1: All apps use Game Driver
- // 2: All apps use system graphics driver
+ // 2: All apps use Prerelease Driver
+ // 3: All apps use system graphics driver
private static final int GAME_DRIVER_GLOBAL_OPT_IN_DEFAULT = 0;
- private static final int GAME_DRIVER_GLOBAL_OPT_IN_ALL = 1;
- private static final int GAME_DRIVER_GLOBAL_OPT_IN_NONE = 2;
+ private static final int GAME_DRIVER_GLOBAL_OPT_IN_GAME_DRIVER = 1;
+ private static final int GAME_DRIVER_GLOBAL_OPT_IN_PRERELEASE_DRIVER = 2;
+ private static final int GAME_DRIVER_GLOBAL_OPT_IN_OFF = 3;
private ClassLoader mClassLoader;
private String mLayerPath;
@@ -714,15 +719,19 @@ public class GraphicsEnvironment {
// 4. GAME_DRIVER_OPT_IN_APPS
// 5. GAME_DRIVER_BLACKLIST
// 6. GAME_DRIVER_WHITELIST
- final int globalOptIn = coreSettings.getInt(Settings.Global.GAME_DRIVER_ALL_APPS, 0);
- if (globalOptIn == GAME_DRIVER_GLOBAL_OPT_IN_NONE) {
- if (DEBUG) Log.v(TAG, "Game Driver is turned off on this device.");
- return null;
- }
-
- if (globalOptIn == GAME_DRIVER_GLOBAL_OPT_IN_ALL) {
- if (DEBUG) Log.v(TAG, "All apps opt in to use Game Driver.");
- return hasGameDriver ? gameDriver : null;
+ switch (coreSettings.getInt(Settings.Global.GAME_DRIVER_ALL_APPS, 0)) {
+ case GAME_DRIVER_GLOBAL_OPT_IN_OFF:
+ if (DEBUG) Log.v(TAG, "Game Driver is turned off on this device.");
+ return null;
+ case GAME_DRIVER_GLOBAL_OPT_IN_GAME_DRIVER:
+ if (DEBUG) Log.v(TAG, "All apps opt in to use Game Driver.");
+ return hasGameDriver ? gameDriver : null;
+ case GAME_DRIVER_GLOBAL_OPT_IN_PRERELEASE_DRIVER:
+ if (DEBUG) Log.v(TAG, "All apps opt in to use prerelease driver.");
+ return hasPrereleaseDriver ? prereleaseDriver : null;
+ case GAME_DRIVER_GLOBAL_OPT_IN_DEFAULT:
+ default:
+ break;
}
final String appPackageName = ai.packageName;
@@ -816,10 +825,7 @@ public class GraphicsEnvironment {
.append("!/lib/")
.append(abi);
final String paths = sb.toString();
-
- final String sphalLibraries =
- coreSettings.getString(Settings.Global.GAME_DRIVER_SPHAL_LIBRARIES);
-
+ final String sphalLibraries = getSphalLibraries(context, driverPackageName);
if (DEBUG) {
Log.v(TAG,
"gfx driver package search path: " + paths
@@ -856,6 +862,29 @@ public class GraphicsEnvironment {
return null;
}
+ private static String getSphalLibraries(Context context, String driverPackageName) {
+ try {
+ final Context driverContext =
+ context.createPackageContext(driverPackageName, Context.CONTEXT_RESTRICTED);
+ final BufferedReader reader = new BufferedReader(new InputStreamReader(
+ driverContext.getAssets().open(GAME_DRIVER_SPHAL_LIBRARIES_FILENAME)));
+ final ArrayList<String> assetStrings = new ArrayList<>();
+ for (String assetString; (assetString = reader.readLine()) != null;) {
+ assetStrings.add(assetString);
+ }
+ return String.join(":", assetStrings);
+ } catch (PackageManager.NameNotFoundException e) {
+ if (DEBUG) {
+ Log.w(TAG, "Driver package '" + driverPackageName + "' not installed");
+ }
+ } catch (IOException e) {
+ if (DEBUG) {
+ Log.w(TAG, "Failed to load '" + GAME_DRIVER_SPHAL_LIBRARIES_FILENAME + "'");
+ }
+ }
+ return "";
+ }
+
private static native int getCanLoadSystemLibraries();
private static native void setLayerPaths(ClassLoader classLoader, String layerPaths);
private static native void setDebugLayers(String layers);
diff --git a/core/java/android/service/notification/ConditionProviderService.java b/core/java/android/service/notification/ConditionProviderService.java
index 45480cb5acb7..7d3b13bec2f6 100644
--- a/core/java/android/service/notification/ConditionProviderService.java
+++ b/core/java/android/service/notification/ConditionProviderService.java
@@ -77,6 +77,7 @@ public abstract class ConditionProviderService extends Service {
private Provider mProvider;
private INotificationManager mNoMan;
+ boolean mIsConnected;
/**
* The {@link Intent} that must be declared as handled by the service.
@@ -179,7 +180,7 @@ public abstract class ConditionProviderService extends Service {
try {
noMan.requestUnbindProvider(mProvider);
// Disable future messages.
- mProvider = null;
+ mIsConnected = false;
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
@@ -233,16 +234,16 @@ public abstract class ConditionProviderService extends Service {
*/
@TestApi
public boolean isBound() {
- if (mProvider == null) {
+ if (!mIsConnected) {
Log.w(TAG, "Condition provider service not yet bound.");
- return false;
}
- return true;
+ return mIsConnected;
}
private final class Provider extends IConditionProvider.Stub {
@Override
public void onConnected() {
+ mIsConnected = true;
mHandler.obtainMessage(H.ON_CONNECTED).sendToTarget();
}
@@ -265,7 +266,7 @@ public abstract class ConditionProviderService extends Service {
@Override
public void handleMessage(Message msg) {
String name = null;
- if (!isBound()) {
+ if (!mIsConnected) {
return;
}
try {
diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java
index 1bcfc05224ca..7c7223c04b59 100755
--- a/core/java/android/util/DisplayMetrics.java
+++ b/core/java/android/util/DisplayMetrics.java
@@ -157,6 +157,14 @@ public class DisplayMetrics {
public static final int DENSITY_440 = 440;
/**
+ * Intermediate density for screens that sit somewhere between
+ * {@link #DENSITY_XHIGH} (320 dpi) and {@link #DENSITY_XXHIGH} (480 dpi).
+ * This is not a density that applications should target, instead relying
+ * on the system to scale their {@link #DENSITY_XXHIGH} assets for them.
+ */
+ public static final int DENSITY_450 = 450;
+
+ /**
* Standard quantized DPI for extra-extra-high-density screens.
*/
public static final int DENSITY_XXHIGH = 480;
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 7a3609a61614..3adddc790c67 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -2002,18 +2002,9 @@ public final class ViewRootImpl implements ViewParent,
mDisplay.getRealSize(size);
desiredWindowWidth = size.x;
desiredWindowHeight = size.y;
- } else if (lp.width == ViewGroup.LayoutParams.WRAP_CONTENT
- || lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
- // For wrap content, we have to remeasure later on anyways. Use size consistent with
- // below so we get best use of the measure cache.
- desiredWindowWidth = dipToPx(config.screenWidthDp);
- desiredWindowHeight = dipToPx(config.screenHeightDp);
} else {
- // After addToDisplay, the frame contains the frameHint from window manager, which
- // for most windows is going to be the same size as the result of relayoutWindow.
- // Using this here allows us to avoid remeasuring after relayoutWindow
- desiredWindowWidth = frame.width();
- desiredWindowHeight = frame.height();
+ desiredWindowWidth = mWinFrame.width();
+ desiredWindowHeight = mWinFrame.height();
}
// We used to use the following condition to choose 32 bits drawing caches:
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index c2e37d5adca8..3a7caa4c2fc0 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -3609,8 +3609,8 @@ public class BatteryStatsImpl extends BatteryStats {
public void createFakeHistoryEvents(long numEvents) {
for(long i = 0; i < numEvents; i++) {
- noteWifiOnLocked();
- noteWifiOffLocked();
+ noteLongPartialWakelockStart("name1", "historyName1", 1000);
+ noteLongPartialWakelockFinish("name1", "historyName1", 1000);
}
}
@@ -3693,9 +3693,10 @@ public class BatteryStatsImpl extends BatteryStats {
mHistoryBufferLastPos = -1;
final long elapsedRealtime = mClocks.elapsedRealtime();
final long uptime = mClocks.uptimeMillis();
+ HistoryItem newItem = new HistoryItem();
+ newItem.setTo(cur);
startRecordingHistory(elapsedRealtime, uptime, false);
-
- addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE, cur);
+ addHistoryBufferLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE, newItem);
return;
}
diff --git a/core/jni/android_os_Trace.cpp b/core/jni/android_os_Trace.cpp
index 81428dc02fb4..bd82bd91c55d 100644
--- a/core/jni/android_os_Trace.cpp
+++ b/core/jni/android_os_Trace.cpp
@@ -24,26 +24,29 @@
namespace android {
-inline static void sanitizeString(char* str, size_t size) {
- for (size_t i = 0; i < size; i++) {
- char c = str[i];
- if (c == '\0' || c == '\n' || c == '|') {
- str[i] = ' ';
+inline static void sanitizeString(char* str) {
+ while (*str) {
+ char c = *str;
+ if (c == '\n' || c == '|') {
+ *str = ' ';
}
+ str++;
}
}
-inline static void getString(JNIEnv* env, jstring jstring, char* outBuffer, jsize maxSize) {
- jsize size = std::min(env->GetStringLength(jstring), maxSize);
- env->GetStringUTFRegion(jstring, 0, size, outBuffer);
- sanitizeString(outBuffer, size);
- outBuffer[size] = '\0';
-}
-
template<typename F>
inline static void withString(JNIEnv* env, jstring jstr, F callback) {
- std::array<char, 1024> buffer;
- getString(env, jstr, buffer.data(), buffer.size());
+ // We need to handle the worst case of 1 character -> 4 bytes
+ // So make a buffer of size 4097 and let it hold a string with a maximum length
+ // of 1024. The extra last byte for the null terminator.
+ std::array<char, 4097> buffer;
+ // We have no idea of knowing how much data GetStringUTFRegion wrote, so null it out in
+ // advance so we can have a reliable null terminator
+ memset(buffer.data(), 0, buffer.size());
+ jsize size = std::min(env->GetStringLength(jstr), 1024);
+ env->GetStringUTFRegion(jstr, 0, size, buffer.data());
+ sanitizeString(buffer.data());
+
callback(buffer.data());
}
diff --git a/core/jni/com_android_internal_os_ZygoteInit.cpp b/core/jni/com_android_internal_os_ZygoteInit.cpp
index 5cca0fdc735b..c2a5ee43dbd5 100644
--- a/core/jni/com_android_internal_os_ZygoteInit.cpp
+++ b/core/jni/com_android_internal_os_ZygoteInit.cpp
@@ -19,7 +19,6 @@
#include <EGL/egl.h>
#include <Properties.h>
#include <ui/GraphicBufferMapper.h>
-#include <vulkan/vulkan.h>
#include "core_jni_helpers.h"
@@ -67,9 +66,6 @@ void android_internal_os_ZygoteInit_nativePreloadGraphicsDriver(JNIEnv* env, jcl
ScopedSCSExit x;
if (Properties::peekRenderPipelineType() == RenderPipelineType::SkiaGL) {
eglGetDisplay(EGL_DEFAULT_DISPLAY);
- } else {
- uint32_t count = 0;
- vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
}
}
diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto
index 9a9c9d14154b..7d0629ee6fba 100644
--- a/core/proto/android/os/incident.proto
+++ b/core/proto/android/os/incident.proto
@@ -321,6 +321,14 @@ message IncidentProto {
(section).args = "incidentcompanion --restricted_image"
];
+ // System trace as a serialized protobuf.
+ optional bytes system_trace = 3026 [
+ (section).type = SECTION_FILE,
+ (section).args = "/data/misc/perfetto-traces/incident-trace",
+ (privacy).dest = DEST_AUTOMATIC,
+ (section).userdebug_and_eng_only = true
+ ];
+
// Reserved for OEMs.
extensions 50000 to 100000;
}
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 3149c2d42623..432c101c286d 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -308,7 +308,7 @@
<string name="permgrouprequest_storage" msgid="7885942926944299560">"‏هل تريد السماح لتطبيق &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; بالوصول إلى الصور والوسائط والملفات على جهازك؟"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"الميكروفون"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"تسجيل الصوت"</string>
- <string name="permgrouprequest_microphone" msgid="9167492350681916038">"‏هل تريد السماح لتطبيق &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; بتسجيل الصوت؟"</string>
+ <string name="permgrouprequest_microphone" msgid="9167492350681916038">"‏هل تريد السماح لـ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; بتسجيل الصوت؟"</string>
<string name="permgrouplab_activityRecognition" msgid="1565108047054378642">"النشاط البدني"</string>
<string name="permgroupdesc_activityRecognition" msgid="6949472038320473478">"الوصول إلى بيانات نشاطك البدني"</string>
<string name="permgrouprequest_activityRecognition" msgid="7626438016904799383">"‏هل تريد السماح للتطبيق &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; بالوصول إلى بيانات نشاطك البدني؟"</string>
@@ -320,7 +320,7 @@
<string name="permgrouprequest_calllog" msgid="8487355309583773267">"‏هل تريد السماح لتطبيق &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; بالوصول إلى سجلّ مكالماتك الهاتفية؟"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"الهاتف"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"إجراء مكالمات هاتفية وإدارتها"</string>
- <string name="permgrouprequest_phone" msgid="9166979577750581037">"‏هل تريد السماح لتطبيق &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; بإجراء المكالمات الهاتفية وإدارتها؟"</string>
+ <string name="permgrouprequest_phone" msgid="9166979577750581037">"‏هل تريد السماح لـ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; بإجراء المكالمات الهاتفية وإدارتها؟"</string>
<string name="permgrouplab_sensors" msgid="4838614103153567532">"أجهزة استشعار الجسم"</string>
<string name="permgroupdesc_sensors" msgid="7147968539346634043">"الوصول إلى بيانات المستشعر حول علاماتك الحيوية"</string>
<string name="permgrouprequest_sensors" msgid="6349806962814556786">"‏هل تريد السماح لتطبيق &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; بالدخول إلى بيانات المستشعر حول علاماتك الحيوية؟"</string>
@@ -2122,7 +2122,7 @@
<string name="harmful_app_warning_title" msgid="8982527462829423432">"تم العثور على تطبيق ضار"</string>
<string name="slices_permission_request" msgid="8484943441501672932">"يريد تطبيق <xliff:g id="APP_0">%1$s</xliff:g> عرض شرائح تطبيق <xliff:g id="APP_2">%2$s</xliff:g>."</string>
<string name="screenshot_edit" msgid="7867478911006447565">"تعديل"</string>
- <string name="volume_dialog_ringer_guidance_vibrate" msgid="8902050240801159042">"سيهتز الهاتف عند تلقي المكالمات والإشعارات"</string>
+ <string name="volume_dialog_ringer_guidance_vibrate" msgid="8902050240801159042">"سيهتز الهاتف عند تلقّي المكالمات والإشعارات"</string>
<string name="volume_dialog_ringer_guidance_silent" msgid="2128975224280276122">"سيتم كتم صوت الهاتف عند تلقي المكالمات والإشعارات"</string>
<string name="notification_channel_system_changes" msgid="5072715579030948646">"تغييرات النظام"</string>
<string name="notification_channel_do_not_disturb" msgid="6766940333105743037">"عدم الإزعاج"</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index df5c303fbab6..6f50a81f17d2 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -131,8 +131,7 @@
<!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
<skip />
<string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> ৱাই- ফাই কলিং"</string>
- <!-- no translation found for wfcSpnFormat_spn_wifi_calling_vo_hyphen (1730997175789582756) -->
- <skip />
+ <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> ৱাই-ফাই কলিং"</string>
<string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN কল"</string>
<string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN কল"</string>
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> ৱাই-ফাই"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 0c957e049474..135e4e5e4a07 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -42,11 +42,11 @@
<string name="serviceErased" msgid="1288584695297200972">"پاک کردن با موفقیت انجام شد."</string>
<string name="passwordIncorrect" msgid="7612208839450128715">"گذرواژه اشتباه است."</string>
<string name="mmiComplete" msgid="8232527495411698359">"‏MMI کامل شد."</string>
- <string name="badPin" msgid="9015277645546710014">"‏پین قدیمی که نوشته‎اید صحیح نیست."</string>
+ <string name="badPin" msgid="9015277645546710014">"این پین قدیمی که نوشتید صحیح نیست."</string>
<string name="badPuk" msgid="5487257647081132201">"‏PUK که نوشته‌اید صحیح نیست."</string>
<string name="mismatchPin" msgid="609379054496863419">"‏پین‎هایی که وارد کرده‎اید با یکدیگر مطابقت ندارند."</string>
- <string name="invalidPin" msgid="3850018445187475377">"یک پین بنویسید که 4 تا 8 رقم باشد."</string>
- <string name="invalidPuk" msgid="8761456210898036513">"‏یک PUK با 8 رقم یا بیشتر تایپ کنید."</string>
+ <string name="invalidPin" msgid="3850018445187475377">"یک پین بنویسید که ۴ تا ۸ رقم باشد."</string>
+ <string name="invalidPuk" msgid="8761456210898036513">"‏یک PUK با ۸ رقم یا بیشتر تایپ کنید."</string>
<string name="needPuk" msgid="919668385956251611">"‏سیم کارت شما با PUK قفل شده است. کد PUK را برای بازگشایی آن بنویسید."</string>
<string name="needPuk2" msgid="4526033371987193070">"‏PUK2 را برای بازگشایی قفل سیم کارت بنویسید."</string>
<string name="enablePin" msgid="209412020907207950">"‏ناموفق بود، قفل سیم/RUIM را فعال کنید."</string>
@@ -73,8 +73,8 @@
<string name="DndMmi" msgid="1265478932418334331">"مزاحم نشوید"</string>
<string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"پیش‌فرض شناسه تماس‌گیرنده روی محدود است. تماس بعدی: محدود"</string>
<string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"پیش‌فرض شناسه تماس‌گیرنده روی محدود است. تماس بعدی: بدون محدودیت"</string>
- <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"پیش‌فرض شناسه تماس‌گیرنده روی غیر محدود است. تماس بعدی: محدود"</string>
- <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"پیش‌فرض شناسه تماس‌گیرنده روی غیر محدود است. تماس بعدی: بدون محدودیت"</string>
+ <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"پیش‌فرض شناسه تماس‌گیرنده روی غیرمحدود است. تماس بعدی: محدود"</string>
+ <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"پیش‌فرض شناسه تماس‌گیرنده روی غیرمحدود است. تماس بعدی: بدون محدودیت"</string>
<string name="serviceNotProvisioned" msgid="8614830180508686666">"سرویس دارای مجوز نیست."</string>
<string name="CLIRPermanent" msgid="3377371145926835671">"‏شما می‎توانید تنظیم شناسه تماس‌گیرنده را تغییر دهید."</string>
<string name="RestrictedOnDataTitle" msgid="5221736429761078014">"بدون سرویس داده تلفن همراه"</string>
@@ -103,7 +103,7 @@
<string name="serviceClassData" msgid="872456782077937893">"داده"</string>
<string name="serviceClassFAX" msgid="5566624998840486475">"نمابر"</string>
<string name="serviceClassSMS" msgid="2015460373701527489">"پیامک"</string>
- <string name="serviceClassDataAsync" msgid="4523454783498551468">"غیر همگام"</string>
+ <string name="serviceClassDataAsync" msgid="4523454783498551468">"ناهمگام"</string>
<string name="serviceClassDataSync" msgid="7530000519646054776">"همگام‌سازی"</string>
<string name="serviceClassPacket" msgid="6991006557993423453">"بسته"</string>
<string name="serviceClassPAD" msgid="3235259085648271037">"PAD"</string>
@@ -154,7 +154,7 @@
<string name="fcError" msgid="3327560126588500777">"مشکل در اتصال یا کد ویژگی نامعتبر."</string>
<string name="httpErrorOk" msgid="1191919378083472204">"تأیید"</string>
<string name="httpError" msgid="7956392511146698522">"خطایی در شبکه وجود داشت."</string>
- <string name="httpErrorLookup" msgid="4711687456111963163">"‏URL پیدا نشد."</string>
+ <string name="httpErrorLookup" msgid="4711687456111963163">"نشانی اینترنتی پیدا نشد."</string>
<string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"‏طرح کلی احراز هویت سایت پشتیبانی نمی‌‎شود."</string>
<string name="httpErrorAuth" msgid="1435065629438044534">"راستی‌آزمایی ناموفق بود."</string>
<string name="httpErrorProxyAuth" msgid="1788207010559081331">"احراز هویت از طریق سرور پروکسی انجام نشد."</string>
@@ -164,10 +164,10 @@
<string name="httpErrorRedirectLoop" msgid="8679596090392779516">"این صفحه دارای تعداد بسیار زیادی تغییر مسیر سرور است."</string>
<string name="httpErrorUnsupportedScheme" msgid="5015730812906192208">"‏پروتکل پشتیبانی نمی‌‎شود."</string>
<string name="httpErrorFailedSslHandshake" msgid="96549606000658641">"اتصال امن ایجاد نشد."</string>
- <string name="httpErrorBadUrl" msgid="3636929722728881972">"‏بدلیل نامعتبر بودن URL، باز کردن صفحه ممکن نیست."</string>
+ <string name="httpErrorBadUrl" msgid="3636929722728881972">"به‌دلیل نامعتبر بودن نشانی اینترنتی، صفحه باز نمی‌شود."</string>
<string name="httpErrorFile" msgid="2170788515052558676">"دسترسی به فایل انجام نشد."</string>
<string name="httpErrorFileNotFound" msgid="6203856612042655084">"فایل درخواستی پیدا نشد."</string>
- <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"درخواست‌های زیادی در حال پردازش است. بعداً دوباره امتحان کنید."</string>
+ <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"درخواست‌های زیادی درحال پردازش است. بعداً دوباره امتحان کنید."</string>
<string name="notification_title" msgid="8967710025036163822">"خطای ورود به سیستم برای <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string>
<string name="contentServiceSync" msgid="8353523060269335667">"همگام‌سازی"</string>
<string name="contentServiceSyncNotificationTitle" msgid="7036196943673524858">"همگام‌سازی نشد"</string>
@@ -210,7 +210,7 @@
<string name="reboot_to_update_reboot" msgid="6428441000951565185">"در حال راه‌اندازی مجدد…"</string>
<string name="reboot_to_reset_title" msgid="4142355915340627490">"بازنشانی داده‌های کارخانه"</string>
<string name="reboot_to_reset_message" msgid="2432077491101416345">"در حال راه‌اندازی مجدد…"</string>
- <string name="shutdown_progress" msgid="2281079257329981203">"در حال خاموش شدن…"</string>
+ <string name="shutdown_progress" msgid="2281079257329981203">"درحال خاموش شدن…"</string>
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"رایانهٔ لوحی شما خاموش می‌شود."</string>
<string name="shutdown_confirm" product="tv" msgid="476672373995075359">"تلویزیون شما خاموش خواهد شد."</string>
<string name="shutdown_confirm" product="watch" msgid="3490275567476369184">"ساعت شما خاموش می‌شود."</string>
@@ -399,7 +399,7 @@
<string name="permlab_readCallLog" msgid="3478133184624102739">"خواندن گزارش تماس"</string>
<string name="permdesc_readCallLog" msgid="3204122446463552146">"این برنامه می‌تواند سابقه تماس شما را بخواند."</string>
<string name="permlab_writeCallLog" msgid="8552045664743499354">"نوشتن گزارش تماس"</string>
- <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"‏به برنامه اجازه می‌دهد گزارشات تماس رایانهٔ لوحی شما، از جمله داده‌هایی درمورد تماس‎های ورودی و خروجی را تغییر دهد. برنامه‌های مخرب ممکن است از این ویژگی برای پاک کردن یا تغییر گزارش تماس شما استفاده کنند."</string>
+ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"‏به برنامه اجازه می‌دهد گزارش‌های تماس رایانهٔ لوحی شما، از جمله داده‌هایی درباره تماس‎های ورودی و خروجی را تغییر دهد. برنامه‌های مخرب ممکن است از این ویژگی برای پاک کردن یا تغییر گزارش تماس شما استفاده کنند."</string>
<string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"‏به برنامه اجازه می‌دهد گزارشات تماس تلویزیون شما، از جمله داده‌هایی درمورد تماس‎های ورودی و خروجی را تغییر دهد. برنامه‌های مخرب شاید از این ویژگی برای پاک کردن یا تغییر گزارش تماس شما استفاده کنند."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"‏به برنامه اجازه می‌دهد گزارشات تماس تلفنی شما، از جمله داده‌هایی درمورد تماس‎های ورودی و خروجی را تغییر دهد. برنامه‌های مخرب ممکن است از این ویژگی برای پاک کردن یا تغییر گزارش تماس شما استفاده کنند."</string>
<string name="permlab_bodySensors" msgid="4683341291818520277">"دسترسی به حسگرهای بدن (مانند پایشگرهای ضربان قلب)"</string>
@@ -501,7 +501,7 @@
<string name="permdesc_bluetooth" product="tv" msgid="3974124940101104206">"به برنامه اجازه می‌دهد تا پیکربندی بلوتوث را در تلویزیون مشاهده کند و اتصالات را با دستگاه‌های مرتبط‌شده ایجاد کند و بپذیرد."</string>
<string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"‏به برنامه اجازه می‎دهد تا پیکربندی بلوتوث در تلفن را مشاهده کند، و اتصالات دستگاه‌های مرتبط را برقرار کرده و بپذیرد."</string>
<string name="permlab_nfc" msgid="4423351274757876953">"کنترل ارتباط راه نزدیک"</string>
- <string name="permdesc_nfc" msgid="7120611819401789907">"‏به برنامه اجازه می‎دهد تا با تگهای ارتباط میدان نزدیک (NFC)، کارتها و فایل خوان ارتباط برقرار کند."</string>
+ <string name="permdesc_nfc" msgid="7120611819401789907">"‏به برنامه اجازه می‎دهد تا با تگ‌های «ارتباط میدان نزدیک» (NFC)، کارت‌ها و فایل‌خوان ارتباط برقرار کند."</string>
<string name="permlab_disableKeyguard" msgid="3598496301486439258">"غیرفعال کردن قفل صفحه شما"</string>
<string name="permdesc_disableKeyguard" msgid="6034203065077122992">"به برنامه امکان می‌دهد قفل کلید و هر گونه امنیت گذرواژه مرتبط را غیرفعال کند. به‌عنوان مثال تلفن هنگام دریافت یک تماس تلفنی ورودی قفل کلید را غیرفعال می‌کند و بعد از پایان تماس، قفل کلید را دوباره فعال می‌کند."</string>
<string name="permlab_requestPasswordComplexity" msgid="202650535669249674">"درخواست پیچیدگی قفل صفحه"</string>
@@ -656,7 +656,7 @@
<string name="policylab_watchLogin" msgid="5091404125971980158">"پایش تلاش‌های باز کردن قفل صفحه"</string>
<string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"‏تعداد گذرواژه‎های نادرست تایپ شده را هنگام بازکردن قفل صفحه کنترل می‌کند، و اگر دفعات زیادی گذرواژه نادرست وارد شود رایانهٔ لوحی را قفل می‌کند و همه داده‎های رایانهٔ لوحی را پاک می‌کند."</string>
<string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"بر تعداد گذرواژه‌های نادرست تایپ‌شده در زمان باز کردن قفل صفحه نظارت کنید و اگر تعدا زیادی گذرواژه‌های اشتباه تایپ شده است، تلویزیون را قفل کنید یا همه داده‌های تلویزیون را پاک کنید."</string>
- <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"‏تعداد گذرواژه‎های نادرست تایپ شده را هنگام بازکردن قفل صفحه کنترل می‎کند. اگر دفعات زیادی گذرواژه نادرست وارد شود، تلفن را قفل می‌کند یا همه داده‎های تلفن را پاک می‌کند."</string>
+ <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"‏تعداد گذرواژه‎های نادرست تایپ‌شده را هنگام بازکردن قفل صفحه کنترل می‎کند و اگر چندین بار گذرواژه‌های نادرست وارد شود، تلفن را قفل می‌کند یا همه داده‎های تلفن را پاک می‌کند."</string>
<string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="4280246270601044505">"بر تعداد گذرواژه‌های نادرستی که هنگام باز کردن قفل صفحه تایپ شده، نظارت می‌کند، و اگر تعداد گذرواژه‌های تایپ شده نادرست بیش از حد بود، رایانه لوحی را قفل می‌کند یا کلیه داده‌های کاربر را پاک می‌کند."</string>
<string name="policydesc_watchLogin_secondaryUser" product="TV" msgid="3484832653564483250">"بر تعداد گذرواژه‌های نادرستی که هنگام باز کردن قفل صفحه تایپ شده، نظارت می‌کند، و اگر تعداد گذرواژه‌های تایپ شده نادرست بیش از حد بود، تلویزیون را قفل می‌کند یا کلیه داده‌های کاربر را پاک می‌کند."</string>
<string name="policydesc_watchLogin_secondaryUser" product="default" msgid="2185480427217127147">"بر تعداد گذرواژه‌های نادرستی که هنگام باز کردن قفل صفحه تایپ شده، نظارت می‌کند، و اگر تعداد گذرواژه‌های تایپ شده نادرست بیش از حد بود، تلفن را قفل می‌کند یا کلیه داده‌های کاربر را پاک می‌کند."</string>
@@ -678,7 +678,7 @@
<string name="policydesc_expirePassword" msgid="5367525762204416046">"تغییر تعداد دفعاتی که گذرواژه، پین یا الگوی قفل صفحه باید تغییر کند."</string>
<string name="policylab_encryptedStorage" msgid="8901326199909132915">"تنظیم رمزگذاری حافظه"</string>
<string name="policydesc_encryptedStorage" msgid="2637732115325316992">"اطلاعات ذخیره شده برنامه باید رمزگذاری شود."</string>
- <string name="policylab_disableCamera" msgid="6395301023152297826">"غیر فعال کردن دوربین ها"</string>
+ <string name="policylab_disableCamera" msgid="6395301023152297826">"غیرفعال کردن دوربین‌ها"</string>
<string name="policydesc_disableCamera" msgid="2306349042834754597">"جلوگیری از استفاده از همه دوربین‌های دستگاه."</string>
<string name="policylab_disableKeyguardFeatures" msgid="8552277871075367771">"غیرفعال کردن ویژگی‌های قفل صفحه"</string>
<string name="policydesc_disableKeyguardFeatures" msgid="2044755691354158439">"مانع استفاده از برخی ویژگی‌های قفل صفحه می‌شود."</string>
@@ -838,7 +838,7 @@
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"‏سیم کارت با PUK قفل شده است."</string>
<string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"لطفاً به راهنمای کاربر مراجعه کرده یا با مرکز پشتیبانی از مشتریان تماس بگیرید."</string>
<string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"سیم کارت قفل شد."</string>
- <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"بازگشایی قفل سیم کارت..."</string>
+ <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"بازگشایی قفل سیم کارت…"</string>
<string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"‏الگوی بازگشایی قفل خود را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیده‎اید. \n\nپس از <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانیه دوباره امتحان کنید."</string>
<string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"گذرواژهٔ خود را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه تایپ کرده‌اید. \n\nپس از <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانیه دوباره امتحان کنید."</string>
<string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"‏پین را<xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه تایپ کرده‎اید. \n\nپس از <xliff:g id="NUMBER_1">%2$d</xliff:g> ثانیه دوباره امتحان کنید."</string>
@@ -850,7 +850,7 @@
<string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"شما به اشتباه <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اقدام به باز کردن قفل تلفن کرده‌اید. پس از<xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق دیگر، تلفن به پیش‌فرض کارخانه بازنشانی می‌شود و تمام داده‌های کاربر از دست خواهد رفت."</string>
<string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"شما به اشتباه اقدام به باز کردن قفل <xliff:g id="NUMBER">%d</xliff:g> رایانهٔ لوحی کرده‌اید. رایانهٔ لوحی در حال حاضر به پیش‌فرض کارخانه بازنشانی می‌شود."</string>
<string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"<xliff:g id="NUMBER">%d</xliff:g> دفعه به صورت نادرست سعی کرده‌اید قفل تلویزیون را باز کنید. اکنون تلویزیون به تنظیمات پیش‌فرض کارخانه بازنشانی خواهد شد."</string>
- <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"شما به اشتباه <xliff:g id="NUMBER">%d</xliff:g> بار اقدام به باز کردن قفل تلفن کرده‌اید. این تلفن در حال حاضر به پیش‌فرض کارخانه بازنشانی می‌شود."</string>
+ <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"به‌اشتباه <xliff:g id="NUMBER">%d</xliff:g> بار اقدام به باز کردن قفل تلفن کرده‌اید. این تلفن دیگر به پیش‌فرض کارخانه بازنشانی می‌شود."</string>
<string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"پس از <xliff:g id="NUMBER">%d</xliff:g> ثانیه دوباره امتحان کنید."</string>
<string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"الگو را فراموش کرده‌اید؟"</string>
<string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"بازگشایی قفل حساب"</string>
@@ -861,7 +861,7 @@
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"ورود به سیستم"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"نام کاربر یا گذرواژه نامعتبر است."</string>
<string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"‏نام کاربری یا گذرواژهٔ خود را فراموش کردید؟\nاز "<b>"google.com/accounts/recovery"</b>" بازدید کنید."</string>
- <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"در حال بررسی..."</string>
+ <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"درحال بررسی…"</string>
<string name="lockscreen_unlock_label" msgid="737440483220667054">"بازگشایی قفل"</string>
<string name="lockscreen_sound_on_label" msgid="9068877576513425970">"صدا روشن"</string>
<string name="lockscreen_sound_off_label" msgid="996822825154319026">"صدا خاموش"</string>
@@ -1077,7 +1077,7 @@
<string name="failed_to_copy_to_clipboard" msgid="1833662432489814471">"در بریده‌دان کپی نشد"</string>
<string name="paste" msgid="5629880836805036433">"جای‌گذاری"</string>
<string name="paste_as_plain_text" msgid="5427792741908010675">"جای‌گذاری به عنوان متن ساده"</string>
- <string name="replace" msgid="5781686059063148930">"جایگزین شود..."</string>
+ <string name="replace" msgid="5781686059063148930">"جایگزین شود…"</string>
<string name="delete" msgid="6098684844021697789">"حذف"</string>
<string name="copyUrl" msgid="2538211579596067402">"‏کپی URL"</string>
<string name="selectTextMode" msgid="1018691815143165326">"انتخاب متن"</string>
@@ -1121,7 +1121,7 @@
<string name="yes" msgid="5362982303337969312">"تأیید"</string>
<string name="no" msgid="5141531044935541497">"لغو"</string>
<string name="dialog_alert_title" msgid="2049658708609043103">"توجه"</string>
- <string name="loading" msgid="7933681260296021180">"در حال بارکردن…"</string>
+ <string name="loading" msgid="7933681260296021180">"درحال بارکردن…"</string>
<string name="capital_on" msgid="1544682755514494298">"روشن"</string>
<string name="capital_off" msgid="6815870386972805832">"خاموش"</string>
<string name="whichApplication" msgid="4533185947064773386">"تکمیل عملکرد با استفاده از"</string>
@@ -1198,8 +1198,8 @@
<string name="app_upgrading_toast" msgid="3008139776215597053">"<xliff:g id="APPLICATION">%1$s</xliff:g> درحال ارتقا است...."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"در حال بهینه‌سازی برنامهٔ <xliff:g id="NUMBER_0">%1$d</xliff:g> از <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_preparing_apk" msgid="8162599310274079154">"آماده‌سازی <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
- <string name="android_upgrading_starting_apps" msgid="451464516346926713">"در حال آغاز برنامه‌ها."</string>
- <string name="android_upgrading_complete" msgid="1405954754112999229">"در حال اتمام راه‌اندازی."</string>
+ <string name="android_upgrading_starting_apps" msgid="451464516346926713">"درحال آغاز کردن برنامه‌ها."</string>
+ <string name="android_upgrading_complete" msgid="1405954754112999229">"درحال اتمام راه‌اندازی."</string>
<string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> در حال اجرا"</string>
<string name="heavy_weight_notification_detail" msgid="2304833848484424985">"برای برگشت به بازی، ضربه بزنید"</string>
<string name="heavy_weight_switcher_title" msgid="387882830435195342">"انتخاب بازی"</string>
@@ -1306,8 +1306,8 @@
<string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="3087858235069421128">"‏در حالی که تلویزیون به <xliff:g id="DEVICE_NAME">%1$s</xliff:g> متصل است، ارتباط آن به صورت موقت از Wi-Fi قطع خواهد شد."</string>
<string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"‏این گوشی به‌طور موقت از Wi-Fi قطع خواهد شد، در حالی که به <xliff:g id="DEVICE_NAME">%1$s</xliff:g> وصل است"</string>
<string name="select_character" msgid="3365550120617701745">"درج نویسه"</string>
- <string name="sms_control_title" msgid="7296612781128917719">"ارسال پیامک ها"</string>
- <string name="sms_control_message" msgid="3867899169651496433">"‏&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; در حال ارسال تعداد زیادی پیامک است. آیا اجازه می‌دهید این برنامه همچنان پیامک ارسال کند؟"</string>
+ <string name="sms_control_title" msgid="7296612781128917719">"درحال ارسال پیامک‌ها"</string>
+ <string name="sms_control_message" msgid="3867899169651496433">"‏&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; درحال ارسال تعداد زیادی پیامک است. آیا اجازه می‌دهید این برنامه همچنان پیامک ارسال کند؟"</string>
<string name="sms_control_yes" msgid="3663725993855816807">"مجاز است"</string>
<string name="sms_control_no" msgid="625438561395534982">"اجازه ندارد"</string>
<string name="sms_short_code_confirm_message" msgid="1645436466285310855">"‏&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; مایل است پیامی به &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt; ارسال کند."</string>
@@ -1459,7 +1459,7 @@
<string name="condition_provider_service_binding_label" msgid="1321343352906524564">"ارائه‌دهنده وضعیت"</string>
<string name="notification_ranker_binding_label" msgid="774540592299064747">"سرویس رتبه‌بندی اعلان"</string>
<string name="vpn_title" msgid="19615213552042827">"‏VPN فعال شد"</string>
- <string name="vpn_title_long" msgid="6400714798049252294">"‏VPN توسط <xliff:g id="APP">%s</xliff:g> فعال شده است"</string>
+ <string name="vpn_title_long" msgid="6400714798049252294">"‏VPN را <xliff:g id="APP">%s</xliff:g> فعال کرده است"</string>
<string name="vpn_text" msgid="1610714069627824309">"برای مدیریت شبکه ضربه بزنید."</string>
<string name="vpn_text_long" msgid="4907843483284977618">"به <xliff:g id="SESSION">%s</xliff:g> متصل شد. برای مدیریت شبکه ضربه بزنید."</string>
<string name="vpn_lockdown_connecting" msgid="6443438964440960745">"‏در حال اتصال VPN همیشه فعال…"</string>
@@ -1495,11 +1495,11 @@
<string name="find_previous" msgid="2196723669388360506">"یافتن قبلی"</string>
<string name="gpsNotifTicker" msgid="5622683912616496172">"درخواست مکان از <xliff:g id="NAME">%s</xliff:g>"</string>
<string name="gpsNotifTitle" msgid="5446858717157416839">"درخواست مکان"</string>
- <string name="gpsNotifMessage" msgid="1374718023224000702">"درخواست شده توسط <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+ <string name="gpsNotifMessage" msgid="1374718023224000702">"درخواست‌کننده <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
<string name="gpsVerifYes" msgid="2346566072867213563">"بله"</string>
<string name="gpsVerifNo" msgid="1146564937346454865">"نه"</string>
<string name="sync_too_many_deletes" msgid="5296321850662746890">"از حد مجاز حذف فراتر رفت"</string>
- <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"‏<xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> مورد حذف شده برای <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>، حساب <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> وجود دارد. می‎خواهید چه کاری انجام دهید؟"</string>
+ <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"‏<xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> مورد حذف‌شده برای <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>، حساب <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> وجود دارد. می‎خواهید چه کار بکنید؟"</string>
<string name="sync_really_delete" msgid="2572600103122596243">"حذف موارد"</string>
<string name="sync_undo_deletes" msgid="2941317360600338602">"واگرد موارد حذف شده"</string>
<string name="sync_do_nothing" msgid="3743764740430821845">"اکنون کاری انجام نشود"</string>
@@ -1564,11 +1564,11 @@
<string name="data_usage_rapid_app_body" msgid="5396680996784142544">"<xliff:g id="APP">%s</xliff:g> بیش از معمول داده مصرف کرده است"</string>
<string name="ssl_certificate" msgid="6510040486049237639">"گواهی امنیتی"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"این گواهی معتبر است."</string>
- <string name="issued_to" msgid="454239480274921032">"صادر شده برای:"</string>
+ <string name="issued_to" msgid="454239480274921032">"صادرشده برای:"</string>
<string name="common_name" msgid="2233209299434172646">"نام معمولی:"</string>
<string name="org_name" msgid="6973561190762085236">"سازمان:"</string>
<string name="org_unit" msgid="7265981890422070383">"واحد سازمانی:"</string>
- <string name="issued_by" msgid="2647584988057481566">"صادر شده توسط:"</string>
+ <string name="issued_by" msgid="2647584988057481566">"صادرکننده:"</string>
<string name="validity_period" msgid="8818886137545983110">"اعتبار:"</string>
<string name="issued_on" msgid="5895017404361397232">"صادر شده در:"</string>
<string name="expires_on" msgid="3676242949915959821">"تاریخ انقضا:"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index da5f866a4713..c8482f9de2d4 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -308,7 +308,7 @@
<string name="permgrouprequest_calllog" msgid="8487355309583773267">"Autoriser &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; à accéder à vos journaux d\'appels?"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Téléphone"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"faire et gérer des appels téléphoniques"</string>
- <string name="permgrouprequest_phone" msgid="9166979577750581037">"Autoriser &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; à faire et à gérer les appels téléphoniques?"</string>
+ <string name="permgrouprequest_phone" msgid="9166979577750581037">"Autoriser &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; à faire et à gérer des appels téléphoniques?"</string>
<string name="permgrouplab_sensors" msgid="4838614103153567532">"Capteurs corporels"</string>
<string name="permgroupdesc_sensors" msgid="7147968539346634043">"accéder aux données des capteurs sur vos signes vitaux"</string>
<string name="permgrouprequest_sensors" msgid="6349806962814556786">"Autoriser « <xliff:g id="APP_NAME">%1$s</xliff:g> » à accéder aux données des capteurs pour vos signes vitaux?"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 4e9b0d272c25..d05a184f3e7e 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -116,7 +116,7 @@
<string name="roamingText6" msgid="2059440825782871513">"रोमिंग - उपलब्‍ध सिस्‍टम"</string>
<string name="roamingText7" msgid="7112078724097233605">"रोमिंग - गठबंधन सहयोगी"</string>
<string name="roamingText8" msgid="5989569778604089291">"रोमिंग - प्रीमियम सहयोगी"</string>
- <string name="roamingText9" msgid="7969296811355152491">"रोमिंग - पूर्ण सेवा काम की क्षमता"</string>
+ <string name="roamingText9" msgid="7969296811355152491">"रोमिंग - पूरी सेवा काम की क्षमता"</string>
<string name="roamingText10" msgid="3992906999815316417">"रोमिंग - आंशिक सेवा काम की क्षमता"</string>
<string name="roamingText11" msgid="4154476854426920970">"रोमिंग बैनर चालू"</string>
<string name="roamingText12" msgid="1189071119992726320">"रोमिंग बैनर बंद"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 69c53db396bb..ef6397af77f9 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -902,7 +902,7 @@
<string name="granularity_label_link" msgid="5815508880782488267">"링크"</string>
<string name="granularity_label_line" msgid="5764267235026120888">"행"</string>
<string name="factorytest_failed" msgid="5410270329114212041">"출고 테스트 불합격"</string>
- <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST 작업은 /system/app 디렉토리에 설치된 패키지에 대해서만 지원됩니다."</string>
+ <string name="factorytest_not_system" msgid="4435201656767276723">"FACTORY_TEST 작업은 /system/app 디렉터리에 설치된 패키지에 대해서만 지원됩니다."</string>
<string name="factorytest_no_action" msgid="872991874799998561">"FACTORY_TEST 작업을 제공하는 패키지가 없습니다."</string>
<string name="factorytest_reboot" msgid="6320168203050791643">"다시 부팅"</string>
<string name="js_dialog_title" msgid="1987483977834603872">"\'<xliff:g id="TITLE">%s</xliff:g>\' 페이지 내용:"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index b760e2824f2d..d8dde58a5a3d 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -296,7 +296,7 @@
<string name="permgrouprequest_storage" msgid="7885942926944299560">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; အား သင့်ဖုန်းရှိ ဓာတ်ပုံများ၊ မီဒီယာနှင့် ဖိုင်များ ဝင်သုံးခွင့်ပေးလိုပါသလား။"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"မိုက်ခရိုဖုန်း"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"အသံဖမ်းခြင်း"</string>
- <string name="permgrouprequest_microphone" msgid="9167492350681916038">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; အား အသံဖမ်းယူခွင့် ပေးလိုပါသလား။"</string>
+ <string name="permgrouprequest_microphone" msgid="9167492350681916038">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ကို အသံဖမ်းယူခွင့် ပေးလိုပါသလား။"</string>
<string name="permgrouplab_activityRecognition" msgid="1565108047054378642">"ကိုယ်လက်လှုပ်ရှားမှု"</string>
<string name="permgroupdesc_activityRecognition" msgid="6949472038320473478">"သင့်ကိုယ်လက်လှုပ်ရှားမှုကို ဝင်ကြည့်ရန်"</string>
<string name="permgrouprequest_activityRecognition" msgid="7626438016904799383">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; အား သင့်ကိုယ်လက်လှုပ်ရှားမှုကို ဝင်ကြည့်ခွင့် ပေးလိုပါသလား။"</string>
@@ -308,7 +308,7 @@
<string name="permgrouprequest_calllog" msgid="8487355309583773267">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; အား သင်၏ခေါ်ဆိုထားသော မှတ်တမ်းများကို သုံးခွင့်ပေးလိုပါသလား။"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ဖုန်း"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"ဖုန်းခေါ်ဆိုမှုများ ပြုလုပ်ရန်နှင့် စီမံရန်"</string>
- <string name="permgrouprequest_phone" msgid="9166979577750581037">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; အား ဖုန်းခေါ်ဆိုမှုများ ပြုလုပ်ခွင့်နှင့် စီမံခွင့်ပေးလိုပါသလား။"</string>
+ <string name="permgrouprequest_phone" msgid="9166979577750581037">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ကို ဖုန်းခေါ်ဆိုမှုများ ပြုလုပ်ခွင့်နှင့် စီမံခွင့်ပေးလိုပါသလား။"</string>
<string name="permgrouplab_sensors" msgid="4838614103153567532">"စက်၏ အာရုံခံစနစ်များ"</string>
<string name="permgroupdesc_sensors" msgid="7147968539346634043">"သင်၏ အဓိကကျသော လက္ခဏာများအကြောင်း အာရုံခံကိရိယာဒေတာကို ရယူသုံးစွဲရန်"</string>
<string name="permgrouprequest_sensors" msgid="6349806962814556786">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; အား သင်၏ အရေးကြီးသောလက္ခဏာ အာရုံခံကိရိယာ ဒေတာများကို သုံးခွင့်ပေးလိုပါသလား။"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 6e2ba99ac567..c48668a91461 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -308,7 +308,7 @@
<string name="permgrouprequest_calllog" msgid="8487355309583773267">"Ungependa kuiruhusu &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ifikie rekodi zako za nambari za simu?"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Simu"</string>
<string name="permgroupdesc_phone" msgid="6234224354060641055">"piga na udhibiti simu"</string>
- <string name="permgrouprequest_phone" msgid="9166979577750581037">"Ungependa kuiruhusu &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ipige na kudhibiti simu?"</string>
+ <string name="permgrouprequest_phone" msgid="9166979577750581037">"Ungependa kuruhusu &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; kupiga na kudhibiti simu?"</string>
<string name="permgrouplab_sensors" msgid="4838614103153567532">"Vihisi vya mwili"</string>
<string name="permgroupdesc_sensors" msgid="7147968539346634043">"fikia data ya kitambuzi kuhusu alama zako muhimu"</string>
<string name="permgrouprequest_sensors" msgid="6349806962814556786">"Ungependa kuiruhusu &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ifikie data ya vitambuzi kuhusu viashiria muhimu vya mwili wako?"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 30001b198c53..5e150c594b2b 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -131,8 +131,7 @@
<!-- no translation found for wfcSpnFormat_spn (4998685024207291232) -->
<skip />
<string name="wfcSpnFormat_spn_wifi_calling" msgid="136001023263502280">"<xliff:g id="SPN">%s</xliff:g> வைஃபை அழைப்பு"</string>
- <!-- no translation found for wfcSpnFormat_spn_wifi_calling_vo_hyphen (1730997175789582756) -->
- <skip />
+ <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="1730997175789582756">"<xliff:g id="SPN">%s</xliff:g> வைஃபை அழைப்பு"</string>
<string name="wfcSpnFormat_wlan_call" msgid="2533371081782489793">"WLAN அழைப்பு"</string>
<string name="wfcSpnFormat_spn_wlan_call" msgid="2315240198303197168">"<xliff:g id="SPN">%s</xliff:g> WLAN அழைப்பு"</string>
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> வைஃபை"</string>
diff --git a/data/keyboards/Vendor_045e_Product_028e.kl b/data/keyboards/Vendor_045e_Product_028e.kl
index 301601a1ffdd..e4f48f9fb326 100644
--- a/data/keyboards/Vendor_045e_Product_028e.kl
+++ b/data/keyboards/Vendor_045e_Product_028e.kl
@@ -22,9 +22,7 @@ key 307 BUTTON_X
key 308 BUTTON_Y
key 310 BUTTON_L1
key 311 BUTTON_R1
-key 314 BACK
-key 315 BUTTON_START
-key 316 HOME
+
key 317 BUTTON_THUMBL
key 318 BUTTON_THUMBR
@@ -44,3 +42,14 @@ axis 0x05 RTRIGGER
# Hat.
axis 0x10 HAT_X
axis 0x11 HAT_Y
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+
+# Button labeled as "BACK" (left-pointing triangle)
+key 314 BUTTON_SELECT
+
+# The branded "X" button in the center of the controller
+key 316 BUTTON_MODE
+
+# Button labeled as "START" (right-pointing triangle)
+key 315 BUTTON_START
diff --git a/data/keyboards/Vendor_057e_Product_2009.kl b/data/keyboards/Vendor_057e_Product_2009.kl
new file mode 100644
index 000000000000..b36e946a547f
--- /dev/null
+++ b/data/keyboards/Vendor_057e_Product_2009.kl
@@ -0,0 +1,68 @@
+# 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.
+
+#
+# Nintendo Switch Pro Controller - HAC-013 - Bluetooth
+#
+
+
+# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html
+
+# Button labeled as "Y" but should really produce keycode "X"
+key 0x132 BUTTON_X
+# Button labeled as "B" but should really produce keycode "A"
+key 0x130 BUTTON_A
+# Button labeled as "A" but should really produce keycode "B"
+key 0x131 BUTTON_B
+# Button labeled as "X" but should really product keycode "Y"
+key 0x133 BUTTON_Y
+
+# Button labeled as "L"
+key 0x134 BUTTON_L1
+# Button labeled as "R"
+key 0x135 BUTTON_R1
+
+# No LT / RT axes on this controller. Instead, there are keys.
+# Trigger labeled as "ZL"
+key 0x136 BUTTON_L2
+# Trigger labeled as "ZR"
+key 0x137 BUTTON_R2
+
+# Left Analog Stick
+axis 0x00 X
+axis 0x01 Y
+# Right Analog Stick
+axis 0x03 Z
+axis 0x04 RZ
+
+# Left stick click (generates linux BTN_SELECT)
+key 0x13a BUTTON_THUMBL
+# Right stick click (generates linux BTN_START)
+key 0x13b BUTTON_THUMBR
+
+# Hat
+axis 0x10 HAT_X
+axis 0x11 HAT_Y
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Minus
+key 0x138 BUTTON_SELECT
+# Plus
+key 0x139 BUTTON_START
+
+# Circle
+key 0x13d BUTTON_MODE
+
+# Home key
+key 0x13c HOME
diff --git a/packages/SystemUI/res/layout/status_bar_notification_section_header.xml b/packages/SystemUI/res/layout/status_bar_notification_section_header.xml
index d3eb9aeb1710..eabc5c5f254e 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_section_header.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_section_header.xml
@@ -49,6 +49,7 @@
android:text="@string/notification_section_header_gentle"
android:textSize="12sp"
android:textColor="@color/notification_section_header_label_color"
+ android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
/>
<ImageView
android:id="@+id/btn_clear_all"
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java
index bd7b3d598927..9ba21a328ca4 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java
@@ -22,6 +22,7 @@ import android.graphics.Rect;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message;
+import android.os.Trace;
import android.view.Surface;
import android.view.View;
import android.view.ViewRootImpl;
@@ -95,6 +96,7 @@ public class SyncRtSurfaceTransactionApplierCompat {
.sendToTarget();
return;
}
+ Trace.traceBegin(Trace.TRACE_TAG_VIEW, "Sync transaction frameNumber=" + frame);
TransactionCompat t = new TransactionCompat();
for (int i = params.length - 1; i >= 0; i--) {
SyncRtSurfaceTransactionApplierCompat.SurfaceParams surfaceParams =
@@ -105,6 +107,7 @@ public class SyncRtSurfaceTransactionApplierCompat {
}
t.setEarlyWakeup();
t.apply();
+ Trace.traceEnd(Trace.TRACE_TAG_VIEW);
Message.obtain(mApplyHandler, MSG_UPDATE_SEQUENCE_NUMBER, toApplySeqNo, 0)
.sendToTarget();
}
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index f66463e4ef9b..ffa69fa87436 100644
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -365,6 +365,10 @@ public class BatteryMeterView extends LinearLayout implements
} else {
setPercentTextAtCurrentLevel();
}
+ } else {
+ setContentDescription(
+ getContext().getString(mCharging ? R.string.accessibility_battery_level_charging
+ : R.string.accessibility_battery_level, mLevel));
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index eff705415957..73e57de3f915 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -768,6 +768,10 @@ public class ScreenDecorations extends SystemUI implements Tunable,
@Override
public void onDarkIntensity(float darkIntensity) {
+ if (!mHandler.getLooper().isCurrentThread()) {
+ mHandler.post(() -> onDarkIntensity(darkIntensity));
+ return;
+ }
if (mOverlay != null) {
CornerHandleView assistHintTopLeft = mOverlay.findViewById(R.id.assist_hint_left);
CornerHandleView assistHintTopRight = mOverlay.findViewById(R.id.assist_hint_right);
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java
index 87fb28b4c65e..909b68b52e3f 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java
@@ -16,14 +16,13 @@
package com.android.systemui.assist;
-import static com.android.systemui.shared.system.PackageManagerWrapper.ACTION_PREFERRED_ACTIVITY_CHANGED;
-
import android.app.ActivityManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.ResolveInfo;
import android.os.Handler;
import android.os.SystemClock;
import android.provider.Settings;
@@ -44,6 +43,7 @@ import com.android.systemui.statusbar.StatusBarState;
import java.io.PrintWriter;
import java.time.LocalDate;
import java.util.ArrayList;
+import java.util.List;
import java.util.concurrent.TimeUnit;
/**
@@ -68,6 +68,14 @@ final class AssistHandleReminderExpBehavior implements BehaviorController {
private static final boolean DEFAULT_SUPPRESS_ON_LAUNCHER = false;
private static final boolean DEFAULT_SUPPRESS_ON_APPS = false;
+ private static final String[] DEFAULT_HOME_CHANGE_ACTIONS = new String[] {
+ PackageManagerWrapper.ACTION_PREFERRED_ACTIVITY_CHANGED,
+ Intent.ACTION_BOOT_COMPLETED,
+ Intent.ACTION_PACKAGE_ADDED,
+ Intent.ACTION_PACKAGE_CHANGED,
+ Intent.ACTION_PACKAGE_REMOVED
+ };
+
private final StatusBarStateController.StateListener mStatusBarStateListener =
new StatusBarStateController.StateListener() {
@Override
@@ -110,8 +118,7 @@ final class AssistHandleReminderExpBehavior implements BehaviorController {
mDefaultHome = getCurrentDefaultHome();
}
};
- private final IntentFilter mDefaultHomeIntentFilter =
- new IntentFilter(ACTION_PREFERRED_ACTIVITY_CHANGED);
+ private final IntentFilter mDefaultHomeIntentFilter;
private final Runnable mResetConsecutiveTaskSwitches = this::resetConsecutiveTaskSwitches;
private final Handler mHandler;
@@ -146,6 +153,10 @@ final class AssistHandleReminderExpBehavior implements BehaviorController {
mStatusBarStateController = Dependency.get(StatusBarStateController.class);
mActivityManagerWrapper = ActivityManagerWrapper.getInstance();
mOverviewProxyService = Dependency.get(OverviewProxyService.class);
+ mDefaultHomeIntentFilter = new IntentFilter();
+ for (String action : DEFAULT_HOME_CHANGE_ACTIONS) {
+ mDefaultHomeIntentFilter.addAction(action);
+ }
}
@Override
@@ -205,7 +216,24 @@ final class AssistHandleReminderExpBehavior implements BehaviorController {
@Nullable
private static ComponentName getCurrentDefaultHome() {
- return PackageManagerWrapper.getInstance().getHomeActivities(new ArrayList<>());
+ List<ResolveInfo> homeActivities = new ArrayList<>();
+ ComponentName defaultHome =
+ PackageManagerWrapper.getInstance().getHomeActivities(homeActivities);
+ if (defaultHome != null) {
+ return defaultHome;
+ }
+
+ int topPriority = Integer.MIN_VALUE;
+ ComponentName topComponent = null;
+ for (ResolveInfo resolveInfo : homeActivities) {
+ if (resolveInfo.priority > topPriority) {
+ topComponent = resolveInfo.activityInfo.getComponentName();
+ topPriority = resolveInfo.priority;
+ } else if (resolveInfo.priority == topPriority) {
+ topComponent = null;
+ }
+ }
+ return topComponent;
}
private void handleStatusBarStateChanged(int newState) {
diff --git a/packages/SystemUI/src/com/android/systemui/assist/PhoneStateMonitor.java b/packages/SystemUI/src/com/android/systemui/assist/PhoneStateMonitor.java
index 1fd3089aaa41..e73dc4a57bd7 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/PhoneStateMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/PhoneStateMonitor.java
@@ -16,8 +16,6 @@
package com.android.systemui.assist;
-import static com.android.systemui.shared.system.PackageManagerWrapper.ACTION_PREFERRED_ACTIVITY_CHANGED;
-
import android.app.ActivityManager;
import android.app.KeyguardManager;
import android.content.BroadcastReceiver;
@@ -25,6 +23,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.ResolveInfo;
import androidx.annotation.Nullable;
@@ -38,6 +37,7 @@ import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.phone.StatusBar;
import java.util.ArrayList;
+import java.util.List;
/** Class to monitor and report the state of the phone. */
final class PhoneStateMonitor {
@@ -53,6 +53,14 @@ final class PhoneStateMonitor {
private static final int PHONE_STATE_APP_IMMERSIVE = 9;
private static final int PHONE_STATE_APP_FULLSCREEN = 10;
+ private static final String[] DEFAULT_HOME_CHANGE_ACTIONS = new String[] {
+ PackageManagerWrapper.ACTION_PREFERRED_ACTIVITY_CHANGED,
+ Intent.ACTION_BOOT_COMPLETED,
+ Intent.ACTION_PACKAGE_ADDED,
+ Intent.ACTION_PACKAGE_CHANGED,
+ Intent.ACTION_PACKAGE_REMOVED
+ };
+
private final Context mContext;
private final StatusBarStateController mStatusBarStateController;
@@ -64,14 +72,17 @@ final class PhoneStateMonitor {
mStatusBarStateController = Dependency.get(StatusBarStateController.class);
ActivityManagerWrapper activityManagerWrapper = ActivityManagerWrapper.getInstance();
- mDefaultHome = PackageManagerWrapper.getInstance().getHomeActivities(new ArrayList<>());
+ mDefaultHome = getCurrentDefaultHome();
+ IntentFilter intentFilter = new IntentFilter();
+ for (String action : DEFAULT_HOME_CHANGE_ACTIONS) {
+ intentFilter.addAction(action);
+ }
mContext.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- mDefaultHome =
- PackageManagerWrapper.getInstance().getHomeActivities(new ArrayList<>());
+ mDefaultHome = getCurrentDefaultHome();
}
- }, new IntentFilter(ACTION_PREFERRED_ACTIVITY_CHANGED));
+ }, intentFilter);
mLauncherShowing = isLauncherShowing(activityManagerWrapper.getRunningTask());
activityManagerWrapper.registerTaskStackListener(new TaskStackChangeListener() {
@Override
@@ -93,6 +104,28 @@ final class PhoneStateMonitor {
return phoneState;
}
+ @Nullable
+ private static ComponentName getCurrentDefaultHome() {
+ List<ResolveInfo> homeActivities = new ArrayList<>();
+ ComponentName defaultHome =
+ PackageManagerWrapper.getInstance().getHomeActivities(homeActivities);
+ if (defaultHome != null) {
+ return defaultHome;
+ }
+
+ int topPriority = Integer.MIN_VALUE;
+ ComponentName topComponent = null;
+ for (ResolveInfo resolveInfo : homeActivities) {
+ if (resolveInfo.priority > topPriority) {
+ topComponent = resolveInfo.activityInfo.getComponentName();
+ topPriority = resolveInfo.priority;
+ } else if (resolveInfo.priority == topPriority) {
+ topComponent = null;
+ }
+ }
+ return topComponent;
+ }
+
private int getPhoneLockscreenState() {
if (isDozing()) {
return PHONE_STATE_AOD1;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index c13c46d1ba4c..e5caf68c416e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -27,6 +27,9 @@ import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_INP
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SUPPORTS_WINDOW_CORNERS;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_WINDOW_CORNER_RADIUS;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED;
import android.annotation.FloatRange;
import android.app.ActivityTaskManager;
@@ -67,6 +70,7 @@ import com.android.systemui.statusbar.phone.NavigationBarFragment;
import com.android.systemui.statusbar.phone.NavigationBarView;
import com.android.systemui.statusbar.phone.NavigationModeController;
import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.StatusBarWindowCallback;
import com.android.systemui.statusbar.phone.StatusBarWindowController;
import com.android.systemui.statusbar.policy.CallbackController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -90,7 +94,6 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
private static final String ACTION_QUICKSTEP = "android.intent.action.QUICKSTEP_SERVICE";
public static final String TAG_OPS = "OverviewProxyService";
- public static final boolean DEBUG_OVERVIEW_PROXY = false;
private static final long BACKOFF_MILLIS = 1000;
private static final long DEFERRED_CALLBACK_MILLIS = 5000;
@@ -445,6 +448,8 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
}
};
+ private final StatusBarWindowCallback mStatusBarWindowCallback = this::onStatusBarStateChanged;
+
// This is the death handler for the binder from the launcher service
private final IBinder.DeathRecipient mOverviewServiceDeathRcpt
= this::cleanupAfterDeath;
@@ -484,6 +489,9 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
PatternMatcher.PATTERN_LITERAL);
filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
mContext.registerReceiver(mLauncherStateChangedReceiver, filter);
+
+ // Listen for status bar state changes
+ statusBarWinController.registerCallback(mStatusBarWindowCallback);
}
public void notifyBackAction(boolean completed, int downX, int downY, boolean isButton,
@@ -534,7 +542,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
navBarView.updateSystemUiStateFlags();
}
if (mStatusBarWinController != null) {
- mStatusBarWinController.updateSystemUiStateFlags();
+ mStatusBarWinController.notifyStateChangedCallbacks();
}
notifySystemUiStateFlags(mSysUiStateFlags);
}
@@ -549,6 +557,16 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
}
}
+ private void onStatusBarStateChanged(boolean keyguardShowing, boolean keyguardOccluded,
+ boolean bouncerShowing) {
+ int displayId = mContext.getDisplayId();
+ setSystemUiStateFlag(SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING,
+ keyguardShowing && !keyguardOccluded, displayId);
+ setSystemUiStateFlag(SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED,
+ keyguardShowing && keyguardOccluded, displayId);
+ setSystemUiStateFlag(SYSUI_STATE_BOUNCER_SHOWING, bouncerShowing, displayId);
+ }
+
/**
* Sets the navbar region which can receive touch inputs
*/
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java
index 38ff468304b7..cc0bc5f160e4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java
@@ -57,6 +57,7 @@ import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.shared.system.WindowManagerWrapper;
+import java.io.PrintWriter;
import java.util.concurrent.Executor;
/**
@@ -118,7 +119,7 @@ public class EdgeBackGestureHandler implements DisplayListener {
private final Region mExcludeRegion = new Region();
// The edge width where touch down is allowed
- private final int mEdgeWidth;
+ private int mEdgeWidth;
// The slop to distinguish between horizontal and vertical motion
private final float mTouchSlop;
// Duration after which we consider the event as longpress.
@@ -163,10 +164,6 @@ public class EdgeBackGestureHandler implements DisplayListener {
mWm = context.getSystemService(WindowManager.class);
mOverviewProxyService = overviewProxyService;
- // TODO: Get this for the current user
- mEdgeWidth = res.getDimensionPixelSize(
- com.android.internal.R.dimen.config_backGestureInset);
-
// Reduce the default touch slop to ensure that we can intercept the gesture
// before the app starts to react to it.
// TODO(b/130352502) Tune this value and extract into a constant
@@ -176,6 +173,12 @@ public class EdgeBackGestureHandler implements DisplayListener {
mNavBarHeight = res.getDimensionPixelSize(R.dimen.navigation_bar_frame_height);
mMinArrowPosition = res.getDimensionPixelSize(R.dimen.navigation_edge_arrow_min_y);
mFingerOffset = res.getDimensionPixelSize(R.dimen.navigation_edge_finger_offset);
+ updateCurrentUserResources(res);
+ }
+
+ public void updateCurrentUserResources(Resources res) {
+ mEdgeWidth = res.getDimensionPixelSize(
+ com.android.internal.R.dimen.config_backGestureInset);
}
/**
@@ -194,9 +197,10 @@ public class EdgeBackGestureHandler implements DisplayListener {
updateIsEnabled();
}
- public void onNavigationModeChanged(int mode) {
+ public void onNavigationModeChanged(int mode, Context currentUserContext) {
mIsGesturalModeEnabled = QuickStepContract.isGesturalMode(mode);
updateIsEnabled();
+ updateCurrentUserResources(currentUserContext.getResources());
}
private void disposeInputChannel() {
@@ -270,6 +274,8 @@ public class EdgeBackGestureHandler implements DisplayListener {
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT);
+ mEdgePanelLp.privateFlags |=
+ WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
mEdgePanelLp.setTitle(TAG + mDisplayId);
mEdgePanelLp.accessibilityTitle = mContext.getString(R.string.nav_bar_edge_panel);
mEdgePanelLp.windowAnimations = 0;
@@ -449,6 +455,16 @@ public class EdgeBackGestureHandler implements DisplayListener {
mRightInset = rightInset;
}
+ public void dump(PrintWriter pw) {
+ pw.println("EdgeBackGestureHandler:");
+ pw.println(" mIsEnabled=" + mIsEnabled);
+ pw.println(" mAllowGesture=" + mAllowGesture);
+ pw.println(" mExcludeRegion=" + mExcludeRegion);
+ pw.println(" mImeHeight=" + mImeHeight);
+ pw.println(" mIsAttached=" + mIsAttached);
+ pw.println(" mEdgeWidth=" + mEdgeWidth);
+ }
+
class SysUiInputEventReceiver extends InputEventReceiver {
SysUiInputEventReceiver(InputChannel channel, Looper looper) {
super(channel, looper);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java
index f5016da29ad7..6bbeffaa9bfe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java
@@ -16,8 +16,10 @@
package com.android.systemui.statusbar.phone;
+import android.annotation.ColorInt;
import android.content.Context;
import android.content.res.Resources;
+import android.graphics.Color;
import android.graphics.PixelFormat;
import android.view.ContextThemeWrapper;
import android.view.Gravity;
@@ -26,6 +28,7 @@ import android.view.Surface;
import android.view.View;
import android.view.WindowManager;
+import com.android.settingslib.Utils;
import com.android.systemui.R;
import com.android.systemui.statusbar.policy.KeyButtonDrawable;
import com.android.systemui.statusbar.policy.KeyButtonView;
@@ -33,6 +36,8 @@ import com.android.systemui.statusbar.policy.KeyButtonView;
/** Containing logic for the rotation button on the physical left bottom corner of the screen. */
public class FloatingRotationButton implements RotationButton {
+ private static final float BACKGROUND_ALPHA = 0.92f;
+
private final Context mContext;
private final WindowManager mWindowManager;
private final KeyButtonView mKeyButtonView;
@@ -151,8 +156,18 @@ public class FloatingRotationButton implements RotationButton {
public KeyButtonDrawable getImageDrawable() {
Context context = new ContextThemeWrapper(mContext.getApplicationContext(),
mRotationButtonController.getStyleRes());
- return KeyButtonDrawable.create(context, R.drawable.ic_sysbar_rotate_button,
- false /* shadow */, true /* hasOvalBg */);
+ final int dualToneDarkTheme = Utils.getThemeAttr(context, R.attr.darkIconTheme);
+ final int dualToneLightTheme = Utils.getThemeAttr(context, R.attr.lightIconTheme);
+ Context lightContext = new ContextThemeWrapper(context, dualToneLightTheme);
+ Context darkContext = new ContextThemeWrapper(context, dualToneDarkTheme);
+ @ColorInt int darkColor = Utils.getColorAttrDefaultColor(darkContext,
+ R.attr.singleToneColor);
+ Color ovalBackgroundColor = Color.valueOf(Color.red(darkColor), Color.green(darkColor),
+ Color.blue(darkColor), BACKGROUND_ALPHA);
+
+ return KeyButtonDrawable.create(lightContext,
+ Utils.getColorAttrDefaultColor(lightContext, R.attr.singleToneColor), darkColor,
+ R.drawable.ic_sysbar_rotate_button, false /* shadow */, ovalBackgroundColor);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
index 443cc4397bd3..c0a1b123fe77 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
@@ -112,7 +112,9 @@ public class MultiUserSwitch extends FrameLayout implements View.OnClickListener
final boolean guestEnabled = !mContext.getSystemService(DevicePolicyManager.class)
.getGuestUserDisabled(null);
- return mUserSwitcherController.getSwitchableUserCount() > 1 || guestEnabled
+ return mUserSwitcherController.getSwitchableUserCount() > 1
+ // If we cannot add guests even if they are enabled, do not show
+ || (guestEnabled && !mUserManager.hasUserRestriction(UserManager.DISALLOW_ADD_USER))
|| mContext.getResources().getBoolean(R.bool.qs_show_user_switcher_for_single_user);
}
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 90bce391c68d..ed486cdce665 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -772,9 +772,10 @@ public class NavigationBarView extends FrameLayout implements
@Override
public void onNavigationModeChanged(int mode) {
+ Context curUserCtx = Dependency.get(NavigationModeController.class).getCurrentUserContext();
mNavBarMode = mode;
mBarTransitions.onNavigationModeChanged(mNavBarMode);
- mEdgeBackGestureHandler.onNavigationModeChanged(mNavBarMode);
+ mEdgeBackGestureHandler.onNavigationModeChanged(mNavBarMode, curUserCtx);
mRecentsOnboarding.onNavigationModeChanged(mNavBarMode);
getRotateSuggestionButton().onNavigationModeChanged(mNavBarMode);
@@ -1103,6 +1104,7 @@ public class NavigationBarView extends FrameLayout implements
mContextualButtonGroup.dump(pw);
mRecentsOnboarding.dump(pw);
mTintController.dump(pw);
+ mEdgeBackGestureHandler.dump(pw);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java
index 77eb469c4b29..11242201d893 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java
@@ -224,7 +224,7 @@ public class NavigationModeController implements Dumpable {
return mode;
}
- private Context getCurrentUserContext() {
+ public Context getCurrentUserContext() {
int userId = ActivityManagerWrapper.getInstance().getCurrentUserId();
if (DEBUG) {
Log.d(TAG, "getCurrentUserContext: contextUser=" + mContext.getUserId()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
index f458618a43f2..e20a23edc66d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -315,10 +315,11 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
@Override
public void onViewRemoved(View child) {
super.onViewRemoved(child);
- if (mAnimationsEnabled && child instanceof StatusBarIconView) {
+
+ if (child instanceof StatusBarIconView) {
boolean isReplacingIcon = isReplacingIcon(child);
final StatusBarIconView icon = (StatusBarIconView) child;
- if (icon.getVisibleState() != StatusBarIconView.STATE_HIDDEN
+ if (mAnimationsEnabled && icon.getVisibleState() != StatusBarIconView.STATE_HIDDEN
&& child.getVisibility() == VISIBLE && isReplacingIcon) {
int animationStartIndex = findFirstViewIndexAfter(icon.getTranslationX());
if (mAddAnimationStartIndex < 0) {
@@ -329,7 +330,7 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
}
if (!mChangingViewPositions) {
mIconStates.remove(child);
- if (!isReplacingIcon) {
+ if (mAnimationsEnabled && !isReplacingIcon) {
addTransientView(icon, 0);
boolean isIsolatedIcon = child == mIsolatedIcon;
icon.setVisibleState(StatusBarIconView.STATE_HIDDEN, true /* animate */,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationContextButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationContextButton.java
index b117dec44cb4..24e73362defe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationContextButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationContextButton.java
@@ -24,7 +24,6 @@ import android.content.Context;
import android.view.ContextThemeWrapper;
import android.view.View;
-import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.statusbar.policy.KeyButtonDrawable;
/** Containing logic for the rotation button in nav bar. */
@@ -61,7 +60,7 @@ public class RotationContextButton extends ContextualButton implements
Context context = new ContextThemeWrapper(getContext().getApplicationContext(),
mRotationButtonController.getStyleRes());
return KeyButtonDrawable.create(context, mIconResId, false /* shadow */,
- QuickStepContract.isGesturalMode(mNavBarMode));
+ null /* ovalBackgroundColor */);
}
@Override
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 80fbda0809ba..1fdabc0a9fee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -317,17 +317,6 @@ public class StatusBar extends SystemUI implements DemoMode,
/** If true, the lockscreen will show a distinct wallpaper */
public static final boolean ENABLE_LOCKSCREEN_WALLPAPER = true;
- private static final AudioAttributes AUDIO_ATTRIBUTES =
- new AudioAttributes.Builder()
- .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
- // Temporary fix for b/123870990. No time in this release to
- // introduce a new vibration type, but we need to distinguish these vibrations
- // from other haptic feedback vibrations. Fortunately, Alarm vibrations have
- // exactly the same behavior as we need
- // TODO: refactor within the scope of b/132170758
- .setUsage(AudioAttributes.USAGE_ALARM)
- .build();
-
static {
boolean onlyCoreApps;
try {
@@ -3699,7 +3688,7 @@ public class StatusBar extends SystemUI implements DemoMode,
private void vibrateForCameraGesture() {
// Make sure to pass -1 for repeat so VibratorService doesn't stop us when going to sleep.
- mVibrator.vibrate(mCameraLaunchGestureVibePattern, -1 /* repeat */, AUDIO_ATTRIBUTES);
+ mVibrator.vibrate(mCameraLaunchGestureVibePattern, -1 /* repeat */);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowCallback.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowCallback.java
new file mode 100644
index 000000000000..f33ff2732cda
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowCallback.java
@@ -0,0 +1,20 @@
+/*
+ * 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;
+
+public interface StatusBarWindowCallback {
+ void onStateChanged(boolean keyguardShowing, boolean keyguardOccluded, boolean bouncerShowing);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
index c73ed60f161d..8621b7293711 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
@@ -18,9 +18,6 @@ package com.android.systemui.statusbar.phone;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED;
import static com.android.systemui.statusbar.NotificationRemoteInputManager.ENABLE_REMOTE_INPUT;
import android.app.ActivityManager;
@@ -47,17 +44,19 @@ import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
-import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.statusbar.RemoteInputController.Callback;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
+import com.google.android.collect.Lists;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
+import java.util.ArrayList;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -83,6 +82,8 @@ public class StatusBarWindowController implements Callback, Dumpable, Configurat
private float mScreenBrightnessDoze;
private final State mCurrentState = new State();
private OtherwisedCollapsedListener mListener;
+ private final ArrayList<WeakReference<StatusBarWindowCallback>>
+ mCallbacks = Lists.newArrayList();
private final SysuiColorExtractor mColorExtractor = Dependency.get(SysuiColorExtractor.class);
@@ -108,6 +109,19 @@ public class StatusBarWindowController implements Callback, Dumpable, Configurat
Dependency.get(ConfigurationController.class).addCallback(this);
}
+ /**
+ * Register to receive notifications about status bar window state changes.
+ */
+ public void registerCallback(StatusBarWindowCallback callback) {
+ // Prevent adding duplicate callbacks
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ if (mCallbacks.get(i).get() == callback) {
+ return;
+ }
+ }
+ mCallbacks.add(new WeakReference<StatusBarWindowCallback>(callback));
+ }
+
private boolean shouldEnableKeyguardScreenRotation() {
Resources res = mContext.getResources();
return SystemProperties.getBoolean("lockscreen.rot_override", false)
@@ -318,18 +332,18 @@ public class StatusBarWindowController implements Callback, Dumpable, Configurat
}
mHasTopUi = mHasTopUiChanged;
}
- updateSystemUiStateFlags();
- }
-
- public void updateSystemUiStateFlags() {
- int displayId = mContext.getDisplayId();
- OverviewProxyService overviewProxyService = Dependency.get(OverviewProxyService.class);
- overviewProxyService.setSystemUiStateFlag(SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING,
- mCurrentState.keyguardShowing && !mCurrentState.keyguardOccluded, displayId);
- overviewProxyService.setSystemUiStateFlag(SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED,
- mCurrentState.keyguardShowing && mCurrentState.keyguardOccluded, displayId);
- overviewProxyService.setSystemUiStateFlag(SYSUI_STATE_BOUNCER_SHOWING,
- mCurrentState.bouncerShowing, displayId);
+ notifyStateChangedCallbacks();
+ }
+
+ public void notifyStateChangedCallbacks() {
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ StatusBarWindowCallback cb = mCallbacks.get(i).get();
+ if (cb != null) {
+ cb.onStateChanged(mCurrentState.keyguardShowing,
+ mCurrentState.keyguardOccluded,
+ mCurrentState.bouncerShowing);
+ }
+ }
}
private void applyForceStatusBarVisibleFlag(State state) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java
index 568de63b0112..8fcaa67e7614 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java
@@ -82,9 +82,9 @@ public class KeyButtonDrawable extends Drawable {
private AnimatedVectorDrawable mAnimatedDrawable;
public KeyButtonDrawable(Drawable d, @ColorInt int lightColor, @ColorInt int darkColor,
- boolean horizontalFlip, boolean hasOvalBg) {
+ boolean horizontalFlip, Color ovalBackgroundColor) {
this(d, new ShadowDrawableState(lightColor, darkColor,
- d instanceof AnimatedVectorDrawable, horizontalFlip, hasOvalBg));
+ d instanceof AnimatedVectorDrawable, horizontalFlip, ovalBackgroundColor));
}
private KeyButtonDrawable(Drawable d, ShadowDrawableState state) {
@@ -166,7 +166,7 @@ public class KeyButtonDrawable extends Drawable {
public void setColorFilter(ColorFilter colorFilter) {
mIconPaint.setColorFilter(colorFilter);
if (mAnimatedDrawable != null) {
- if (mState.mHasOvalBg) {
+ if (hasOvalBg()) {
mAnimatedDrawable.setColorFilter(
new PorterDuffColorFilter(mState.mLightColor, PorterDuff.Mode.SRC_IN));
} else {
@@ -212,15 +212,6 @@ public class KeyButtonDrawable extends Drawable {
return mState.mBaseWidth + (mState.mShadowSize + Math.abs(mState.mShadowOffsetX)) * 2;
}
- /** Return if the drawable has oval background. */
- public boolean hasOvalBg() {
- return mState.mHasOvalBg;
- }
-
- public int getDarkColor() {
- return mState.mDarkColor;
- }
-
public boolean canAnimate() {
return mState.mSupportsAnimation;
}
@@ -290,6 +281,14 @@ public class KeyButtonDrawable extends Drawable {
return mState.canApplyTheme();
}
+ @ColorInt int getDrawableBackgroundColor() {
+ return mState.mOvalBackgroundColor.toArgb();
+ }
+
+ boolean hasOvalBg() {
+ return mState.mOvalBackgroundColor != null;
+ }
+
private void regenerateBitmapIconCache() {
final int width = getIntrinsicWidth();
final int height = getIntrinsicHeight();
@@ -394,16 +393,16 @@ public class KeyButtonDrawable extends Drawable {
final int mLightColor;
final int mDarkColor;
final boolean mSupportsAnimation;
- final boolean mHasOvalBg;
+ final Color mOvalBackgroundColor;
public ShadowDrawableState(@ColorInt int lightColor, @ColorInt int darkColor,
- boolean animated, boolean horizontalFlip, boolean hasOvalBg) {
+ boolean animated, boolean horizontalFlip, Color ovalBackgroundColor) {
mLightColor = lightColor;
mDarkColor = darkColor;
mSupportsAnimation = animated;
mAlpha = 255;
mHorizontalFlip = horizontalFlip;
- mHasOvalBg = hasOvalBg;
+ mOvalBackgroundColor = ovalBackgroundColor;
}
@Override
@@ -428,16 +427,17 @@ public class KeyButtonDrawable extends Drawable {
* @param ctx Context to get the drawable and determine the dark and light theme
* @param icon the icon resource id
* @param hasShadow if a shadow will appear with the drawable
- * @param hasOvalBg if an oval bg will be drawn
+ * @param ovalBackgroundColor the color of the oval bg that will be drawn
* @return KeyButtonDrawable
*/
public static KeyButtonDrawable create(@NonNull Context ctx, @DrawableRes int icon,
- boolean hasShadow, boolean hasOvalBg) {
+ boolean hasShadow, Color ovalBackgroundColor) {
final int dualToneDarkTheme = Utils.getThemeAttr(ctx, R.attr.darkIconTheme);
final int dualToneLightTheme = Utils.getThemeAttr(ctx, R.attr.lightIconTheme);
Context lightContext = new ContextThemeWrapper(ctx, dualToneLightTheme);
Context darkContext = new ContextThemeWrapper(ctx, dualToneDarkTheme);
- return KeyButtonDrawable.create(lightContext, darkContext, icon, hasShadow, hasOvalBg);
+ return KeyButtonDrawable.create(lightContext, darkContext, icon, hasShadow,
+ ovalBackgroundColor);
}
/**
@@ -446,7 +446,7 @@ public class KeyButtonDrawable extends Drawable {
*/
public static KeyButtonDrawable create(@NonNull Context ctx, @DrawableRes int icon,
boolean hasShadow) {
- return create(ctx, icon, hasShadow, false /* hasOvalBg */);
+ return create(ctx, icon, hasShadow, null /* ovalBackgroundColor */);
}
/**
@@ -454,11 +454,11 @@ public class KeyButtonDrawable extends Drawable {
* {@link #create(Context, int, boolean, boolean)}.
*/
public static KeyButtonDrawable create(Context lightContext, Context darkContext,
- @DrawableRes int iconResId, boolean hasShadow, boolean hasOvalBg) {
+ @DrawableRes int iconResId, boolean hasShadow, Color ovalBackgroundColor) {
return create(lightContext,
Utils.getColorAttrDefaultColor(lightContext, R.attr.singleToneColor),
Utils.getColorAttrDefaultColor(darkContext, R.attr.singleToneColor),
- iconResId, hasShadow, hasOvalBg);
+ iconResId, hasShadow, ovalBackgroundColor);
}
/**
@@ -467,12 +467,12 @@ public class KeyButtonDrawable extends Drawable {
*/
public static KeyButtonDrawable create(Context context, @ColorInt int lightColor,
@ColorInt int darkColor, @DrawableRes int iconResId, boolean hasShadow,
- boolean hasOvalBg) {
+ Color ovalBackgroundColor) {
final Resources res = context.getResources();
boolean isRtl = res.getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
Drawable d = context.getDrawable(iconResId);
final KeyButtonDrawable drawable = new KeyButtonDrawable(d, lightColor, darkColor,
- isRtl && d.isAutoMirrored(), hasOvalBg);
+ isRtl && d.isAutoMirrored(), ovalBackgroundColor);
if (hasShadow) {
int offsetX = res.getDimensionPixelSize(R.dimen.nav_key_button_shadow_offset_x);
int offsetY = res.getDimensionPixelSize(R.dimen.nav_key_button_shadow_offset_y);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index c9579fdd3788..64b28424ae63 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -79,6 +79,7 @@ public class KeyButtonView extends ImageView implements ButtonInterface {
private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
private final InputManager mInputManager;
private final Paint mOvalBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
+ private float mDarkIntensity;
private boolean mHasOvalBg = false;
private final Runnable mCheckLongPress = new Runnable() {
@@ -304,6 +305,23 @@ public class KeyButtonView extends ImageView implements ButtonInterface {
return true;
}
+ @Override
+ public void setImageDrawable(Drawable drawable) {
+ super.setImageDrawable(drawable);
+
+ if (drawable == null) {
+ return;
+ }
+ KeyButtonDrawable keyButtonDrawable = (KeyButtonDrawable) drawable;
+ keyButtonDrawable.setDarkIntensity(mDarkIntensity);
+ mHasOvalBg = keyButtonDrawable.hasOvalBg();
+ if (mHasOvalBg) {
+ mOvalBgPaint.setColor(keyButtonDrawable.getDrawableBackgroundColor());
+ }
+ mRipple.setType(keyButtonDrawable.hasOvalBg() ? KeyButtonRipple.Type.OVAL
+ : KeyButtonRipple.Type.ROUNDED_RECT);
+ }
+
public void playSoundEffect(int soundConstant) {
if (!mPlaySounds) return;
mAudioManager.playSoundEffect(soundConstant, ActivityManager.getCurrentUser());
@@ -360,17 +378,11 @@ public class KeyButtonView extends ImageView implements ButtonInterface {
@Override
public void setDarkIntensity(float darkIntensity) {
+ mDarkIntensity = darkIntensity;
+
Drawable drawable = getDrawable();
if (drawable != null) {
- KeyButtonDrawable keyButtonDrawable = (KeyButtonDrawable) drawable;
- keyButtonDrawable.setDarkIntensity(darkIntensity);
- mHasOvalBg = keyButtonDrawable.hasOvalBg();
- if (mHasOvalBg) {
- mOvalBgPaint.setColor(keyButtonDrawable.getDarkColor());
- }
- mRipple.setType(keyButtonDrawable.hasOvalBg() ? KeyButtonRipple.Type.OVAL
- : KeyButtonRipple.Type.ROUNDED_RECT);
-
+ ((KeyButtonDrawable) drawable).setDarkIntensity(darkIntensity);
// Since we reuse the same drawable for multiple views, we need to invalidate the view
// manually.
invalidate();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index 2afe485eff8e..13f93b923505 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -545,7 +545,7 @@ public class MobileSignalController extends SignalController<
}
private boolean isDataDisabled() {
- return !mPhone.getDataEnabled(mSubscriptionInfo.getSubscriptionId());
+ return !mPhone.isDataCapable();
}
@VisibleForTesting
@@ -566,6 +566,7 @@ public class MobileSignalController extends SignalController<
pw.println(" mDataState=" + mDataState + ",");
pw.println(" mDataNetType=" + mDataNetType + ",");
pw.println(" mInflateSignalStrengths=" + mInflateSignalStrengths + ",");
+ pw.println(" isDataDisabled=" + isDataDisabled() + ",");
}
class MobilePhoneStateListener extends PhoneStateListener {
diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/DumpTruck.java b/packages/SystemUI/src/com/android/systemui/util/leak/DumpTruck.java
index efd6e03b0d20..fa7af0be77f1 100644
--- a/packages/SystemUI/src/com/android/systemui/util/leak/DumpTruck.java
+++ b/packages/SystemUI/src/com/android/systemui/util/leak/DumpTruck.java
@@ -16,6 +16,8 @@
package com.android.systemui.util.leak;
+import android.content.ClipData;
+import android.content.ClipDescription;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
@@ -47,10 +49,11 @@ public class DumpTruck {
private static final String FILEPROVIDER_PATH = "leak";
private static final String TAG = "DumpTruck";
- private static final int BUFSIZ = 512 * 1024; // 512K
+ private static final int BUFSIZ = 1024 * 1024; // 1MB
private final Context context;
private Uri hprofUri;
+ private long pss;
final StringBuilder body = new StringBuilder();
public DumpTruck(Context context) {
@@ -89,6 +92,7 @@ public class DumpTruck {
.append(info.currentPss)
.append(" uss=")
.append(info.currentUss);
+ pss = info.currentPss;
}
}
if (pid == myPid) {
@@ -114,6 +118,7 @@ public class DumpTruck {
if (DumpTruck.zipUp(zipfile, paths)) {
final File pathFile = new File(zipfile);
hprofUri = FileProvider.getUriForFile(context, FILEPROVIDER_AUTHORITY, pathFile);
+ Log.v(TAG, "Heap dump accessible at URI: " + hprofUri);
}
} catch (IOException e) {
Log.e(TAG, "unable to zip up heapdumps", e);
@@ -138,16 +143,27 @@ public class DumpTruck {
* @return share intent
*/
public Intent createShareIntent() {
- Intent shareIntent = new Intent(Intent.ACTION_SEND);
+ Intent shareIntent = new Intent(Intent.ACTION_SEND_MULTIPLE);
shareIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- shareIntent.putExtra(Intent.EXTRA_SUBJECT, "SystemUI memory dump");
+ shareIntent.putExtra(Intent.EXTRA_SUBJECT,
+ String.format("SystemUI memory dump (pss=%dM)", pss / 1024));
shareIntent.putExtra(Intent.EXTRA_TEXT, body.toString());
if (hprofUri != null) {
+ final ArrayList<Uri> uriList = new ArrayList<>();
+ uriList.add(hprofUri);
shareIntent.setType("application/zip");
- shareIntent.putExtra(Intent.EXTRA_STREAM, hprofUri);
+ shareIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uriList);
+
+ // Include URI in ClipData also, so that grantPermission picks it up.
+ // We don't use setData here because some apps interpret this as "to:".
+ ClipData clipdata = new ClipData(new ClipDescription("content",
+ new String[]{ClipDescription.MIMETYPE_TEXT_PLAIN}),
+ new ClipData.Item(hprofUri));
+ shareIntent.setClipData(clipdata);
+ shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
return shareIntent;
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
index aa3fd5f69802..583f6b340d47 100644
--- a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
@@ -16,9 +16,13 @@
package com.android.systemui.util.leak;
+import static android.service.quicksettings.Tile.STATE_ACTIVE;
+import static android.telephony.ims.feature.ImsFeature.STATE_UNAVAILABLE;
+
import static com.android.internal.logging.MetricsLogger.VIEW_UNKNOWN;
import static com.android.systemui.Dependency.BG_LOOPER_NAME;
+import android.annotation.Nullable;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
@@ -38,11 +42,11 @@ import android.os.Message;
import android.os.Process;
import android.os.SystemProperties;
import android.provider.Settings;
-import android.service.quicksettings.Tile;
import android.text.format.DateUtils;
import android.util.Log;
import android.util.LongSparseArray;
+import com.android.systemui.Dumpable;
import com.android.systemui.R;
import com.android.systemui.SystemUI;
import com.android.systemui.SystemUIFactory;
@@ -50,6 +54,8 @@ import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.tileimpl.QSTileImpl;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
import java.util.ArrayList;
import javax.inject.Inject;
@@ -59,7 +65,7 @@ import javax.inject.Singleton;
/**
*/
@Singleton
-public class GarbageMonitor {
+public class GarbageMonitor implements Dumpable {
private static final boolean LEAK_REPORTING_ENABLED =
Build.IS_DEBUGGABLE
&& SystemProperties.getBoolean("debug.enable_leak_reporting", false);
@@ -77,12 +83,15 @@ public class GarbageMonitor {
private static final long GARBAGE_INSPECTION_INTERVAL =
15 * DateUtils.MINUTE_IN_MILLIS; // 15 min
private static final long HEAP_TRACK_INTERVAL = 1 * DateUtils.MINUTE_IN_MILLIS; // 1 min
+ private static final int HEAP_TRACK_HISTORY_LEN = 720; // 12 hours
private static final int DO_GARBAGE_INSPECTION = 1000;
private static final int DO_HEAP_TRACK = 3000;
private static final int GARBAGE_ALLOWANCE = 5;
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
private final Handler mHandler;
private final TrackedGarbage mTrackedGarbage;
private final LeakReporter mLeakReporter;
@@ -180,7 +189,7 @@ public class GarbageMonitor {
sb.append(p);
sb.append(" ");
}
- Log.v(TAG, sb.toString());
+ if (DEBUG) Log.v(TAG, sb.toString());
}
private void update() {
@@ -189,18 +198,18 @@ public class GarbageMonitor {
for (int i = 0; i < dinfos.length; i++) {
Debug.MemoryInfo dinfo = dinfos[i];
if (i > mPids.size()) {
- Log.e(TAG, "update: unknown process info received: " + dinfo);
+ if (DEBUG) Log.e(TAG, "update: unknown process info received: " + dinfo);
break;
}
final long pid = mPids.get(i).intValue();
final ProcessMemInfo info = mData.get(pid);
- info.head = (info.head + 1) % info.pss.length;
info.pss[info.head] = info.currentPss = dinfo.getTotalPss();
info.uss[info.head] = info.currentUss = dinfo.getTotalPrivateDirty();
+ info.head = (info.head + 1) % info.pss.length;
if (info.currentPss > info.max) info.max = info.currentPss;
if (info.currentUss > info.max) info.max = info.currentUss;
if (info.currentPss == 0) {
- Log.v(TAG, "update: pid " + pid + " has pss=0, it probably died");
+ if (DEBUG) Log.v(TAG, "update: pid " + pid + " has pss=0, it probably died");
mData.remove(pid);
}
}
@@ -230,11 +239,36 @@ public class GarbageMonitor {
return b + SUFFIXES[i];
}
- private void dumpHprofAndShare() {
- final Intent share = mDumpTruck.captureHeaps(getTrackedProcesses()).createShareIntent();
- mContext.startActivity(share);
+ private Intent dumpHprofAndGetShareIntent() {
+ return mDumpTruck.captureHeaps(getTrackedProcesses()).createShareIntent();
}
+ @Override
+ public void dump(@Nullable FileDescriptor fd, PrintWriter pw, @Nullable String[] args) {
+ pw.println("GarbageMonitor params:");
+ pw.println(String.format(" mHeapLimit=%d KB", mHeapLimit));
+ pw.println(String.format(" GARBAGE_INSPECTION_INTERVAL=%d (%.1f mins)",
+ GARBAGE_INSPECTION_INTERVAL,
+ (float) GARBAGE_INSPECTION_INTERVAL / DateUtils.MINUTE_IN_MILLIS));
+ final float htiMins = HEAP_TRACK_INTERVAL / DateUtils.MINUTE_IN_MILLIS;
+ pw.println(String.format(" HEAP_TRACK_INTERVAL=%d (%.1f mins)",
+ HEAP_TRACK_INTERVAL,
+ htiMins));
+ pw.println(String.format(" HEAP_TRACK_HISTORY_LEN=%d (%.1f hr total)",
+ HEAP_TRACK_HISTORY_LEN,
+ (float) HEAP_TRACK_HISTORY_LEN * htiMins / 60f));
+
+ pw.println("GarbageMonitor tracked processes:");
+
+ for (long pid : mPids) {
+ final ProcessMemInfo pmi = mData.get(pid);
+ if (pmi != null) {
+ pmi.dump(fd, pw, args);
+ }
+ }
+ }
+
+
private static class MemoryIconDrawable extends Drawable {
long pss, limit;
final Drawable baseIcon;
@@ -244,7 +278,7 @@ public class GarbageMonitor {
MemoryIconDrawable(Context context) {
baseIcon = context.getDrawable(R.drawable.ic_memory).mutate();
dp = context.getResources().getDisplayMetrics().density;
- paint.setColor(QSTileImpl.getColorForState(context, Tile.STATE_ACTIVE));
+ paint.setColor(QSTileImpl.getColorForState(context, STATE_ACTIVE));
}
public void setPss(long pss) {
@@ -354,6 +388,7 @@ public class GarbageMonitor {
private final GarbageMonitor gm;
private ProcessMemInfo pmi;
+ private boolean dumpInProgress;
@Inject
public MemoryTile(QSHost host) {
@@ -373,8 +408,26 @@ public class GarbageMonitor {
@Override
protected void handleClick() {
- getHost().collapsePanels();
- mHandler.post(gm::dumpHprofAndShare);
+ if (dumpInProgress) return;
+
+ dumpInProgress = true;
+ refreshState();
+ new Thread("HeapDumpThread") {
+ @Override
+ public void run() {
+ try {
+ // wait for animations & state changes
+ Thread.sleep(500);
+ } catch (InterruptedException ignored) { }
+ final Intent shareIntent = gm.dumpHprofAndGetShareIntent();
+ mHandler.post(() -> {
+ dumpInProgress = false;
+ refreshState();
+ getHost().collapsePanels();
+ mContext.startActivity(shareIntent);
+ });
+ }
+ }.start();
}
@Override
@@ -404,9 +457,12 @@ public class GarbageMonitor {
pmi = gm.getMemInfo(Process.myPid());
final MemoryGraphIcon icon = new MemoryGraphIcon();
icon.setHeapLimit(gm.mHeapLimit);
+ state.state = dumpInProgress ? STATE_UNAVAILABLE : STATE_ACTIVE;
+ state.label = dumpInProgress
+ ? "Dumping..."
+ : mContext.getString(R.string.heap_dump_tile_name);
if (pmi != null) {
icon.setPss(pmi.currentPss);
- state.label = mContext.getString(R.string.heap_dump_tile_name);
state.secondaryLabel =
String.format(
"pss: %s / %s",
@@ -414,7 +470,6 @@ public class GarbageMonitor {
formatBytes(gm.mHeapLimit * 1024));
} else {
icon.setPss(0);
- state.label = "Dump SysUI";
state.secondaryLabel = null;
}
state.icon = icon;
@@ -433,13 +488,14 @@ public class GarbageMonitor {
}
}
- public static class ProcessMemInfo {
+ /** */
+ public static class ProcessMemInfo implements Dumpable {
public long pid;
public String name;
public long startTime;
public long currentPss, currentUss;
- public long[] pss = new long[256];
- public long[] uss = new long[256];
+ public long[] pss = new long[HEAP_TRACK_HISTORY_LEN];
+ public long[] uss = new long[HEAP_TRACK_HISTORY_LEN];
public long max = 1;
public int head = 0;
@@ -452,9 +508,33 @@ public class GarbageMonitor {
public long getUptime() {
return System.currentTimeMillis() - startTime;
}
+
+ @Override
+ public void dump(@Nullable FileDescriptor fd, PrintWriter pw, @Nullable String[] args) {
+ pw.print("{ \"pid\": ");
+ pw.print(pid);
+ pw.print(", \"name\": \"");
+ pw.print(name.replace('"', '-'));
+ pw.print("\", \"start\": ");
+ pw.print(startTime);
+ pw.print(", \"pss\": [");
+ // write pss values starting from the oldest, which is pss[head], wrapping around to
+ // pss[(head-1) % pss.length]
+ for (int i = 0; i < pss.length; i++) {
+ if (i > 0) pw.print(",");
+ pw.print(pss[(head + i) % pss.length]);
+ }
+ pw.print("], \"uss\": [");
+ for (int i = 0; i < uss.length; i++) {
+ if (i > 0) pw.print(",");
+ pw.print(uss[(head + i) % uss.length]);
+ }
+ pw.println("] }");
+ }
}
- public static class Service extends SystemUI {
+ /** */
+ public static class Service extends SystemUI implements Dumpable {
private GarbageMonitor mGarbageMonitor;
@Override
@@ -472,6 +552,11 @@ public class GarbageMonitor {
mGarbageMonitor.startHeapTracking();
}
}
+
+ @Override
+ public void dump(@Nullable FileDescriptor fd, PrintWriter pw, @Nullable String[] args) {
+ if (mGarbageMonitor != null) mGarbageMonitor.dump(fd, pw, args);
+ }
}
private class BackgroundHeapCheckHandler extends Handler {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarContextTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarContextTest.java
index cb70a1fa3a3b..be69f5f8a844 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarContextTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarContextTest.java
@@ -180,9 +180,9 @@ public class NavigationBarContextTest extends SysuiTestCase {
final Drawable d = mock(Drawable.class);
final ContextualButton button = spy(mBtn0);
final KeyButtonDrawable kbd1 = spy(new KeyButtonDrawable(d, unusedColor, unusedColor,
- false /* horizontalFlip */, false /* hasOvalBg */));
+ false /* horizontalFlip */, null /* ovalBackgroundColor */));
final KeyButtonDrawable kbd2 = spy(new KeyButtonDrawable(d, unusedColor, unusedColor,
- false /* horizontalFlip */, false /* hasOvalBg */));
+ false /* horizontalFlip */, null /* ovalBackgroundColor */));
kbd1.setDarkIntensity(TEST_DARK_INTENSITY);
kbd2.setDarkIntensity(0f);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index 616b46a6d316..3464fe574007 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -164,7 +164,7 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
protected void setupNetworkController() {
// For now just pretend to be the data sim, so we can test that too.
mSubId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
- when(mMockTm.getDataEnabled(mSubId)).thenReturn(true);
+ when(mMockTm.isDataCapable()).thenReturn(true);
setDefaultSubId(mSubId);
setSubscriptions(mSubId);
mMobileSignalController = mNetworkController.mMobileSignalControllers.get(mSubId);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
index cd0a04411ee1..5128675e2723 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
@@ -119,7 +119,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
@Test
public void testNoInternetIcon_withDefaultSub() {
setupNetworkController();
- when(mMockTm.getDataEnabled(mSubId)).thenReturn(false);
+ when(mMockTm.isDataCapable()).thenReturn(false);
setupDefaultSignal();
updateDataConnectionState(TelephonyManager.DATA_CONNECTED, 0);
setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
@@ -133,7 +133,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
@Test
public void testDataDisabledIcon_withDefaultSub() {
setupNetworkController();
- when(mMockTm.getDataEnabled(mSubId)).thenReturn(false);
+ when(mMockTm.isDataCapable()).thenReturn(false);
setupDefaultSignal();
updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED, 0);
setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
@@ -147,7 +147,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
@Test
public void testNoInternetIcon_withoutDefaultSub() {
setupNetworkController();
- when(mMockTm.getDataEnabled(mSubId)).thenReturn(false);
+ when(mMockTm.isDataCapable()).thenReturn(false);
setupDefaultSignal();
setDefaultSubId(mSubId + 1);
updateDataConnectionState(TelephonyManager.DATA_CONNECTED, 0);
@@ -162,7 +162,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
@Test
public void testDataDisabledIcon_withoutDefaultSub() {
setupNetworkController();
- when(mMockTm.getDataEnabled(mSubId)).thenReturn(false);
+ when(mMockTm.isDataCapable()).thenReturn(false);
setupDefaultSignal();
setDefaultSubId(mSubId + 1);
updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED, 0);
@@ -218,7 +218,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
@Test
public void testDataDisabledIcon_UserNotSetup() {
setupNetworkController();
- when(mMockTm.getDataEnabled(mSubId)).thenReturn(false);
+ when(mMockTm.isDataCapable()).thenReturn(false);
setupDefaultSignal();
updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED, 0);
setConnectivityViaBroadcast(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
@@ -233,7 +233,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
@Test
public void testAlwaysShowDataRatIcon() {
setupDefaultSignal();
- when(mMockTm.getDataEnabled(mSubId)).thenReturn(false);
+ when(mMockTm.isDataCapable()).thenReturn(false);
updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED,
TelephonyManager.NETWORK_TYPE_GSM);
diff --git a/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsPerUserService.java b/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsPerUserService.java
index 593478c65a1c..06d9395cd7d6 100644
--- a/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsPerUserService.java
+++ b/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsPerUserService.java
@@ -95,7 +95,7 @@ public final class ContentSuggestionsPerUserService extends
@GuardedBy("mLock")
void provideContextImageLocked(int taskId, @NonNull Bundle imageContextRequestExtras) {
- RemoteContentSuggestionsService service = getRemoteServiceLocked();
+ RemoteContentSuggestionsService service = ensureRemoteServiceLocked();
if (service != null) {
ActivityManager.TaskSnapshot snapshot =
mActivityTaskManagerInternal.getTaskSnapshotNoRestore(taskId, false);
@@ -118,7 +118,7 @@ public final class ContentSuggestionsPerUserService extends
void suggestContentSelectionsLocked(
@NonNull SelectionsRequest selectionsRequest,
@NonNull ISelectionsCallback selectionsCallback) {
- RemoteContentSuggestionsService service = getRemoteServiceLocked();
+ RemoteContentSuggestionsService service = ensureRemoteServiceLocked();
if (service != null) {
service.suggestContentSelections(selectionsRequest, selectionsCallback);
}
@@ -128,7 +128,7 @@ public final class ContentSuggestionsPerUserService extends
void classifyContentSelectionsLocked(
@NonNull ClassificationsRequest classificationsRequest,
@NonNull IClassificationsCallback callback) {
- RemoteContentSuggestionsService service = getRemoteServiceLocked();
+ RemoteContentSuggestionsService service = ensureRemoteServiceLocked();
if (service != null) {
service.classifyContentSelections(classificationsRequest, callback);
}
@@ -136,7 +136,7 @@ public final class ContentSuggestionsPerUserService extends
@GuardedBy("mLock")
void notifyInteractionLocked(@NonNull String requestId, @NonNull Bundle bundle) {
- RemoteContentSuggestionsService service = getRemoteServiceLocked();
+ RemoteContentSuggestionsService service = ensureRemoteServiceLocked();
if (service != null) {
service.notifyInteraction(requestId, bundle);
}
@@ -153,12 +153,12 @@ public final class ContentSuggestionsPerUserService extends
@GuardedBy("mLock")
@Nullable
- private RemoteContentSuggestionsService getRemoteServiceLocked() {
+ private RemoteContentSuggestionsService ensureRemoteServiceLocked() {
if (mRemoteService == null) {
final String serviceName = getComponentNameLocked();
if (serviceName == null) {
if (mMaster.verbose) {
- Slog.v(TAG, "getRemoteServiceLocked(): not set");
+ Slog.v(TAG, "ensureRemoteServiceLocked(): not set");
}
return null;
}
@@ -170,8 +170,8 @@ public final class ContentSuggestionsPerUserService extends
@Override
public void onServiceDied(
@NonNull RemoteContentSuggestionsService service) {
- // TODO(b/120865921): properly implement
Slog.w(TAG, "remote content suggestions service died");
+ updateRemoteServiceLocked();
}
}, mMaster.isBindInstantServiceAllowed(), mMaster.verbose);
}
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index e2a874ea0f26..d16244167c62 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -3019,46 +3019,10 @@ class AlarmManagerService extends SystemService {
DateFormat.format(pattern, info.getTriggerTime()).toString();
}
- /**
- * If the last time AlarmThread woke up precedes any due wakeup or non-wakeup alarm that we set
- * by more than half a minute, log a wtf.
- */
- private void validateLastAlarmExpiredLocked(long nowElapsed) {
- final StringBuilder errorMsg = new StringBuilder();
- boolean stuck = false;
- if (mNextNonWakeup < (nowElapsed - 10_000) && mLastWakeup < mNextNonWakeup) {
- stuck = true;
- errorMsg.append("[mNextNonWakeup=");
- TimeUtils.formatDuration(mNextNonWakeup - nowElapsed, errorMsg);
- errorMsg.append(" set at ");
- TimeUtils.formatDuration(mNextNonWakeUpSetAt - nowElapsed, errorMsg);
- errorMsg.append(", mLastWakeup=");
- TimeUtils.formatDuration(mLastWakeup - nowElapsed, errorMsg);
- errorMsg.append(", timerfd_gettime=" + mInjector.getNextAlarm(ELAPSED_REALTIME));
- errorMsg.append("];");
- }
- if (mNextWakeup < (nowElapsed - 10_000) && mLastWakeup < mNextWakeup) {
- stuck = true;
- errorMsg.append("[mNextWakeup=");
- TimeUtils.formatDuration(mNextWakeup - nowElapsed, errorMsg);
- errorMsg.append(" set at ");
- TimeUtils.formatDuration(mNextWakeUpSetAt - nowElapsed, errorMsg);
- errorMsg.append(", mLastWakeup=");
- TimeUtils.formatDuration(mLastWakeup - nowElapsed, errorMsg);
- errorMsg.append(", timerfd_gettime="
- + mInjector.getNextAlarm(ELAPSED_REALTIME_WAKEUP));
- errorMsg.append("];");
- }
- if (stuck) {
- Slog.wtf(TAG, "Alarm delivery stuck: " + errorMsg.toString());
- }
- }
-
void rescheduleKernelAlarmsLocked() {
// Schedule the next upcoming wakeup alarm. If there is a deliverable batch
// prior to that which contains no wakeups, we schedule that as well.
final long nowElapsed = mInjector.getElapsedRealtime();
- validateLastAlarmExpiredLocked(nowElapsed);
long nextNonWakeup = 0;
if (mAlarmBatches.size() > 0) {
final Batch firstWakeup = findFirstWakeupBatchLocked();
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 5027a124e075..e81d1721b271 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -20,6 +20,7 @@ import static android.Manifest.permission.RECEIVE_DATA_ACTIVITY_CHANGE;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
import static android.net.ConnectivityManager.NETID_UNSET;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
import static android.net.ConnectivityManager.TYPE_ETHERNET;
import static android.net.ConnectivityManager.TYPE_NONE;
import static android.net.ConnectivityManager.TYPE_VPN;
@@ -6901,8 +6902,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
final int userId = UserHandle.getCallingUserId();
- final IpMemoryStore ipMemoryStore = IpMemoryStore.getMemoryStore(mContext);
- ipMemoryStore.factoryReset();
+ Binder.withCleanCallingIdentity(() -> {
+ final IpMemoryStore ipMemoryStore = IpMemoryStore.getMemoryStore(mContext);
+ ipMemoryStore.factoryReset();
+ });
// Turn airplane mode off
setAirplaneMode(false);
@@ -6952,6 +6955,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
+ // restore private DNS settings to default mode (opportunistic)
+ if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_PRIVATE_DNS)) {
+ Settings.Global.putString(mContext.getContentResolver(),
+ Settings.Global.PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_OPPORTUNISTIC);
+ }
+
Settings.Global.putString(mContext.getContentResolver(),
Settings.Global.NETWORK_AVOID_BAD_WIFI, null);
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index f14a3fdda8db..627ca911f9b9 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -7299,6 +7299,13 @@ public class ActivityManagerService extends IActivityManager.Stub
if (wasInLaunchingProviders) {
mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
}
+ // Make sure the package is associated with the process.
+ // XXX We shouldn't need to do this, since we have added the package
+ // when we generated the providers in generateApplicationProvidersLocked().
+ // But for some reason in some cases we get here with the package no longer
+ // added... for now just patch it in to make things happy.
+ r.addPackage(dst.info.applicationInfo.packageName,
+ dst.info.applicationInfo.longVersionCode, mProcessStats);
synchronized (dst) {
dst.provider = src.provider;
dst.setProcess(r);
diff --git a/services/core/java/com/android/server/biometrics/ClientMonitor.java b/services/core/java/com/android/server/biometrics/ClientMonitor.java
index 421b3f5ae106..942e0501d88d 100644
--- a/services/core/java/com/android/server/biometrics/ClientMonitor.java
+++ b/services/core/java/com/android/server/biometrics/ClientMonitor.java
@@ -42,12 +42,7 @@ public abstract class ClientMonitor extends LoggableMonitor implements IBinder.D
private static final AudioAttributes FINGERPRINT_SONFICATION_ATTRIBUTES =
new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
- // Temporary fix for b/123870990. No time in this release to
- // introduce a new vibration type, but we need to distinguish these vibrations
- // from other haptic feedback vibrations. Fortunately, Alarm vibrations have
- // exactly the same behavior as we need
- // TODO: refactor within the scope of b/132170758
- .setUsage(AudioAttributes.USAGE_ALARM)
+ .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
.build();
private final Context mContext;
diff --git a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
index f6735d983466..077c4057a3a0 100644
--- a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
+++ b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
@@ -232,6 +232,11 @@ public class NetworkNotificationManager {
title = r.getString(R.string.network_switch_metered, toTransport);
details = r.getString(R.string.network_switch_metered_detail, toTransport,
fromTransport);
+ } else if (notifyType == NotificationType.NO_INTERNET
+ || notifyType == NotificationType.PARTIAL_CONNECTIVITY) {
+ // NO_INTERNET and PARTIAL_CONNECTIVITY notification for non-WiFi networks
+ // are sent, but they are not implemented yet.
+ return;
} else {
Slog.wtf(TAG, "Unknown notification type " + notifyType + " on network transport "
+ getTransportName(transportType));
diff --git a/services/core/java/com/android/server/gpu/GpuService.java b/services/core/java/com/android/server/gpu/GpuService.java
index d4396534d067..955f17781540 100644
--- a/services/core/java/com/android/server/gpu/GpuService.java
+++ b/services/core/java/com/android/server/gpu/GpuService.java
@@ -64,7 +64,6 @@ public class GpuService extends SystemService {
private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0";
private static final String GAME_DRIVER_WHITELIST_FILENAME = "whitelist.txt";
- private static final String GAME_DRIVER_SPHAL_LIBRARIES_FILENAME = "sphal_libraries.txt";
private static final int BASE64_FLAGS = Base64.NO_PADDING | Base64.NO_WRAP;
private final Context mContext;
@@ -230,9 +229,6 @@ public class GpuService extends SystemService {
// Reset the whitelist.
Settings.Global.putString(mContentResolver,
Settings.Global.GAME_DRIVER_WHITELIST, "");
- // Reset the sphal libraries
- Settings.Global.putString(mContentResolver,
- Settings.Global.GAME_DRIVER_SPHAL_LIBRARIES, "");
mGameDriverVersionCode = driverInfo.longVersionCode;
try {
@@ -241,10 +237,6 @@ public class GpuService extends SystemService {
assetToSettingsGlobal(mContext, driverContext, GAME_DRIVER_WHITELIST_FILENAME,
Settings.Global.GAME_DRIVER_WHITELIST, ",");
-
- assetToSettingsGlobal(mContext, driverContext, GAME_DRIVER_SPHAL_LIBRARIES_FILENAME,
- Settings.Global.GAME_DRIVER_SPHAL_LIBRARIES, ":");
-
} catch (PackageManager.NameNotFoundException e) {
if (DEBUG) {
Slog.w(TAG, "driver package '" + mDriverPackageName + "' not installed");
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 4d84048fa603..5f4d11360160 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -24334,8 +24334,12 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public boolean isPermissionsReviewRequired(String packageName, int userId) {
synchronized (mPackages) {
- return mPermissionManager.isPermissionsReviewRequired(
- mPackages.get(packageName), userId);
+ final PackageParser.Package pkg = mPackages.get(packageName);
+ if (pkg == null) {
+ return false;
+ }
+
+ return mPermissionManager.isPermissionsReviewRequired(pkg, userId);
}
}
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 4edd9eff7397..e4e0c554a060 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -1897,14 +1897,15 @@ public class PermissionManagerService {
return Boolean.TRUE == granted;
}
- private boolean isPermissionsReviewRequired(PackageParser.Package pkg, int userId) {
+ private boolean isPermissionsReviewRequired(@NonNull PackageParser.Package pkg,
+ @UserIdInt int userId) {
// Permission review applies only to apps not supporting the new permission model.
if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
return false;
}
// Legacy apps have the permission and get user consent on launch.
- if (pkg == null || pkg.mExtras == null) {
+ if (pkg.mExtras == null) {
return false;
}
final PackageSetting ps = (PackageSetting) pkg.mExtras;
@@ -2952,7 +2953,7 @@ public class PermissionManagerService {
PermissionManagerService.this.systemReady();
}
@Override
- public boolean isPermissionsReviewRequired(Package pkg, int userId) {
+ public boolean isPermissionsReviewRequired(@NonNull Package pkg, @UserIdInt int userId) {
return PermissionManagerService.this.isPermissionsReviewRequired(pkg, userId);
}
@Override
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
index 9fb71f44716b..313de3daffa3 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
@@ -18,6 +18,7 @@ package com.android.server.pm.permission;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UserIdInt;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.PermissionInfoFlags;
import android.content.pm.PackageParser;
@@ -65,7 +66,8 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager
public abstract void systemReady();
- public abstract boolean isPermissionsReviewRequired(PackageParser.Package pkg, int userId);
+ public abstract boolean isPermissionsReviewRequired(@NonNull PackageParser.Package pkg,
+ @UserIdInt int userId);
public abstract void grantRuntimePermission(
@NonNull String permName, @NonNull String packageName, boolean overridePolicy,
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 7e706ad26f66..da87b2f1994b 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -5199,6 +5199,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
awakenDreams();
}
+ if (!isUserSetupComplete()) {
+ Slog.i(TAG, "Not going home because user setup is in progress.");
+ return;
+ }
+
// Start dock.
Intent dock = createHomeDockIntent();
if (dock != null) {
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index feef5e27d26a..bc0f74715240 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -544,14 +544,30 @@ class ActivityMetricsLogger {
// If we have an active transition that's waiting on a certain activity that will be
// invisible now, we'll never get onWindowsDrawn, so abort the transition if necessary.
- if (info != null && !hasVisibleNonFinishingActivity(t)) {
- if (DEBUG_METRICS) Slog.i(TAG, "notifyVisibilityChanged to invisible"
- + " activity=" + r);
- logAppTransitionCancel(info);
- mWindowingModeTransitionInfo.remove(r.getWindowingMode());
- if (mWindowingModeTransitionInfo.size() == 0) {
- reset(true /* abort */, info, "notifyVisibilityChanged to invisible");
- }
+
+ // We have no active transitions.
+ if (info == null) {
+ return;
+ }
+
+ // The notified activity whose visibility changed is no longer the launched activity.
+ // We can still wait to get onWindowsDrawn.
+ if (info.launchedActivity != r) {
+ return;
+ }
+
+ // Check if there is any activity in the task that is visible and not finishing. If the
+ // launched activity finished before it is drawn and if there is another activity in
+ // the task then that activity will be draw on screen.
+ if (hasVisibleNonFinishingActivity(t)) {
+ return;
+ }
+
+ if (DEBUG_METRICS) Slog.i(TAG, "notifyVisibilityChanged to invisible activity=" + r);
+ logAppTransitionCancel(info);
+ mWindowingModeTransitionInfo.remove(r.getWindowingMode());
+ if (mWindowingModeTransitionInfo.size() == 0) {
+ reset(true /* abort */, info, "notifyVisibilityChanged to invisible");
}
}
}
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 4a9a3f71f90e..918927912c0b 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -1322,7 +1322,9 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
if (prevDc == null || prevDc == mDisplayContent) {
return;
}
- if (prevDc.mChangingApps.contains(this)) {
+
+ prevDc.mOpeningApps.remove(this);
+ if (prevDc.mChangingApps.remove(this)) {
// This gets called *after* the AppWindowToken has been reparented to the new display.
// That reparenting resulted in this window changing modes (eg. FREEFORM -> FULLSCREEN),
// so this token is now "frozen" while waiting for the animation to start on prevDc
@@ -1331,6 +1333,8 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
// so we need to cancel the change transition here.
clearChangeLeash(getPendingTransaction(), true /* cancel */);
}
+ prevDc.mClosingApps.remove(this);
+
if (prevDc.mFocusedApp == this) {
prevDc.setFocusedApp(null);
final TaskStack stack = dc.getTopStack();
@@ -3216,16 +3220,6 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
true /* topToBottom */);
}
- void removeFromPendingTransition() {
- if (isWaitingForTransitionStart() && mDisplayContent != null) {
- mDisplayContent.mOpeningApps.remove(this);
- if (mDisplayContent.mChangingApps.remove(this)) {
- clearChangeLeash(getPendingTransaction(), true /* cancel */);
- }
- mDisplayContent.mClosingApps.remove(this);
- }
- }
-
private void updateColorTransform() {
if (mSurfaceControl != null && mLastAppSaturationInfo != null) {
getPendingTransaction().setColorTransform(mSurfaceControl,
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index c3a769b63e5a..80848a8f24f0 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -2377,9 +2377,6 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
+ " to its current displayId=" + mDisplayId);
}
- // Clean up all pending transitions when stack reparent to another display.
- stack.forAllAppWindows(AppWindowToken::removeFromPendingTransition);
-
prevDc.mTaskStackContainers.removeChild(stack);
mTaskStackContainers.addStackToDisplay(stack, onTop);
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 203704bf7224..6dd85270e7e8 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -731,8 +731,13 @@ public final class SystemServer {
(int) SystemClock.elapsedRealtime());
}
traceBeginAndSlog("StartPackageManagerService");
- mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
- mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
+ try {
+ Watchdog.getInstance().pauseWatchingCurrentThread("packagemanagermain");
+ mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
+ mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
+ } finally {
+ Watchdog.getInstance().resumeWatchingCurrentThread("packagemanagermain");
+ }
mFirstBoot = mPackageManagerService.isFirstBoot();
mPackageManager = mSystemContext.getPackageManager();
traceEnd();
diff --git a/services/net/java/android/net/ipmemorystore/NetworkAttributes.java b/services/net/java/android/net/ipmemorystore/NetworkAttributes.java
index e76976991797..818515ac9af1 100644
--- a/services/net/java/android/net/ipmemorystore/NetworkAttributes.java
+++ b/services/net/java/android/net/ipmemorystore/NetworkAttributes.java
@@ -127,6 +127,7 @@ public class NetworkAttributes {
@Nullable
private static InetAddress getByAddressOrNull(@Nullable final byte[] address) {
+ if (null == address) return null;
try {
return InetAddress.getByAddress(address);
} catch (UnknownHostException e) {
@@ -227,7 +228,9 @@ public class NetworkAttributes {
}
/**
- * Set the lease expiry timestamp of assigned v4 address.
+ * Set the lease expiry timestamp of assigned v4 address. Long.MAX_VALUE is used
+ * to represent "infinite lease".
+ *
* @param assignedV4AddressExpiry The lease expiry timestamp of assigned v4 address.
* @return This builder.
*/
diff --git a/services/net/java/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java b/services/net/java/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java
index ca6f3029d496..395ad98f38e0 100644
--- a/services/net/java/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java
+++ b/services/net/java/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java
@@ -40,8 +40,8 @@ public interface OnNetworkAttributesRetrievedListener {
// NonNull, but still don't crash the system server if null
if (null != listener) {
listener.onNetworkAttributesRetrieved(
- new Status(statusParcelable), l2Key,
- new NetworkAttributes(networkAttributesParcelable));
+ new Status(statusParcelable), l2Key, null == networkAttributesParcelable
+ ? null : new NetworkAttributes(networkAttributesParcelable));
}
}
diff --git a/services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerTests.java b/services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerTests.java
new file mode 100644
index 000000000000..fc24f5e207a8
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerTests.java
@@ -0,0 +1,95 @@
+/*
+ * 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.server.policy;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.reset;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
+
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+
+import android.app.ActivityManager;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.server.wm.ActivityTaskManagerInternal;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Test class for {@link PhoneWindowManager}.
+ *
+ * Build/Install/Run:
+ * atest WmTests:PhoneWindowManagerTests
+ */
+@SmallTest
+public class PhoneWindowManagerTests {
+
+ PhoneWindowManager mPhoneWindowManager;
+
+ @Before
+ public void setUp() {
+ mPhoneWindowManager = spy(new PhoneWindowManager());
+ spyOn(ActivityManager.getService());
+ }
+
+ @After
+ public void tearDown() {
+ reset(ActivityManager.getService());
+ }
+
+ @Test
+ public void testShouldNotStartDockOrHomeWhenSetup() throws Exception {
+ mockStartDockOrHome();
+ doReturn(false).when(mPhoneWindowManager).isUserSetupComplete();
+
+ mPhoneWindowManager.startDockOrHome(
+ 0 /* displayId */, false /* fromHomeKey */, false /* awakenFromDreams */);
+
+ verify(mPhoneWindowManager, never()).createHomeDockIntent();
+ }
+
+ @Test
+ public void testShouldStartDockOrHomeAfterSetup() throws Exception {
+ mockStartDockOrHome();
+ doReturn(true).when(mPhoneWindowManager).isUserSetupComplete();
+
+ mPhoneWindowManager.startDockOrHome(
+ 0 /* displayId */, false /* fromHomeKey */, false /* awakenFromDreams */);
+
+ verify(mPhoneWindowManager).createHomeDockIntent();
+ }
+
+ private void mockStartDockOrHome() throws Exception {
+ doNothing().when(ActivityManager.getService()).stopAppSwitches();
+ ActivityTaskManagerInternal mMockActivityTaskManagerInternal =
+ mock(ActivityTaskManagerInternal.class);
+ when(mMockActivityTaskManagerInternal.startHomeOnDisplay(
+ anyInt(), anyString(), anyInt(), anyBoolean(), anyBoolean())).thenReturn(false);
+ mPhoneWindowManager.mActivityTaskManagerInternal = mMockActivityTaskManagerInternal;
+ }
+}
diff --git a/tools/incident_section_gen/main.cpp b/tools/incident_section_gen/main.cpp
index c9c0edc59585..91f875ed9918 100644
--- a/tools/incident_section_gen/main.cpp
+++ b/tools/incident_section_gen/main.cpp
@@ -408,9 +408,10 @@ static bool generateSectionListCpp(Descriptor const* descriptor) {
for (int i=0; i<descriptor->field_count(); i++) {
const FieldDescriptor* field = descriptor->field(i);
- if (field->type() != FieldDescriptor::TYPE_MESSAGE
- && field->type() != FieldDescriptor::TYPE_STRING) {
- continue;
+ if (field->type() != FieldDescriptor::TYPE_MESSAGE &&
+ field->type() != FieldDescriptor::TYPE_STRING &&
+ field->type() != FieldDescriptor::TYPE_BYTES) {
+ continue;
}
const SectionFlags s = getSectionFlags(field);