diff options
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">"هل تريد السماح لتطبيق <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> بالوصول إلى الصور والوسائط والملفات على جهازك؟"</string> <string name="permgrouplab_microphone" msgid="171539900250043464">"الميكروفون"</string> <string name="permgroupdesc_microphone" msgid="4988812113943554584">"تسجيل الصوت"</string> - <string name="permgrouprequest_microphone" msgid="9167492350681916038">"هل تريد السماح لتطبيق <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> بتسجيل الصوت؟"</string> + <string name="permgrouprequest_microphone" msgid="9167492350681916038">"هل تريد السماح لـ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> بتسجيل الصوت؟"</string> <string name="permgrouplab_activityRecognition" msgid="1565108047054378642">"النشاط البدني"</string> <string name="permgroupdesc_activityRecognition" msgid="6949472038320473478">"الوصول إلى بيانات نشاطك البدني"</string> <string name="permgrouprequest_activityRecognition" msgid="7626438016904799383">"هل تريد السماح للتطبيق <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> بالوصول إلى بيانات نشاطك البدني؟"</string> @@ -320,7 +320,7 @@ <string name="permgrouprequest_calllog" msgid="8487355309583773267">"هل تريد السماح لتطبيق <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> بالوصول إلى سجلّ مكالماتك الهاتفية؟"</string> <string name="permgrouplab_phone" msgid="5229115638567440675">"الهاتف"</string> <string name="permgroupdesc_phone" msgid="6234224354060641055">"إجراء مكالمات هاتفية وإدارتها"</string> - <string name="permgrouprequest_phone" msgid="9166979577750581037">"هل تريد السماح لتطبيق <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> بإجراء المكالمات الهاتفية وإدارتها؟"</string> + <string name="permgrouprequest_phone" msgid="9166979577750581037">"هل تريد السماح لـ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> بإجراء المكالمات الهاتفية وإدارتها؟"</string> <string name="permgrouplab_sensors" msgid="4838614103153567532">"أجهزة استشعار الجسم"</string> <string name="permgroupdesc_sensors" msgid="7147968539346634043">"الوصول إلى بيانات المستشعر حول علاماتك الحيوية"</string> <string name="permgrouprequest_sensors" msgid="6349806962814556786">"هل تريد السماح لتطبيق <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> بالدخول إلى بيانات المستشعر حول علاماتك الحيوية؟"</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">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> در حال ارسال تعداد زیادی پیامک است. آیا اجازه میدهید این برنامه همچنان پیامک ارسال کند؟"</string> + <string name="sms_control_title" msgid="7296612781128917719">"درحال ارسال پیامکها"</string> + <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> درحال ارسال تعداد زیادی پیامک است. آیا اجازه میدهید این برنامه همچنان پیامک ارسال کند؟"</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">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> مایل است پیامی به <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> ارسال کند."</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 <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> à 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 <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> à faire et à gérer les appels téléphoniques?"</string> + <string name="permgrouprequest_phone" msgid="9166979577750581037">"Autoriser <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> à 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">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> အား သင့်ဖုန်းရှိ ဓာတ်ပုံများ၊ မီဒီယာနှင့် ဖိုင်များ ဝင်သုံးခွင့်ပေးလိုပါသလား။"</string> <string name="permgrouplab_microphone" msgid="171539900250043464">"မိုက်ခရိုဖုန်း"</string> <string name="permgroupdesc_microphone" msgid="4988812113943554584">"အသံဖမ်းခြင်း"</string> - <string name="permgrouprequest_microphone" msgid="9167492350681916038">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> အား အသံဖမ်းယူခွင့် ပေးလိုပါသလား။"</string> + <string name="permgrouprequest_microphone" msgid="9167492350681916038">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ကို အသံဖမ်းယူခွင့် ပေးလိုပါသလား။"</string> <string name="permgrouplab_activityRecognition" msgid="1565108047054378642">"ကိုယ်လက်လှုပ်ရှားမှု"</string> <string name="permgroupdesc_activityRecognition" msgid="6949472038320473478">"သင့်ကိုယ်လက်လှုပ်ရှားမှုကို ဝင်ကြည့်ရန်"</string> <string name="permgrouprequest_activityRecognition" msgid="7626438016904799383">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> အား သင့်ကိုယ်လက်လှုပ်ရှားမှုကို ဝင်ကြည့်ခွင့် ပေးလိုပါသလား။"</string> @@ -308,7 +308,7 @@ <string name="permgrouprequest_calllog" msgid="8487355309583773267">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> အား သင်၏ခေါ်ဆိုထားသော မှတ်တမ်းများကို သုံးခွင့်ပေးလိုပါသလား။"</string> <string name="permgrouplab_phone" msgid="5229115638567440675">"ဖုန်း"</string> <string name="permgroupdesc_phone" msgid="6234224354060641055">"ဖုန်းခေါ်ဆိုမှုများ ပြုလုပ်ရန်နှင့် စီမံရန်"</string> - <string name="permgrouprequest_phone" msgid="9166979577750581037">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> အား ဖုန်းခေါ်ဆိုမှုများ ပြုလုပ်ခွင့်နှင့် စီမံခွင့်ပေးလိုပါသလား။"</string> + <string name="permgrouprequest_phone" msgid="9166979577750581037">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ကို ဖုန်းခေါ်ဆိုမှုများ ပြုလုပ်ခွင့်နှင့် စီမံခွင့်ပေးလိုပါသလား။"</string> <string name="permgrouplab_sensors" msgid="4838614103153567532">"စက်၏ အာရုံခံစနစ်များ"</string> <string name="permgroupdesc_sensors" msgid="7147968539346634043">"သင်၏ အဓိကကျသော လက္ခဏာများအကြောင်း အာရုံခံကိရိယာဒေတာကို ရယူသုံးစွဲရန်"</string> <string name="permgrouprequest_sensors" msgid="6349806962814556786">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> အား သင်၏ အရေးကြီးသောလက္ခဏာ အာရုံခံကိရိယာ ဒေတာများကို သုံးခွင့်ပေးလိုပါသလား။"</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 <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> 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 <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ipige na kudhibiti simu?"</string> + <string name="permgrouprequest_phone" msgid="9166979577750581037">"Ungependa kuruhusu <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> 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 <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> 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); |