diff options
273 files changed, 3904 insertions, 2315 deletions
diff --git a/api/current.txt b/api/current.txt index 25741b3e79e6..a38ff53577b4 100644 --- a/api/current.txt +++ b/api/current.txt @@ -1357,6 +1357,7 @@ package android { field public static final int toYDelta = 16843209; // 0x10101c9 field public static final int toYScale = 16843205; // 0x10101c5 field public static final int toolbarStyle = 16843946; // 0x10104aa + field public static final int tooltip = 16844084; // 0x1010534 field public static final int top = 16843182; // 0x10101ae field public static final int topBright = 16842955; // 0x10100cb field public static final int topDark = 16842951; // 0x10100c7 @@ -19914,6 +19915,7 @@ package android.media { field public static final int SCO_AUDIO_STATE_CONNECTING = 2; // 0x2 field public static final int SCO_AUDIO_STATE_DISCONNECTED = 0; // 0x0 field public static final int SCO_AUDIO_STATE_ERROR = -1; // 0xffffffff + field public static final int STREAM_ACCESSIBILITY = 10; // 0xa field public static final int STREAM_ALARM = 4; // 0x4 field public static final int STREAM_DTMF = 8; // 0x8 field public static final int STREAM_MUSIC = 3; // 0x3 @@ -37682,6 +37684,7 @@ package android.telephony { field public static final java.lang.String ACTION_CONFIGURE_VOICEMAIL = "android.telephony.action.CONFIGURE_VOICEMAIL"; field public static final java.lang.String ACTION_PHONE_STATE_CHANGED = "android.intent.action.PHONE_STATE"; field public static final java.lang.String ACTION_RESPOND_VIA_MESSAGE = "android.intent.action.RESPOND_VIA_MESSAGE"; + field public static final java.lang.String ACTION_SHOW_VOICEMAIL_NOTIFICATION = "android.telephony.action.SHOW_VOICEMAIL_NOTIFICATION"; field public static final int APPTYPE_CSIM = 4; // 0x4 field public static final int APPTYPE_ISIM = 5; // 0x5 field public static final int APPTYPE_RUIM = 3; // 0x3 @@ -37701,11 +37704,15 @@ package android.telephony { field public static final int DATA_CONNECTING = 1; // 0x1 field public static final int DATA_DISCONNECTED = 0; // 0x0 field public static final int DATA_SUSPENDED = 3; // 0x3 + field public static final java.lang.String EXTRA_CALL_VOICEMAIL_INTENT = "android.telephony.extra.CALL_VOICEMAIL_INTENT"; field public static final java.lang.String EXTRA_INCOMING_NUMBER = "incoming_number"; + field public static final java.lang.String EXTRA_LAUNCH_VOICEMAIL_SETTINGS_INTENT = "android.telephony.extra.LAUNCH_VOICEMAIL_SETTINGS_INTENT"; + field public static final java.lang.String EXTRA_NOTIFICATION_COUNT = "android.telephony.extra.NOTIFICATION_COUNT"; field public static final java.lang.String EXTRA_STATE = "state"; field public static final java.lang.String EXTRA_STATE_IDLE; field public static final java.lang.String EXTRA_STATE_OFFHOOK; field public static final java.lang.String EXTRA_STATE_RINGING; + field public static final java.lang.String EXTRA_VOICEMAIL_NUMBER = "android.telephony.extra.VOICEMAIL_NUMBER"; field public static final int NETWORK_TYPE_1xRTT = 7; // 0x7 field public static final int NETWORK_TYPE_CDMA = 4; // 0x4 field public static final int NETWORK_TYPE_EDGE = 2; // 0x2 @@ -42827,6 +42834,7 @@ package android.view { method public java.lang.Object getTag(int); method public int getTextAlignment(); method public int getTextDirection(); + method public final java.lang.CharSequence getTooltip(); method public final int getTop(); method protected float getTopFadingEdgeStrength(); method protected int getTopPaddingOffset(); @@ -43115,6 +43123,7 @@ package android.view { method public void setTag(int, java.lang.Object); method public void setTextAlignment(int); method public void setTextDirection(int); + method public final void setTooltip(java.lang.CharSequence); method public final void setTop(int); method public void setTouchDelegate(android.view.TouchDelegate); method public final void setTransitionName(java.lang.String); @@ -59087,8 +59096,8 @@ package java.util { method public static void rotate(java.util.List<?>, int); method public static void shuffle(java.util.List<?>); method public static void shuffle(java.util.List<?>, java.util.Random); - method public static <E> java.util.Set<E> singleton(E); - method public static <E> java.util.List<E> singletonList(E); + method public static <T> java.util.Set<T> singleton(T); + method public static <T> java.util.List<T> singletonList(T); method public static <K, V> java.util.Map<K, V> singletonMap(K, V); method public static <T extends java.lang.Comparable<? super T>> void sort(java.util.List<T>); method public static <T> void sort(java.util.List<T>, java.util.Comparator<? super T>); diff --git a/api/system-current.txt b/api/system-current.txt index bfa590c7c85b..bcf4897c8661 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -1468,6 +1468,7 @@ package android { field public static final int toYDelta = 16843209; // 0x10101c9 field public static final int toYScale = 16843205; // 0x10101c5 field public static final int toolbarStyle = 16843946; // 0x10104aa + field public static final int tooltip = 16844084; // 0x1010534 field public static final int top = 16843182; // 0x10101ae field public static final int topBright = 16842955; // 0x10100cb field public static final int topDark = 16842951; // 0x10100c7 @@ -21476,6 +21477,7 @@ package android.media { field public static final int SCO_AUDIO_STATE_CONNECTING = 2; // 0x2 field public static final int SCO_AUDIO_STATE_DISCONNECTED = 0; // 0x0 field public static final int SCO_AUDIO_STATE_ERROR = -1; // 0xffffffff + field public static final int STREAM_ACCESSIBILITY = 10; // 0xa field public static final int STREAM_ALARM = 4; // 0x4 field public static final int STREAM_DTMF = 8; // 0x8 field public static final int STREAM_MUSIC = 3; // 0x3 @@ -35380,6 +35382,7 @@ package android.provider { field public static final java.lang.String ACTION_VR_LISTENER_SETTINGS = "android.settings.VR_LISTENER_SETTINGS"; field public static final java.lang.String ACTION_WEBVIEW_SETTINGS = "android.settings.WEBVIEW_SETTINGS"; field public static final java.lang.String ACTION_WIFI_IP_SETTINGS = "android.settings.WIFI_IP_SETTINGS"; + field public static final java.lang.String ACTION_WIFI_SAVED_NETWORK_SETTINGS = "android.settings.WIFI_SAVED_NETWORK_SETTINGS"; field public static final java.lang.String ACTION_WIFI_SETTINGS = "android.settings.WIFI_SETTINGS"; field public static final java.lang.String ACTION_WIRELESS_SETTINGS = "android.settings.WIRELESS_SETTINGS"; field public static final java.lang.String AUTHORITY = "settings"; @@ -45995,6 +45998,7 @@ package android.view { method public java.lang.Object getTag(int); method public int getTextAlignment(); method public int getTextDirection(); + method public final java.lang.CharSequence getTooltip(); method public final int getTop(); method protected float getTopFadingEdgeStrength(); method protected int getTopPaddingOffset(); @@ -46283,6 +46287,7 @@ package android.view { method public void setTag(int, java.lang.Object); method public void setTextAlignment(int); method public void setTextDirection(int); + method public final void setTooltip(java.lang.CharSequence); method public final void setTop(int); method public void setTouchDelegate(android.view.TouchDelegate); method public final void setTransitionName(java.lang.String); @@ -62614,8 +62619,8 @@ package java.util { method public static void rotate(java.util.List<?>, int); method public static void shuffle(java.util.List<?>); method public static void shuffle(java.util.List<?>, java.util.Random); - method public static <E> java.util.Set<E> singleton(E); - method public static <E> java.util.List<E> singletonList(E); + method public static <T> java.util.Set<T> singleton(T); + method public static <T> java.util.List<T> singletonList(T); method public static <K, V> java.util.Map<K, V> singletonMap(K, V); method public static <T extends java.lang.Comparable<? super T>> void sort(java.util.List<T>); method public static <T> void sort(java.util.List<T>, java.util.Comparator<? super T>); diff --git a/api/test-current.txt b/api/test-current.txt index 4a54733c4f74..fa75e9b4d0a5 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -1357,6 +1357,7 @@ package android { field public static final int toYDelta = 16843209; // 0x10101c9 field public static final int toYScale = 16843205; // 0x10101c5 field public static final int toolbarStyle = 16843946; // 0x10104aa + field public static final int tooltip = 16844084; // 0x1010534 field public static final int top = 16843182; // 0x10101ae field public static final int topBright = 16842955; // 0x10100cb field public static final int topDark = 16842951; // 0x10100c7 @@ -19995,6 +19996,7 @@ package android.media { field public static final int SCO_AUDIO_STATE_CONNECTING = 2; // 0x2 field public static final int SCO_AUDIO_STATE_DISCONNECTED = 0; // 0x0 field public static final int SCO_AUDIO_STATE_ERROR = -1; // 0xffffffff + field public static final int STREAM_ACCESSIBILITY = 10; // 0xa field public static final int STREAM_ALARM = 4; // 0x4 field public static final int STREAM_DTMF = 8; // 0x8 field public static final int STREAM_MUSIC = 3; // 0x3 @@ -37772,6 +37774,7 @@ package android.telephony { field public static final java.lang.String ACTION_CONFIGURE_VOICEMAIL = "android.telephony.action.CONFIGURE_VOICEMAIL"; field public static final java.lang.String ACTION_PHONE_STATE_CHANGED = "android.intent.action.PHONE_STATE"; field public static final java.lang.String ACTION_RESPOND_VIA_MESSAGE = "android.intent.action.RESPOND_VIA_MESSAGE"; + field public static final java.lang.String ACTION_SHOW_VOICEMAIL_NOTIFICATION = "android.telephony.action.SHOW_VOICEMAIL_NOTIFICATION"; field public static final int APPTYPE_CSIM = 4; // 0x4 field public static final int APPTYPE_ISIM = 5; // 0x5 field public static final int APPTYPE_RUIM = 3; // 0x3 @@ -37791,11 +37794,15 @@ package android.telephony { field public static final int DATA_CONNECTING = 1; // 0x1 field public static final int DATA_DISCONNECTED = 0; // 0x0 field public static final int DATA_SUSPENDED = 3; // 0x3 + field public static final java.lang.String EXTRA_CALL_VOICEMAIL_INTENT = "android.telephony.extra.CALL_VOICEMAIL_INTENT"; field public static final java.lang.String EXTRA_INCOMING_NUMBER = "incoming_number"; + field public static final java.lang.String EXTRA_LAUNCH_VOICEMAIL_SETTINGS_INTENT = "android.telephony.extra.LAUNCH_VOICEMAIL_SETTINGS_INTENT"; + field public static final java.lang.String EXTRA_NOTIFICATION_COUNT = "android.telephony.extra.NOTIFICATION_COUNT"; field public static final java.lang.String EXTRA_STATE = "state"; field public static final java.lang.String EXTRA_STATE_IDLE; field public static final java.lang.String EXTRA_STATE_OFFHOOK; field public static final java.lang.String EXTRA_STATE_RINGING; + field public static final java.lang.String EXTRA_VOICEMAIL_NUMBER = "android.telephony.extra.VOICEMAIL_NUMBER"; field public static final int NETWORK_TYPE_1xRTT = 7; // 0x7 field public static final int NETWORK_TYPE_CDMA = 4; // 0x4 field public static final int NETWORK_TYPE_EDGE = 2; // 0x2 @@ -43072,6 +43079,8 @@ package android.view { method public java.lang.Object getTag(int); method public int getTextAlignment(); method public int getTextDirection(); + method public final java.lang.CharSequence getTooltip(); + method public android.view.View getTooltipView(); method public final int getTop(); method protected float getTopFadingEdgeStrength(); method protected int getTopPaddingOffset(); @@ -43360,6 +43369,7 @@ package android.view { method public void setTag(int, java.lang.Object); method public void setTextAlignment(int); method public void setTextDirection(int); + method public final void setTooltip(java.lang.CharSequence); method public final void setTop(int); method public void setTouchDelegate(android.view.TouchDelegate); method public final void setTransitionName(java.lang.String); @@ -43642,10 +43652,14 @@ package android.view { method public static deprecated int getEdgeSlop(); method public static deprecated int getFadingEdgeLength(); method public static deprecated long getGlobalActionKeyTimeout(); + method public static int getHoverTooltipHideShortTimeout(); + method public static int getHoverTooltipHideTimeout(); + method public static int getHoverTooltipShowTimeout(); method public static int getJumpTapTimeout(); method public static int getKeyRepeatDelay(); method public static int getKeyRepeatTimeout(); method public static int getLongPressTimeout(); + method public static int getLongPressTooltipHideTimeout(); method public static deprecated int getMaximumDrawingCacheSize(); method public static deprecated int getMaximumFlingVelocity(); method public static deprecated int getMinimumFlingVelocity(); @@ -59348,8 +59362,8 @@ package java.util { method public static void rotate(java.util.List<?>, int); method public static void shuffle(java.util.List<?>); method public static void shuffle(java.util.List<?>, java.util.Random); - method public static <E> java.util.Set<E> singleton(E); - method public static <E> java.util.List<E> singletonList(E); + method public static <T> java.util.Set<T> singleton(T); + method public static <T> java.util.List<T> singletonList(T); method public static <K, V> java.util.Map<K, V> singletonMap(K, V); method public static <T extends java.lang.Comparable<? super T>> void sort(java.util.List<T>); method public static <T> void sort(java.util.List<T>, java.util.Comparator<? super T>); diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java index 38e35722604c..bfa6d349a9f6 100644 --- a/core/java/android/app/ActivityManagerInternal.java +++ b/core/java/android/app/ActivityManagerInternal.java @@ -61,6 +61,11 @@ public abstract class ActivityManagerInternal { */ public static final int APP_TRANSITION_TIMEOUT = 3; + /** + * Verify that calling app has access to the given provider. + */ + public abstract String checkContentProviderAccess(String authority, int userId); + // Called by the power manager. public abstract void onWakefulnessChanged(int wakefulness); diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 1aa13a9348a9..f052bf7fb717 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -1309,8 +1309,19 @@ public final class ActivityThread { } @Override - public final void updateTimePrefs(boolean is24Hour) { - DateFormat.set24HourTimePref(is24Hour); + public final void updateTimePrefs(int timeFormatPreference) { + final Boolean timeFormatPreferenceBool; + // For convenience we are using the Intent extra values. + if (timeFormatPreference == Intent.EXTRA_TIME_PREF_VALUE_USE_12_HOUR) { + timeFormatPreferenceBool = Boolean.FALSE; + } else if (timeFormatPreference == Intent.EXTRA_TIME_PREF_VALUE_USE_24_HOUR) { + timeFormatPreferenceBool = Boolean.TRUE; + } else { + // timeFormatPreference == Intent.EXTRA_TIME_PREF_VALUE_USE_LOCALE_DEFAULT + // (or unknown). + timeFormatPreferenceBool = null; + } + DateFormat.set24HourTimePref(timeFormatPreferenceBool); } @Override diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 191cc4944e26..ba6bc159cdf2 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -240,7 +240,9 @@ public class AppOpsManager { /** @hide Control whether an application is allowed to run in the background. */ public static final int OP_RUN_IN_BACKGROUND = 63; /** @hide */ - public static final int _NUM_OP = 64; + public static final int OP_AUDIO_ACCESSIBILITY_VOLUME = 64; + /** @hide */ + public static final int _NUM_OP = 65; /** Access to coarse location information. */ public static final String OPSTR_COARSE_LOCATION = "android:coarse_location"; @@ -452,6 +454,7 @@ public class AppOpsManager { OP_TURN_SCREEN_ON, OP_GET_ACCOUNTS, OP_RUN_IN_BACKGROUND, + OP_AUDIO_ACCESSIBILITY_VOLUME, }; /** @@ -523,6 +526,7 @@ public class AppOpsManager { null, OPSTR_GET_ACCOUNTS, null, + null, // OP_AUDIO_ACCESSIBILITY_VOLUME }; /** @@ -594,6 +598,7 @@ public class AppOpsManager { "TURN_ON_SCREEN", "GET_ACCOUNTS", "RUN_IN_BACKGROUND", + "AUDIO_ACCESSIBILITY_VOLUME", }; /** @@ -665,6 +670,7 @@ public class AppOpsManager { null, // no permission for turning the screen on Manifest.permission.GET_ACCOUNTS, null, // no permission for running in background + null, // no permission for changing accessibility volume }; /** @@ -737,6 +743,7 @@ public class AppOpsManager { null, // TURN_ON_SCREEN null, // GET_ACCOUNTS null, // RUN_IN_BACKGROUND + UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ACCESSIBILITY_VOLUME }; /** @@ -808,6 +815,7 @@ public class AppOpsManager { false, // TURN_ON_SCREEN false, // GET_ACCOUNTS false, // RUN_IN_BACKGROUND + false, // AUDIO_ACCESSIBILITY_VOLUME }; /** @@ -878,6 +886,7 @@ public class AppOpsManager { AppOpsManager.MODE_ALLOWED, // OP_TURN_ON_SCREEN AppOpsManager.MODE_ALLOWED, AppOpsManager.MODE_ALLOWED, // OP_RUN_IN_BACKGROUND + AppOpsManager.MODE_ALLOWED, // OP_AUDIO_ACCESSIBILITY_VOLUME }; /** @@ -952,6 +961,7 @@ public class AppOpsManager { false, false, false, + false, // OP_AUDIO_ACCESSIBILITY_VOLUME }; /** diff --git a/core/java/android/app/ApplicationLoaders.java b/core/java/android/app/ApplicationLoaders.java index 6a73829da154..ef2db4a0d795 100644 --- a/core/java/android/app/ApplicationLoaders.java +++ b/core/java/android/app/ApplicationLoaders.java @@ -16,17 +16,19 @@ package android.app; +import android.os.Build; import android.os.Trace; import android.util.ArrayMap; import com.android.internal.os.PathClassLoaderFactory; import dalvik.system.PathClassLoader; -class ApplicationLoaders { +/** @hide */ +public class ApplicationLoaders { public static ApplicationLoaders getDefault() { return gApplicationLoaders; } - public ClassLoader getClassLoader(String zip, int targetSdkVersion, boolean isBundled, + ClassLoader getClassLoader(String zip, int targetSdkVersion, boolean isBundled, String librarySearchPath, String libraryPermittedPath, ClassLoader parent) { /* @@ -80,6 +82,19 @@ class ApplicationLoaders { } } + /** + * Creates a classloader for the WebView APK and places it in the cache of loaders maintained + * by this class. This is used in the WebView zygote, where its presence in the cache speeds up + * startup and enables memory sharing. + */ + public ClassLoader createAndCacheWebViewClassLoader(String packagePath, String libsPath) { + // The correct paths are calculated by WebViewZygote in the system server and passed to + // us here. We hardcode the other parameters: WebView always targets the current SDK, + // does not need to use non-public system libraries, and uses the base classloader as its + // parent to permit usage of the cache. + return getClassLoader(packagePath, Build.VERSION.SDK_INT, false, libsPath, null, null); + } + private static native void setupVulkanLayerPath(ClassLoader classLoader, String librarySearchPath); /** diff --git a/core/java/android/app/IApplicationThread.aidl b/core/java/android/app/IApplicationThread.aidl index 8c9837b6ed4d..6b962b92a66d 100644 --- a/core/java/android/app/IApplicationThread.aidl +++ b/core/java/android/app/IApplicationThread.aidl @@ -138,7 +138,7 @@ oneway interface IApplicationThread { void scheduleTranslucentConversionComplete(IBinder token, boolean timeout); void setProcessState(int state); void scheduleInstallProvider(in ProviderInfo provider); - void updateTimePrefs(boolean is24Hour); + void updateTimePrefs(int timeFormatPreference); void scheduleCancelVisibleBehind(IBinder token); void scheduleBackgroundVisibleBehindChanged(IBinder token, boolean enabled); void scheduleEnterAnimationComplete(IBinder token); @@ -152,4 +152,4 @@ oneway interface IApplicationThread { IVoiceInteractor voiceInteractor); void handleTrustStorageUpdate(); void attachAgent(String path); -}
\ No newline at end of file +} diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java index da99e8005f38..725cc29bd323 100644 --- a/core/java/android/app/KeyguardManager.java +++ b/core/java/android/app/KeyguardManager.java @@ -21,6 +21,7 @@ import android.annotation.RequiresPermission; import android.app.trust.ITrustManager; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; import android.content.pm.UserInfo; import android.os.Binder; import android.os.RemoteException; @@ -45,6 +46,7 @@ public class KeyguardManager { private IWindowManager mWM; private ITrustManager mTrustManager; private IUserManager mUserManager; + private Context mContext; /** * Intent used to prompt user for device credentials. @@ -87,8 +89,12 @@ public class KeyguardManager { Intent intent = new Intent(ACTION_CONFIRM_DEVICE_CREDENTIAL); intent.putExtra(EXTRA_TITLE, title); intent.putExtra(EXTRA_DESCRIPTION, description); - // For security reasons, only allow this to come from system settings. - intent.setPackage("com.android.settings"); + if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH)) { + intent.setPackage("com.google.android.apps.wearable.settings"); + } else { + // For security reasons, only allow this to come from system settings. + intent.setPackage("com.android.settings"); + } return intent; } @@ -109,8 +115,12 @@ public class KeyguardManager { intent.putExtra(EXTRA_TITLE, title); intent.putExtra(EXTRA_DESCRIPTION, description); intent.putExtra(Intent.EXTRA_USER_ID, userId); - // For security reasons, only allow this to come from system settings. - intent.setPackage("com.android.settings"); + if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH)) { + intent.setPackage("com.google.android.apps.wearable.settings"); + } else { + // For security reasons, only allow this to come from system settings. + intent.setPackage("com.android.settings"); + } return intent; } @@ -193,7 +203,8 @@ public class KeyguardManager { } - KeyguardManager() throws ServiceNotFoundException { + KeyguardManager(Context context) throws ServiceNotFoundException { + mContext = context; mWM = WindowManagerGlobal.getWindowManagerService(); mTrustManager = ITrustManager.Stub.asInterface( ServiceManager.getServiceOrThrow(Context.TRUST_SERVICE)); diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java index a38377e67709..94d24e49945b 100644 --- a/core/java/android/app/LoadedApk.java +++ b/core/java/android/app/LoadedApk.java @@ -339,39 +339,43 @@ public final class LoadedApk { * concatenation of both apps' shared library lists. */ - String instrumentationPackageName = activityThread.mInstrumentationPackageName; - String instrumentationAppDir = activityThread.mInstrumentationAppDir; - String[] instrumentationSplitAppDirs = activityThread.mInstrumentationSplitAppDirs; - String instrumentationLibDir = activityThread.mInstrumentationLibDir; - - String instrumentedAppDir = activityThread.mInstrumentedAppDir; - String[] instrumentedSplitAppDirs = activityThread.mInstrumentedSplitAppDirs; - String instrumentedLibDir = activityThread.mInstrumentedLibDir; String[] instrumentationLibs = null; - - if (appDir.equals(instrumentationAppDir) - || appDir.equals(instrumentedAppDir)) { - outZipPaths.clear(); - outZipPaths.add(instrumentationAppDir); - if (instrumentationSplitAppDirs != null) { - Collections.addAll(outZipPaths, instrumentationSplitAppDirs); - } - if (!instrumentationAppDir.equals(instrumentedAppDir)) { - outZipPaths.add(instrumentedAppDir); - if (instrumentedSplitAppDirs != null) { - Collections.addAll(outZipPaths, instrumentedSplitAppDirs); + // activityThread will be null when called from the WebView zygote; just assume + // no instrumentation applies in this case. + if (activityThread != null) { + String instrumentationPackageName = activityThread.mInstrumentationPackageName; + String instrumentationAppDir = activityThread.mInstrumentationAppDir; + String[] instrumentationSplitAppDirs = activityThread.mInstrumentationSplitAppDirs; + String instrumentationLibDir = activityThread.mInstrumentationLibDir; + + String instrumentedAppDir = activityThread.mInstrumentedAppDir; + String[] instrumentedSplitAppDirs = activityThread.mInstrumentedSplitAppDirs; + String instrumentedLibDir = activityThread.mInstrumentedLibDir; + + if (appDir.equals(instrumentationAppDir) + || appDir.equals(instrumentedAppDir)) { + outZipPaths.clear(); + outZipPaths.add(instrumentationAppDir); + if (instrumentationSplitAppDirs != null) { + Collections.addAll(outZipPaths, instrumentationSplitAppDirs); + } + if (!instrumentationAppDir.equals(instrumentedAppDir)) { + outZipPaths.add(instrumentedAppDir); + if (instrumentedSplitAppDirs != null) { + Collections.addAll(outZipPaths, instrumentedSplitAppDirs); + } } - } - if (outLibPaths != null) { - outLibPaths.add(instrumentationLibDir); - if (!instrumentationLibDir.equals(instrumentedLibDir)) { - outLibPaths.add(instrumentedLibDir); + if (outLibPaths != null) { + outLibPaths.add(instrumentationLibDir); + if (!instrumentationLibDir.equals(instrumentedLibDir)) { + outLibPaths.add(instrumentedLibDir); + } } - } - if (!instrumentedAppDir.equals(instrumentationAppDir)) { - instrumentationLibs = getLibrariesFor(instrumentationPackageName); + if (!instrumentedAppDir.equals(instrumentationAppDir)) { + instrumentationLibs = getLibrariesFor(instrumentationPackageName); + } } } diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index f38c0d817047..3ecc309d75da 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -322,10 +322,10 @@ final class SystemServiceRegistry { }}); registerService(Context.KEYGUARD_SERVICE, KeyguardManager.class, - new StaticServiceFetcher<KeyguardManager>() { + new CachedServiceFetcher<KeyguardManager>() { @Override - public KeyguardManager createService() throws ServiceNotFoundException { - return new KeyguardManager(); + public KeyguardManager createService(ContextImpl ctx) throws ServiceNotFoundException { + return new KeyguardManager(ctx); }}); registerService(Context.LAYOUT_INFLATER_SERVICE, LayoutInflater.class, diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index c87de9ade034..50589fea233b 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -4186,13 +4186,21 @@ public class Intent implements Parcelable, Cloneable { = "android.intent.extra.SHUTDOWN_USERSPACE_ONLY"; /** - * Optional boolean extra for {@link #ACTION_TIME_CHANGED} that indicates the - * user has set their time format preferences to the 24 hour format. + * Optional int extra for {@link #ACTION_TIME_CHANGED} that indicates the + * user has set their time format preference. See {@link #EXTRA_TIME_PREF_VALUE_USE_12_HOUR}, + * {@link #EXTRA_TIME_PREF_VALUE_USE_24_HOUR} and + * {@link #EXTRA_TIME_PREF_VALUE_USE_LOCALE_DEFAULT}. The value must not be negative. * * @hide for internal use only. */ public static final String EXTRA_TIME_PREF_24_HOUR_FORMAT = "android.intent.extra.TIME_PREF_24_HOUR_FORMAT"; + /** @hide */ + public static final int EXTRA_TIME_PREF_VALUE_USE_12_HOUR = 0; + /** @hide */ + public static final int EXTRA_TIME_PREF_VALUE_USE_24_HOUR = 1; + /** @hide */ + public static final int EXTRA_TIME_PREF_VALUE_USE_LOCALE_DEFAULT = 2; /** {@hide} */ public static final String EXTRA_REASON = "android.intent.extra.REASON"; diff --git a/core/java/android/content/pm/ParceledListSlice.java b/core/java/android/content/pm/ParceledListSlice.java index 29ea5a07ee9b..945858e6d3c6 100644 --- a/core/java/android/content/pm/ParceledListSlice.java +++ b/core/java/android/content/pm/ParceledListSlice.java @@ -17,15 +17,12 @@ package android.content.pm; import android.os.Binder; -import android.os.Build; import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; import android.os.RemoteException; import android.util.Log; -import dalvik.system.VMRuntime; - import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -130,11 +127,7 @@ public class ParceledListSlice<T extends Parcelable> implements Parcelable { } public List<T> getList() { - if (VMRuntime.getRuntime().getTargetSdkVersion() > Build.VERSION_CODES.N_MR1) { - return Collections.unmodifiableList(mList); - } else { - return mList; - } + return mList; } @Override diff --git a/core/java/android/net/TrafficStats.java b/core/java/android/net/TrafficStats.java index 1ac9fca51b77..e7436be273a3 100644 --- a/core/java/android/net/TrafficStats.java +++ b/core/java/android/net/TrafficStats.java @@ -108,6 +108,26 @@ public class TrafficStats { */ public static final int TAG_SYSTEM_RESTORE = 0xFFFFFF04; + /** @hide */ + public static final int TAG_SYSTEM_DHCP = 0xFFFFFF05; + /** @hide */ + public static final int TAG_SYSTEM_NTP = 0xFFFFFF06; + /** @hide */ + public static final int TAG_SYSTEM_PROBE = 0xFFFFFF07; + /** @hide */ + public static final int TAG_SYSTEM_NEIGHBOR = 0xFFFFFF08; + /** @hide */ + public static final int TAG_SYSTEM_GPS = 0xFFFFFF09; + /** @hide */ + public static final int TAG_SYSTEM_PAC = 0xFFFFFF0A; + + /** + * Sockets that are strictly local on device; never hits network. + * + * @hide + */ + public static final int TAG_SYSTEM_LOCAL = 0xFFFFFFAA; + private static INetworkStatsService sStatsService; private synchronized static INetworkStatsService getStatsService() { diff --git a/core/java/android/os/SystemProperties.java b/core/java/android/os/SystemProperties.java index d31036c532c7..6a751e808d4b 100644 --- a/core/java/android/os/SystemProperties.java +++ b/core/java/android/os/SystemProperties.java @@ -77,6 +77,7 @@ public class SystemProperties { private static native boolean native_get_boolean(String key, boolean def); private static native void native_set(String key, String def); private static native void native_add_change_callback(); + private static native void native_report_sysprop_change(); /** * Get the value for the given key. @@ -195,4 +196,11 @@ public class SystemProperties { } } } + + /* + * Notifies listeners that a system property has changed + */ + public static void reportSyspropChanged() { + native_report_sysprop_change(); + } } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index afbc09bba891..0946906d122d 100755 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -369,6 +369,22 @@ public final class Settings { "android.settings.WIFI_IP_SETTINGS"; /** + * Activity Action: Show settings to allow configuration of Wi-Fi saved networks. + * <p> + * In some cases, a matching Activity may not exist, so ensure you + * safeguard against this. + * <p> + * Input: Nothing. + * <p> + * Output: Nothing. + * @hide + */ + @SystemApi + @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) + public static final String ACTION_WIFI_SAVED_NETWORK_SETTINGS = + "android.settings.WIFI_SAVED_NETWORK_SETTINGS"; + + /** * Activity Action: Show settings to allow configuration of Bluetooth. * <p> * In some cases, a matching Activity may not exist, so ensure you diff --git a/core/java/android/service/autofill/AutoFillService.java b/core/java/android/service/autofill/AutoFillService.java index 3734831b0db2..5f27e3430bc4 100644 --- a/core/java/android/service/autofill/AutoFillService.java +++ b/core/java/android/service/autofill/AutoFillService.java @@ -114,6 +114,11 @@ public abstract class AutoFillService extends Service { private HandlerCaller mHandlerCaller; + /** + * {@inheritDoc} + * + * <strong>NOTE: </strong>if overridden, it must call {@code super.onCreate()}. + */ @Override public void onCreate() { super.onCreate(); diff --git a/core/java/android/service/autofill/IAutoFillCallback.aidl b/core/java/android/service/autofill/IAutoFillCallback.aidl index db8ef96976a2..d6d4f39651da 100644 --- a/core/java/android/service/autofill/IAutoFillCallback.aidl +++ b/core/java/android/service/autofill/IAutoFillCallback.aidl @@ -21,7 +21,7 @@ import java.util.List; /** * @hide */ -interface IAutoFillCallback { +oneway interface IAutoFillCallback { void autofill(in List values); void showError(String message); } diff --git a/core/java/android/service/autofill/IAutoFillManagerService.aidl b/core/java/android/service/autofill/IAutoFillManagerService.aidl index cab073f7045f..76a25614f8ec 100644 --- a/core/java/android/service/autofill/IAutoFillManagerService.aidl +++ b/core/java/android/service/autofill/IAutoFillManagerService.aidl @@ -23,7 +23,7 @@ import android.os.Bundle; * * {@hide} */ -interface IAutoFillManagerService { +oneway interface IAutoFillManagerService { /** * Request auto-fill on the top activity of a given user. diff --git a/core/java/android/service/autofill/IAutoFillService.aidl b/core/java/android/service/autofill/IAutoFillService.aidl index e3e911c39215..bb122e5eff7d 100644 --- a/core/java/android/service/autofill/IAutoFillService.aidl +++ b/core/java/android/service/autofill/IAutoFillService.aidl @@ -25,7 +25,7 @@ import com.android.internal.os.IResultReceiver; * @hide */ interface IAutoFillService { - void onConnected(); - void onDisconnected(); + oneway void onConnected(); + oneway void onDisconnected(); IResultReceiver getAssistReceiver(); } diff --git a/core/java/android/util/BootTimingsTraceLog.java b/core/java/android/util/BootTimingsTraceLog.java new file mode 100644 index 000000000000..2e4319cca0b9 --- /dev/null +++ b/core/java/android/util/BootTimingsTraceLog.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package android.util; + +import android.os.Build; +import android.os.SystemClock; +import android.os.Trace; + +import java.util.ArrayDeque; +import java.util.Deque; + +/** + * Helper class for reporting boot timing metrics. + * @hide + */ +public class BootTimingsTraceLog { + // Debug boot time for every step if it's non-user build. + private static final boolean DEBUG_BOOT_TIME = !"user".equals(Build.TYPE); + private final Deque<Pair<String, Long>> mStartTimes + = DEBUG_BOOT_TIME ? new ArrayDeque<>() : null; + private final String mTag; + private long mTraceTag; + + public BootTimingsTraceLog(String tag, long traceTag) { + mTag = tag; + mTraceTag = traceTag; + } + + public void traceBegin(String name) { + Trace.traceBegin(mTraceTag, name); + if (DEBUG_BOOT_TIME) { + mStartTimes.push(Pair.create(name, SystemClock.elapsedRealtime())); + } + } + + public void traceEnd() { + Trace.traceEnd(mTraceTag); + if (!DEBUG_BOOT_TIME) { + return; + } + if (mStartTimes.peek() == null) { + Slog.w(mTag, "traceEnd called more times than traceBegin"); + return; + } + Pair<String, Long> event = mStartTimes.pop(); + // Log the duration so it can be parsed by external tools for performance reporting + Slog.d(mTag, event.first + " took to complete: " + + (SystemClock.elapsedRealtime() - event.second) + "ms"); + } +} diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 02a85216cc20..84d7548363d1 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -37,6 +37,7 @@ import android.annotation.LayoutRes; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Size; +import android.annotation.TestApi; import android.annotation.UiThread; import android.content.ClipData; import android.content.Context; @@ -111,6 +112,7 @@ import android.widget.ScrollBarDrawable; import com.android.internal.R; import com.android.internal.util.Predicate; +import com.android.internal.view.TooltipPopup; import com.android.internal.view.menu.MenuBuilder; import com.android.internal.widget.ScrollBarUtils; @@ -1196,6 +1198,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, private static Paint sDebugPaint; + /** + * <p>Indicates this view can display a tooltip on hover or long press.</p> + * {@hide} + */ + static final int TOOLTIP = 0x40000000; + /** @hide */ @IntDef(flag = true, value = { @@ -3619,6 +3627,39 @@ public class View implements Drawable.Callback, KeyEvent.Callback, ListenerInfo mListenerInfo; + private static class TooltipInfo { + /** + * Text to be displayed in a tooltip popup. + */ + @Nullable + CharSequence mTooltip; + + /** + * View-relative position of the tooltip anchor point. + */ + int mAnchorX; + int mAnchorY; + + /** + * The tooltip popup. + */ + @Nullable + TooltipPopup mTooltipPopup; + + /** + * Set to true if the tooltip was shown as a result of a long click. + */ + boolean mTooltipFromLongClick; + + /** + * Keep these Runnables so that they can be used to reschedule. + */ + Runnable mShowTooltipRunnable; + Runnable mHideTooltipRunnable; + } + + TooltipInfo mTooltipInfo; + // Temporary values used to hold (x,y) coordinates when delegating from the // two-arg performLongClick() method to the legacy no-arg version. private float mLongClickX = Float.NaN; @@ -4576,6 +4617,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } break; + case R.styleable.View_tooltip: + setTooltip(a.getText(attr)); + break; } } @@ -5712,6 +5756,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, final boolean isAnchored = !Float.isNaN(x) && !Float.isNaN(y); handled = isAnchored ? showContextMenu(x, y) : showContextMenu(); } + if ((mViewFlags & TOOLTIP) == TOOLTIP) { + if (!handled) { + handled = showLongClickTooltip((int) x, (int) y); + } + } if (handled) { performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); } @@ -10603,17 +10652,21 @@ public class View implements Drawable.Callback, KeyEvent.Callback, return true; } - // Long clickable items don't necessarily have to be clickable. - if (((mViewFlags & CLICKABLE) == CLICKABLE - || (mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) - && (event.getRepeatCount() == 0)) { - // For the purposes of menu anchoring and drawable hotspots, - // key events are considered to be at the center of the view. - final float x = getWidth() / 2f; - final float y = getHeight() / 2f; - setPressed(true, x, y); - checkForLongClick(0, x, y); - return true; + if (event.getRepeatCount() == 0) { + // Long clickable items don't necessarily have to be clickable. + final boolean clickable = (mViewFlags & CLICKABLE) == CLICKABLE + || (mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE; + if (clickable || (mViewFlags & TOOLTIP) == TOOLTIP) { + // For the purposes of menu anchoring and drawable hotspots, + // key events are considered to be at the center of the view. + final float x = getWidth() / 2f; + final float y = getHeight() / 2f; + if (clickable) { + setPressed(true, x, y); + } + checkForLongClick(0, x, y); + return true; + } } } @@ -11160,15 +11213,17 @@ public class View implements Drawable.Callback, KeyEvent.Callback, final int viewFlags = mViewFlags; final int action = event.getAction(); + final boolean clickable = ((viewFlags & CLICKABLE) == CLICKABLE + || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) + || (viewFlags & CONTEXT_CLICKABLE) == CONTEXT_CLICKABLE; + if ((viewFlags & ENABLED_MASK) == DISABLED) { if (action == MotionEvent.ACTION_UP && (mPrivateFlags & PFLAG_PRESSED) != 0) { setPressed(false); } // A disabled view that is clickable still consumes the touch // events, it just doesn't respond to them. - return (((viewFlags & CLICKABLE) == CLICKABLE - || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) - || (viewFlags & CONTEXT_CLICKABLE) == CONTEXT_CLICKABLE); + return clickable; } if (mTouchDelegate != null) { if (mTouchDelegate.onTouchEvent(event)) { @@ -11176,11 +11231,20 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } - if (((viewFlags & CLICKABLE) == CLICKABLE || - (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) || - (viewFlags & CONTEXT_CLICKABLE) == CONTEXT_CLICKABLE) { + if (clickable || (viewFlags & TOOLTIP) == TOOLTIP) { switch (action) { case MotionEvent.ACTION_UP: + if ((viewFlags & TOOLTIP) == TOOLTIP) { + handleTooltipUp(); + } + if (!clickable) { + removeTapCallback(); + removeLongPressCallback(); + mInContextButtonPress = false; + mHasPerformedLongPress = false; + mIgnoreNextUpEvent = false; + break; + } boolean prepressed = (mPrivateFlags & PFLAG_PREPRESSED) != 0; if ((mPrivateFlags & PFLAG_PRESSED) != 0 || prepressed) { // take focus if we don't have it already and we should in @@ -11196,7 +11260,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // state now (before scheduling the click) to ensure // the user sees it. setPressed(true, x, y); - } + } if (!mHasPerformedLongPress && !mIgnoreNextUpEvent) { // This is a tap, so remove the longpress check @@ -11236,6 +11300,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, case MotionEvent.ACTION_DOWN: mHasPerformedLongPress = false; + if (!clickable) { + checkForLongClick(0, x, y); + break; + } + if (performButtonActionOnTouchDown(event)) { break; } @@ -11261,7 +11330,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, break; case MotionEvent.ACTION_CANCEL: - setPressed(false); + if (clickable) { + setPressed(false); + } removeTapCallback(); removeLongPressCallback(); mInContextButtonPress = false; @@ -11270,16 +11341,17 @@ public class View implements Drawable.Callback, KeyEvent.Callback, break; case MotionEvent.ACTION_MOVE: - drawableHotspotChanged(x, y); + if (clickable) { + drawableHotspotChanged(x, y); + } // Be lenient about moving outside of buttons if (!pointInView(x, y, mTouchSlop)) { // Outside button + // Remove any future long press/tap checks removeTapCallback(); + removeLongPressCallback(); if ((mPrivateFlags & PFLAG_PRESSED) != 0) { - // Remove any future long press/tap checks - removeLongPressCallback(); - setPressed(false); } } @@ -11311,7 +11383,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ private void removeLongPressCallback() { if (mPendingCheckForLongPress != null) { - removeCallbacks(mPendingCheckForLongPress); + removeCallbacks(mPendingCheckForLongPress); } } @@ -15379,6 +15451,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, cleanupDraw(); mCurrentAnimation = null; + + if ((mViewFlags & TOOLTIP) == TOOLTIP) { + hideTooltip(); + } } private void cleanupDraw() { @@ -21031,7 +21107,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } private void checkForLongClick(int delayOffset, float x, float y) { - if ((mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) { + if ((mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE || (mViewFlags & TOOLTIP) == TOOLTIP) { mHasPerformedLongPress = false; if (mPendingCheckForLongPress == null) { @@ -21039,6 +21115,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } mPendingCheckForLongPress.setAnchor(x, y); mPendingCheckForLongPress.rememberWindowAttachCount(); + mPendingCheckForLongPress.rememberPressedState(); postDelayed(mPendingCheckForLongPress, ViewConfiguration.getLongPressTimeout() - delayOffset); } @@ -22439,10 +22516,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, private int mOriginalWindowAttachCount; private float mX; private float mY; + private boolean mOriginalPressedState; @Override public void run() { - if (isPressed() && (mParent != null) + if ((mOriginalPressedState == isPressed()) && (mParent != null) && mOriginalWindowAttachCount == mWindowAttachCount) { if (performLongClick(mX, mY)) { mHasPerformedLongPress = true; @@ -22458,6 +22536,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, public void rememberWindowAttachCount() { mOriginalWindowAttachCount = mWindowAttachCount; } + + public void rememberPressedState() { + mOriginalPressedState = isPressed(); + } } private final class CheckForTap implements Runnable { @@ -23246,6 +23328,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ public Surface mDragSurface; + + /** + * The view that currently has a tooltip displayed. + */ + View mTooltipHost; + /** * Creates a new set of attachment information with the specified * events handler and thread. @@ -23982,4 +24070,167 @@ public class View implements Drawable.Callback, KeyEvent.Callback, return mAttachInfo.mTmpLocation[0] == insets.getStableInsetLeft() && mAttachInfo.mTmpLocation[1] == insets.getStableInsetTop(); } + + /** + * Sets the tooltip text which will be displayed in a small popup next to the view. + * <p> + * The tooltip will be displayed: + * <li>On long click, unless is not handled otherwise (by OnLongClickListener or a context + * menu). </li> + * <li>On hover, after a brief delay since the pointer has stopped moving </li> + * + * @param tooltip the tooltip text, or null if no tooltip is required + */ + public final void setTooltip(@Nullable CharSequence tooltip) { + if (TextUtils.isEmpty(tooltip)) { + setFlags(0, TOOLTIP); + hideTooltip(); + mTooltipInfo = null; + } else { + setFlags(TOOLTIP, TOOLTIP); + if (mTooltipInfo == null) { + mTooltipInfo = new TooltipInfo(); + mTooltipInfo.mShowTooltipRunnable = this::showHoverTooltip; + mTooltipInfo.mHideTooltipRunnable = this::hideTooltip; + } + mTooltipInfo.mTooltip = tooltip; + if (mTooltipInfo.mTooltipPopup != null && mTooltipInfo.mTooltipPopup.isShowing()) { + mTooltipInfo.mTooltipPopup.updateContent(mTooltipInfo.mTooltip); + } + } + } + + /** + * Returns the view's tooltip text. + * + * @return the tooltip text + */ + @Nullable + public final CharSequence getTooltip() { + return mTooltipInfo != null ? mTooltipInfo.mTooltip : null; + } + + private boolean showTooltip(int x, int y, boolean fromLongClick) { + if (mAttachInfo == null) { + return false; + } + if ((mViewFlags & ENABLED_MASK) != ENABLED) { + return false; + } + final CharSequence tooltipText = getTooltip(); + if (TextUtils.isEmpty(tooltipText)) { + return false; + } + hideTooltip(); + mTooltipInfo.mTooltipFromLongClick = fromLongClick; + mTooltipInfo.mTooltipPopup = new TooltipPopup(getContext()); + mTooltipInfo.mTooltipPopup.show(this, x, y, tooltipText); + mAttachInfo.mTooltipHost = this; + return true; + } + + void hideTooltip() { + if (mTooltipInfo == null) { + return; + } + removeCallbacks(mTooltipInfo.mShowTooltipRunnable); + if (mTooltipInfo.mTooltipPopup == null) { + return; + } + mTooltipInfo.mTooltipPopup.hide(); + mTooltipInfo.mTooltipPopup = null; + mTooltipInfo.mTooltipFromLongClick = false; + if (mAttachInfo != null) { + mAttachInfo.mTooltipHost = null; + } + } + + private boolean showLongClickTooltip(int x, int y) { + removeCallbacks(mTooltipInfo.mShowTooltipRunnable); + removeCallbacks(mTooltipInfo.mHideTooltipRunnable); + return showTooltip(x, y, true); + } + + private void showHoverTooltip() { + showTooltip(mTooltipInfo.mAnchorX, mTooltipInfo.mAnchorY, false); + } + + boolean dispatchTooltipHoverEvent(MotionEvent event) { + if (mTooltipInfo == null) { + return false; + } + switch(event.getAction()) { + case MotionEvent.ACTION_HOVER_MOVE: + if ((mViewFlags & TOOLTIP) != TOOLTIP || (mViewFlags & ENABLED_MASK) != ENABLED) { + break; + } + if (!mTooltipInfo.mTooltipFromLongClick) { + if (mTooltipInfo.mTooltipPopup == null) { + // Schedule showing the tooltip after a timeout. + mTooltipInfo.mAnchorX = (int) event.getX(); + mTooltipInfo.mAnchorY = (int) event.getY(); + removeCallbacks(mTooltipInfo.mShowTooltipRunnable); + postDelayed(mTooltipInfo.mShowTooltipRunnable, + ViewConfiguration.getHoverTooltipShowTimeout()); + } + + // Hide hover-triggered tooltip after a period of inactivity. + // Match the timeout used by NativeInputManager to hide the mouse pointer + // (depends on SYSTEM_UI_FLAG_LOW_PROFILE being set). + final int timeout; + if ((getWindowSystemUiVisibility() & SYSTEM_UI_FLAG_LOW_PROFILE) + == SYSTEM_UI_FLAG_LOW_PROFILE) { + timeout = ViewConfiguration.getHoverTooltipHideShortTimeout(); + } else { + timeout = ViewConfiguration.getHoverTooltipHideTimeout(); + } + removeCallbacks(mTooltipInfo.mHideTooltipRunnable); + postDelayed(mTooltipInfo.mHideTooltipRunnable, timeout); + } + return true; + + case MotionEvent.ACTION_HOVER_EXIT: + if (!mTooltipInfo.mTooltipFromLongClick) { + hideTooltip(); + } + break; + } + return false; + } + + void handleTooltipKey(KeyEvent event) { + switch (event.getAction()) { + case KeyEvent.ACTION_DOWN: + if (event.getRepeatCount() == 0) { + hideTooltip(); + } + break; + + case KeyEvent.ACTION_UP: + handleTooltipUp(); + break; + } + } + + private void handleTooltipUp() { + if (mTooltipInfo == null || mTooltipInfo.mTooltipPopup == null) { + return; + } + removeCallbacks(mTooltipInfo.mHideTooltipRunnable); + postDelayed(mTooltipInfo.mHideTooltipRunnable, + ViewConfiguration.getLongPressTooltipHideTimeout()); + } + + /** + * @return The content view of the tooltip popup currently being shown, or null if the tooltip + * is not showing. + * @hide + */ + @TestApi + public View getTooltipView() { + if (mTooltipInfo == null || mTooltipInfo.mTooltipPopup == null) { + return null; + } + return mTooltipInfo.mTooltipPopup.getContentView(); + } } diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java index 33b488fbc6b4..6d2f850b94f4 100644 --- a/core/java/android/view/ViewConfiguration.java +++ b/core/java/android/view/ViewConfiguration.java @@ -16,6 +16,7 @@ package android.view; +import android.annotation.TestApi; import android.app.AppGlobals; import android.content.Context; import android.content.res.Configuration; @@ -230,6 +231,29 @@ public class ViewConfiguration { private static final long ACTION_MODE_HIDE_DURATION_DEFAULT = 2000; /** + * Defines the duration in milliseconds before an end of a long press causes a tooltip to be + * hidden. + */ + private static final int LONG_PRESS_TOOLTIP_HIDE_TIMEOUT = 1500; + + /** + * Defines the duration in milliseconds before a hover event causes a tooltip to be shown. + */ + private static final int HOVER_TOOLTIP_SHOW_TIMEOUT = 500; + + /** + * Defines the duration in milliseconds before mouse inactivity causes a tooltip to be hidden. + * (default variant to be used when {@link View#SYSTEM_UI_FLAG_LOW_PROFILE} is not set). + */ + private static final int HOVER_TOOLTIP_HIDE_TIMEOUT = 15000; + + /** + * Defines the duration in milliseconds before mouse inactivity causes a tooltip to be hidden + * (short version to be used when {@link View#SYSTEM_UI_FLAG_LOW_PROFILE} is set). + */ + private static final int HOVER_TOOLTIP_HIDE_SHORT_TIMEOUT = 3000; + + /** * Configuration values for overriding {@link #hasPermanentMenuKey()} behavior. * These constants must match the definition in res/values/config.xml. */ @@ -800,4 +824,43 @@ public class ViewConfiguration { public boolean isFadingMarqueeEnabled() { return mFadingMarqueeEnabled; } + + /** + * @return the duration in milliseconds before an end of a long press causes a tooltip to be + * hidden + * @hide + */ + @TestApi + public static int getLongPressTooltipHideTimeout() { + return LONG_PRESS_TOOLTIP_HIDE_TIMEOUT; + } + + /** + * @return the duration in milliseconds before a hover event causes a tooltip to be shown + * @hide + */ + @TestApi + public static int getHoverTooltipShowTimeout() { + return HOVER_TOOLTIP_SHOW_TIMEOUT; + } + + /** + * @return the duration in milliseconds before mouse inactivity causes a tooltip to be hidden + * (default variant to be used when {@link View#SYSTEM_UI_FLAG_LOW_PROFILE} is not set). + * @hide + */ + @TestApi + public static int getHoverTooltipHideTimeout() { + return HOVER_TOOLTIP_HIDE_TIMEOUT; + } + + /** + * @return the duration in milliseconds before mouse inactivity causes a tooltip to be hidden + * (shorter variant to be used when {@link View#SYSTEM_UI_FLAG_LOW_PROFILE} is set). + * @hide + */ + @TestApi + public static int getHoverTooltipHideShortTimeout() { + return HOVER_TOOLTIP_HIDE_SHORT_TIMEOUT; + } } diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index e39cb96ce59e..c0191ce0b791 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -199,6 +199,13 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager // It might not have actually handled the hover event. private boolean mHoveredSelf; + // The child capable of showing a tooltip and currently under the pointer. + private View mTooltipHoverTarget; + + // True if the view group is capable of showing a tooltip and the pointer is directly + // over the view group but not one of its child views. + private boolean mTooltipHoveredSelf; + /** * Internal flags. * @@ -1970,6 +1977,104 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } } + @Override + boolean dispatchTooltipHoverEvent(MotionEvent event) { + final int action = event.getAction(); + switch (action) { + case MotionEvent.ACTION_HOVER_ENTER: + break; + + case MotionEvent.ACTION_HOVER_MOVE: + View newTarget = null; + + // Check what the child under the pointer says about the tooltip. + final int childrenCount = mChildrenCount; + if (childrenCount != 0) { + final float x = event.getX(); + final float y = event.getY(); + + final ArrayList<View> preorderedList = buildOrderedChildList(); + final boolean customOrder = preorderedList == null + && isChildrenDrawingOrderEnabled(); + final View[] children = mChildren; + for (int i = childrenCount - 1; i >= 0; i--) { + final int childIndex = + getAndVerifyPreorderedIndex(childrenCount, i, customOrder); + final View child = + getAndVerifyPreorderedView(preorderedList, children, childIndex); + final PointF point = getLocalPoint(); + if (isTransformedTouchPointInView(x, y, child, point)) { + if (dispatchTooltipHoverEvent(event, child)) { + newTarget = child; + } + break; + } + } + if (preorderedList != null) preorderedList.clear(); + } + + if (mTooltipHoverTarget != newTarget) { + if (mTooltipHoverTarget != null) { + event.setAction(MotionEvent.ACTION_HOVER_EXIT); + mTooltipHoverTarget.dispatchTooltipHoverEvent(event); + event.setAction(action); + } + mTooltipHoverTarget = newTarget; + } + + if (mTooltipHoverTarget != null) { + if (mTooltipHoveredSelf) { + mTooltipHoveredSelf = false; + event.setAction(MotionEvent.ACTION_HOVER_EXIT); + super.dispatchTooltipHoverEvent(event); + event.setAction(action); + } + return true; + } + + mTooltipHoveredSelf = super.dispatchTooltipHoverEvent(event); + return mTooltipHoveredSelf; + + case MotionEvent.ACTION_HOVER_EXIT: + if (mTooltipHoverTarget != null) { + mTooltipHoverTarget.dispatchTooltipHoverEvent(event); + mTooltipHoverTarget = null; + } else if (mTooltipHoveredSelf) { + super.dispatchTooltipHoverEvent(event); + mTooltipHoveredSelf = false; + } + break; + } + return false; + } + + private boolean dispatchTooltipHoverEvent(MotionEvent event, View child) { + final boolean result; + if (!child.hasIdentityMatrix()) { + MotionEvent transformedEvent = getTransformedMotionEvent(event, child); + result = child.dispatchTooltipHoverEvent(transformedEvent); + transformedEvent.recycle(); + } else { + final float offsetX = mScrollX - child.mLeft; + final float offsetY = mScrollY - child.mTop; + event.offsetLocation(offsetX, offsetY); + result = child.dispatchTooltipHoverEvent(event); + event.offsetLocation(-offsetX, -offsetY); + } + return result; + } + + private void exitTooltipHoverTargets() { + if (mTooltipHoveredSelf || mTooltipHoverTarget != null) { + final long now = SystemClock.uptimeMillis(); + MotionEvent event = MotionEvent.obtain(now, now, + MotionEvent.ACTION_HOVER_EXIT, 0.0f, 0.0f, 0); + event.setSource(InputDevice.SOURCE_TOUCHSCREEN); + dispatchTooltipHoverEvent(event); + event.recycle(); + } + } + /** @hide */ @Override protected boolean hasHoveredChild() { @@ -3186,6 +3291,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager // Similarly, set ACTION_EXIT to all hover targets and clear them. exitHoverTargets(); + exitTooltipHoverTargets(); // In case view is detached while transition is running mLayoutCalledWhileSuppressed = false; diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 1ff8fb0bd8ee..e030e767732e 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -3589,6 +3589,10 @@ public final class ViewRootImpl implements ViewParent, mAttachInfo.mKeyDispatchState.reset(); mView.dispatchWindowFocusChanged(hasWindowFocus); mAttachInfo.mTreeObserver.dispatchOnWindowFocusChange(hasWindowFocus); + + if (mAttachInfo.mTooltipHost != null) { + mAttachInfo.mTooltipHost.hideTooltip(); + } } // Note: must be done after the focus change callbacks, @@ -4206,6 +4210,10 @@ public final class ViewRootImpl implements ViewParent, private int processKeyEvent(QueuedInputEvent q) { final KeyEvent event = (KeyEvent)q.mEvent; + if (mAttachInfo.mTooltipHost != null) { + mAttachInfo.mTooltipHost.handleTooltipKey(event); + } + // If the key's purpose is to exit touch mode then we consume it // and consider it handled. if (checkForLeavingTouchModeAndConsume(event)) { @@ -4232,6 +4240,10 @@ public final class ViewRootImpl implements ViewParent, ensureTouchMode(true); } + if (action == MotionEvent.ACTION_DOWN && mAttachInfo.mTooltipHost != null) { + mAttachInfo.mTooltipHost.hideTooltip(); + } + // Offset the scroll position. if (mCurScrollY != 0) { event.offsetLocation(0, mCurScrollY); @@ -4425,6 +4437,7 @@ public final class ViewRootImpl implements ViewParent, mAttachInfo.mHandlingPointerEvent = true; boolean handled = eventTarget.dispatchPointerEvent(event); maybeUpdatePointerIcon(event); + maybeUpdateTooltip(event); mAttachInfo.mHandlingPointerEvent = false; if (mAttachInfo.mUnbufferedDispatchRequested && !mUnbufferedInputDispatch) { mUnbufferedInputDispatch = true; @@ -4512,6 +4525,27 @@ public final class ViewRootImpl implements ViewParent, return true; } + private void maybeUpdateTooltip(MotionEvent event) { + if (event.getPointerCount() != 1) { + return; + } + final int action = event.getActionMasked(); + if (action != MotionEvent.ACTION_HOVER_ENTER + && action != MotionEvent.ACTION_HOVER_MOVE + && action != MotionEvent.ACTION_HOVER_EXIT) { + return; + } + AccessibilityManager manager = AccessibilityManager.getInstance(mContext); + if (manager.isEnabled() && manager.isTouchExplorationEnabled()) { + return; + } + if (mView == null) { + Slog.d(mTag, "maybeUpdateTooltip called after view was removed"); + return; + } + mView.dispatchTooltipHoverEvent(event); + } + /** * Performs synthesis of new input events from unhandled input events. */ diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java index c14789506888..eb0c44c3a07d 100644 --- a/core/java/android/webkit/WebViewFactory.java +++ b/core/java/android/webkit/WebViewFactory.java @@ -57,7 +57,9 @@ import java.util.zip.ZipFile; @SystemApi public final class WebViewFactory { - private static final String CHROMIUM_WEBVIEW_FACTORY = + // visible for WebViewZygoteInit to look up the class by reflection and call preloadInZygote. + /** @hide */ + public static final String CHROMIUM_WEBVIEW_FACTORY = "com.android.webview.chromium.WebViewChromiumFactoryProvider"; private static final String CHROMIUM_WEBVIEW_FACTORY_METHOD = "create"; diff --git a/core/java/android/webkit/WebViewZygote.java b/core/java/android/webkit/WebViewZygote.java index bc6e7b4a9dd3..c2069741d6cd 100644 --- a/core/java/android/webkit/WebViewZygote.java +++ b/core/java/android/webkit/WebViewZygote.java @@ -16,14 +16,19 @@ package android.webkit; +import android.app.LoadedApk; import android.content.pm.PackageInfo; import android.os.Build; import android.os.SystemService; import android.os.ZygoteProcess; +import android.text.TextUtils; import android.util.Log; +import java.io.File; import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import java.util.concurrent.TimeoutException; /** @hide */ @@ -122,11 +127,21 @@ public class WebViewZygote { try { sZygote = new ZygoteProcess("webview_zygote", null); - String packagePath = sPackage.applicationInfo.sourceDir; - String libsPath = sPackage.applicationInfo.nativeLibraryDir; - - Log.d(LOGTAG, "Preloading package " + packagePath + " " + libsPath); - sZygote.preloadPackageForAbi(packagePath, libsPath, Build.SUPPORTED_ABIS[0]); + // All the work below is usually done by LoadedApk, but the zygote can't talk to + // PackageManager or construct a LoadedApk since it's single-threaded pre-fork, so + // doesn't have an ActivityThread and can't use Binder. + // Instead, figure out the paths here, in the system server where we have access to + // the package manager. Reuse the logic from LoadedApk to determine the correct + // paths and pass them to the zygote as strings. + final List<String> zipPaths = new ArrayList<>(10); + final List<String> libPaths = new ArrayList<>(10); + LoadedApk.makePaths(null, sPackage.applicationInfo, zipPaths, libPaths); + final String librarySearchPath = TextUtils.join(File.pathSeparator, libPaths); + final String zip = (zipPaths.size() == 1) ? zipPaths.get(0) : + TextUtils.join(File.pathSeparator, zipPaths); + + Log.d(LOGTAG, "Preloading package " + zip + " " + librarySearchPath); + sZygote.preloadPackageForAbi(zip, librarySearchPath, Build.SUPPORTED_ABIS[0]); } catch (Exception e) { Log.e(LOGTAG, "Error connecting to " + serviceName, e); sZygote = null; diff --git a/core/java/com/android/internal/os/WebViewZygoteInit.java b/core/java/com/android/internal/os/WebViewZygoteInit.java index 11dd0e8771a7..d968e3c939ab 100644 --- a/core/java/com/android/internal/os/WebViewZygoteInit.java +++ b/core/java/com/android/internal/os/WebViewZygoteInit.java @@ -16,14 +16,17 @@ package com.android.internal.os; +import android.app.ApplicationLoaders; import android.net.LocalSocket; import android.os.Build; import android.system.ErrnoException; import android.system.Os; import android.text.TextUtils; import android.util.Log; +import android.webkit.WebViewFactory; import java.io.IOException; +import java.lang.reflect.InvocationTargetException; /** * Startup class for the WebView zygote process. @@ -52,7 +55,27 @@ class WebViewZygoteInit { @Override protected boolean handlePreloadPackage(String packagePath, String libsPath) { - // TODO: Use preload information to setup the ClassLoader. + // Ask ApplicationLoaders to create and cache a classloader for the WebView APK so that + // our children will reuse the same classloader instead of creating their own. + // This enables us to preload Java and native code in the webview zygote process and + // have the preloaded versions actually be used post-fork. + ClassLoader loader = ApplicationLoaders.getDefault().createAndCacheWebViewClassLoader( + packagePath, libsPath); + + // Once we have the classloader, look up the WebViewFactoryProvider implementation and + // call preloadInZygote() on it to give it the opportunity to preload the native library + // and perform any other initialisation work that should be shared among the children. + try { + Class providerClass = Class.forName(WebViewFactory.CHROMIUM_WEBVIEW_FACTORY, true, + loader); + Object result = providerClass.getMethod("preloadInZygote").invoke(null); + if (!((Boolean)result).booleanValue()) { + Log.e(TAG, "preloadInZygote returned false"); + } + } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | + IllegalAccessException | InvocationTargetException e) { + Log.e(TAG, "Exception while preloading package", e); + } return false; } } diff --git a/core/java/com/android/internal/os/WrapperInit.java b/core/java/com/android/internal/os/WrapperInit.java index 594b6ab72ef3..c03bcdf3a834 100644 --- a/core/java/com/android/internal/os/WrapperInit.java +++ b/core/java/com/android/internal/os/WrapperInit.java @@ -17,6 +17,8 @@ package com.android.internal.os; import android.os.Process; +import android.os.Trace; +import android.util.BootTimingsTraceLog; import android.util.Slog; import dalvik.system.VMRuntime; @@ -75,7 +77,8 @@ public class WrapperInit { } // Mimic system Zygote preloading. - ZygoteInit.preload(); + ZygoteInit.preload(new BootTimingsTraceLog("WrapperInitTiming", + Trace.TRACE_TAG_DALVIK)); // Launch the application. String[] runtimeArgs = new String[args.length - 2]; diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index e1118d84ed7b..cdd267e8184f 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -36,11 +36,13 @@ import android.system.ErrnoException; import android.system.Os; import android.system.OsConstants; import android.text.Hyphenator; +import android.util.BootTimingsTraceLog; import android.util.EventLog; import android.util.Log; import android.webkit.WebViewFactory; import android.widget.TextView; +import com.android.internal.logging.MetricsLogger; import com.android.internal.os.InstallerConnection.InstallerException; import dalvik.system.DexFile; @@ -106,20 +108,20 @@ public class ZygoteInit { private static final int ROOT_UID = 0; private static final int ROOT_GID = 0; - static void preload() { + static void preload(BootTimingsTraceLog bootTimingsTraceLog) { Log.d(TAG, "begin preload"); - Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "BeginIcuCachePinning"); + bootTimingsTraceLog.traceBegin("BeginIcuCachePinning"); beginIcuCachePinning(); - Trace.traceEnd(Trace.TRACE_TAG_DALVIK); - Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadClasses"); + bootTimingsTraceLog.traceEnd(); // BeginIcuCachePinning + bootTimingsTraceLog.traceBegin("PreloadClasses"); preloadClasses(); - Trace.traceEnd(Trace.TRACE_TAG_DALVIK); - Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadResources"); + bootTimingsTraceLog.traceEnd(); // PreloadClasses + bootTimingsTraceLog.traceBegin("PreloadResources"); preloadResources(); - Trace.traceEnd(Trace.TRACE_TAG_DALVIK); - Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadOpenGL"); + bootTimingsTraceLog.traceEnd(); // PreloadResources + bootTimingsTraceLog.traceBegin("PreloadOpenGL"); preloadOpenGL(); - Trace.traceEnd(Trace.TRACE_TAG_DALVIK); + bootTimingsTraceLog.traceEnd(); // PreloadOpenGL preloadSharedLibraries(); preloadTextResources(); // Ask the WebViewFactory to do any initialization that must run in the zygote process, @@ -639,7 +641,13 @@ public class ZygoteInit { } try { - Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygoteInit"); + // Report Zygote start time to tron + MetricsLogger.histogram(null, "boot_zygote_init", (int) SystemClock.uptimeMillis()); + + String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing"; + BootTimingsTraceLog bootTimingsTraceLog = new BootTimingsTraceLog(bootTimeTag, + Trace.TRACE_TAG_DALVIK); + bootTimingsTraceLog.traceBegin("ZygoteInit"); RuntimeInit.enableDdms(); // Start profiling the zygote initialization. SamplingProfilerIntegration.start(); @@ -664,22 +672,23 @@ public class ZygoteInit { } zygoteServer.registerServerSocket(socketName); - Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygotePreload"); + bootTimingsTraceLog.traceBegin("ZygotePreload"); EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START, SystemClock.uptimeMillis()); - preload(); + preload(bootTimingsTraceLog); EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END, SystemClock.uptimeMillis()); - Trace.traceEnd(Trace.TRACE_TAG_DALVIK); + bootTimingsTraceLog.traceEnd(); // ZygotePreload // Finish profiling the zygote initialization. SamplingProfilerIntegration.writeZygoteSnapshot(); // Do an initial gc to clean up after startup - Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PostZygoteInitGC"); + bootTimingsTraceLog.traceBegin("PostZygoteInitGC"); gcAndFinalize(); - Trace.traceEnd(Trace.TRACE_TAG_DALVIK); + bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC + bootTimingsTraceLog.traceEnd(); // ZygoteInit // Disable tracing so that forked processes do not inherit stale tracing tags from // Zygote. Trace.setTracingEnabled(false); diff --git a/core/java/com/android/internal/util/NotificationColorUtil.java b/core/java/com/android/internal/util/NotificationColorUtil.java index 4748e6fb19ff..7ee5170ef618 100644 --- a/core/java/com/android/internal/util/NotificationColorUtil.java +++ b/core/java/com/android/internal/util/NotificationColorUtil.java @@ -268,6 +268,45 @@ public class NotificationColorUtil { } /** + * Finds a suitable color such that there's enough contrast. + * + * @param color the color to start searching from. + * @param other the color to ensure contrast against. Assumed to be darker than {@param color} + * @param findFg if true, we assume {@param color} is a foreground, otherwise a background. + * @param minRatio the minimum contrast ratio required. + * @return a color with the same hue as {@param color}, potentially darkened to meet the + * contrast ratio. + */ + public static int findContrastColorAgainstDark(int color, int other, boolean findFg, + double minRatio) { + int fg = findFg ? color : other; + int bg = findFg ? other : color; + if (ColorUtilsFromCompat.calculateContrast(fg, bg) >= minRatio) { + return color; + } + + double[] lab = new double[3]; + ColorUtilsFromCompat.colorToLAB(findFg ? fg : bg, lab); + + double low = lab[0], high = 100; + final double a = lab[1], b = lab[2]; + for (int i = 0; i < 15 && high - low > 0.00001; i++) { + final double l = (low + high) / 2; + if (findFg) { + fg = ColorUtilsFromCompat.LABToColor(l, a, b); + } else { + bg = ColorUtilsFromCompat.LABToColor(l, a, b); + } + if (ColorUtilsFromCompat.calculateContrast(fg, bg) > minRatio) { + high = l; + } else { + low = l; + } + } + return ColorUtilsFromCompat.LABToColor(high, a, b); + } + + /** * Finds a text color with sufficient contrast over bg that has the same hue as the original * color, assuming it is for large text. */ diff --git a/core/java/com/android/internal/view/TooltipPopup.java b/core/java/com/android/internal/view/TooltipPopup.java new file mode 100644 index 000000000000..4f48b9645c69 --- /dev/null +++ b/core/java/com/android/internal/view/TooltipPopup.java @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.view; + +import android.content.Context; +import android.graphics.PixelFormat; +import android.graphics.Rect; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.WindowManager; +import android.widget.TextView; + +public class TooltipPopup { + private final Context mContext; + + private final View mContentView; + private final TextView mMessageView; + + private final WindowManager.LayoutParams mLayoutParams = new WindowManager.LayoutParams(); + private final Rect mTmpDisplayFrame = new Rect(); + private final int[] mTmpAnchorPos = new int[2]; + + public TooltipPopup(Context context) { + mContext = context; + + mContentView = LayoutInflater.from(mContext).inflate( + com.android.internal.R.layout.tooltip, null); + mMessageView = (TextView) mContentView.findViewById( + com.android.internal.R.id.message); + + mLayoutParams.setTitle( + mContext.getString(com.android.internal.R.string.tooltip_popup_title)); + mLayoutParams.packageName = mContext.getOpPackageName(); + mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL; + mLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT; + mLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT; + mLayoutParams.format = PixelFormat.TRANSLUCENT; + mLayoutParams.windowAnimations = com.android.internal.R.style.Animation_Tooltip; + mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE + | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; + } + + public void show(View anchorView, int anchorX, int anchorY, CharSequence tooltipText) { + if (isShowing()) { + hide(); + } + + mMessageView.setText(tooltipText); + + computePosition(anchorView, anchorX, anchorY, mLayoutParams); + + WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE); + wm.addView(mContentView, mLayoutParams); + } + + public void hide() { + if (!isShowing()) { + return; + } + + WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE); + wm.removeView(mContentView); + } + + public View getContentView() { + return mContentView; + } + + public boolean isShowing() { + return mContentView.getParent() != null; + } + + public void updateContent(CharSequence tooltipText) { + mMessageView.setText(tooltipText); + } + + private void computePosition(View anchorView, int anchorX, int anchorY, + WindowManager.LayoutParams outParams) { + final int tooltipPreciseAnchorThreshold = mContext.getResources().getDimensionPixelOffset( + com.android.internal.R.dimen.tooltip_precise_anchor_threshold); + + final int offsetX; + if (anchorView.getWidth() >= tooltipPreciseAnchorThreshold) { + // Wide view. Align the tooltip horizontally to the precise X position. + offsetX = anchorX; + } else { + // Otherwise anchor the tooltip to the view center. + offsetX = anchorView.getWidth() / 2; // Center on the view horizontally. + } + + final int offsetBelow; + final int offsetAbove; + if (anchorView.getHeight() >= tooltipPreciseAnchorThreshold) { + // Tall view. Align the tooltip vertically to the precise Y position. + offsetBelow = anchorY; + offsetAbove = anchorY; + } else { + // Otherwise anchor the tooltip to the view center. + offsetBelow = anchorView.getHeight(); // Place below the view in most cases. + offsetAbove = 0; // Place above the view if the tooltip does not fit below. + } + + outParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP; + + final int tooltipOffset = mContext.getResources().getDimensionPixelOffset( + com.android.internal.R.dimen.tooltip_y_offset); + + anchorView.getWindowVisibleDisplayFrame(mTmpDisplayFrame); + anchorView.getLocationInWindow(mTmpAnchorPos); + outParams.x = mTmpAnchorPos[0] + offsetX - mTmpDisplayFrame.width() / 2; + outParams.y = mTmpAnchorPos[1] + offsetBelow + tooltipOffset; + + final int spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + mContentView.measure(spec, spec); + final int tooltipHeight = mContentView.getMeasuredHeight(); + + if (outParams.y + tooltipHeight > mTmpDisplayFrame.height()) { + // The tooltip does not fit below the anchor point, show above instead. + outParams.y = mTmpAnchorPos[1] + offsetAbove - (tooltipOffset + tooltipHeight); + } + } +} diff --git a/core/jni/android_hardware_location_ContextHubService.cpp b/core/jni/android_hardware_location_ContextHubService.cpp index fbccfd5532e2..4391d93721b1 100644 --- a/core/jni/android_hardware_location_ContextHubService.cpp +++ b/core/jni/android_hardware_location_ContextHubService.cpp @@ -16,26 +16,26 @@ #include "context_hub.h" +#undef LOG_NDEBUG +#undef LOG_TAG #define LOG_NDEBUG 0 #define LOG_TAG "ContextHubService" #include <inttypes.h> #include <jni.h> -#include <mutex> -#include <string.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> - -// TOOD: On master, alphabetize these and move <mutex> into this -// grouping. -#include <chrono> -#include <unordered_map> -#include <queue> +#include <string.h> #include <android-base/macros.h> #include <cutils/log.h> +#include <chrono> +#include <mutex> +#include <queue> +#include <unordered_map> + #include "JNIHelp.h" #include "core_jni_helpers.h" @@ -1180,7 +1180,6 @@ static jint nativeSendMessage(JNIEnv *env, jobject instance, jintArray header_, } if (setAddressSuccess && hubId >= 0) { - ALOGD("Asking HAL to remove app"); retVal = db.hubInfo.contextHubModule->send_message(hubId, &msg); } else { ALOGD("Could not find app instance %" PRId32 " on hubHandle %" PRId32 diff --git a/core/jni/android_os_SystemProperties.cpp b/core/jni/android_os_SystemProperties.cpp index 5dace6b7e536..8844fb0a261f 100644 --- a/core/jni/android_os_SystemProperties.cpp +++ b/core/jni/android_os_SystemProperties.cpp @@ -220,6 +220,11 @@ static void SystemProperties_add_change_callback(JNIEnv *env, jobject clazz) } } +static void SystemProperties_report_sysprop_change(JNIEnv /**env*/, jobject /*clazz*/) +{ + report_sysprop_change(); +} + static const JNINativeMethod method_table[] = { { "native_get", "(Ljava/lang/String;)Ljava/lang/String;", (void*) SystemProperties_getS }, @@ -235,6 +240,8 @@ static const JNINativeMethod method_table[] = { (void*) SystemProperties_set }, { "native_add_change_callback", "()V", (void*) SystemProperties_add_change_callback }, + { "native_report_sysprop_change", "()V", + (void*) SystemProperties_report_sysprop_change }, }; int register_android_os_SystemProperties(JNIEnv *env) diff --git a/core/res/res/anim/tooltip_enter.xml b/core/res/res/anim/tooltip_enter.xml new file mode 100644 index 000000000000..7eceb4c8c86b --- /dev/null +++ b/core/res/res/anim/tooltip_enter.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2016, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<alpha xmlns:android="http://schemas.android.com/apk/res/android" + android:interpolator="@interpolator/decelerate_quad" + android:fromAlpha="0.0" android:toAlpha="1.0" + android:duration="@android:integer/config_tooltipAnimTime" /> diff --git a/core/res/res/anim/tooltip_exit.xml b/core/res/res/anim/tooltip_exit.xml new file mode 100644 index 000000000000..e346ca943eaf --- /dev/null +++ b/core/res/res/anim/tooltip_exit.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2016, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<alpha xmlns:android="http://schemas.android.com/apk/res/android" + android:interpolator="@interpolator/accelerate_quad" + android:fromAlpha="1.0" android:toAlpha="0.0" + android:duration="@android:integer/config_tooltipAnimTime" /> diff --git a/core/res/res/drawable/tooltip_frame.xml b/core/res/res/drawable/tooltip_frame.xml new file mode 100644 index 000000000000..14130c899e96 --- /dev/null +++ b/core/res/res/drawable/tooltip_frame.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2016 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle"> + <solid android:color="?attr/tooltipBackgroundColor" /> + <corners android:radius="@dimen/tooltip_corner_radius" /> +</shape>
\ No newline at end of file diff --git a/core/res/res/layout/tooltip.xml b/core/res/res/layout/tooltip.xml new file mode 100644 index 000000000000..0aa6a8781d91 --- /dev/null +++ b/core/res/res/layout/tooltip.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2016, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <TextView + android:id="@android:id/message" + android:layout_width="wrap_content" + android:layout_height="@dimen/tooltip_height" + android:layout_margin="@dimen/tooltip_margin" + android:paddingStart="@dimen/tooltip_horizontal_padding" + android:paddingEnd="@dimen/tooltip_horizontal_padding" + android:gravity="center" + android:background="?android:attr/tooltipFrameBackground" + android:textAppearance="@style/TextAppearance.Tooltip" + android:textColor="?android:attr/tooltipForegroundColor" + android:singleLine="true" + android:ellipsize="end" + /> + +</LinearLayout> diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index 5ca9f43d6329..e43f1ba76370 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Mediavolume"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Kennisgewing-volume"</string> <string name="ringtone_default" msgid="3789758980357696936">"Verstekluitoon"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Verstekluitoon (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Geen"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Luitone"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Onbekende luitoon"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">Wi-Fi netwerke beskikbaar</item> <item quantity="one">Wi-Fi-netwerk beskikbaar</item> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index 18fc6dd7ff2e..af8c59263d02 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"የማህደረ መረጃ ክፍልፍል"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"የማሳወቂያ ክፍልፍል"</string> <string name="ringtone_default" msgid="3789758980357696936">"ነባሪ የስልክ ላይ ጥሪ"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"(<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>) ነባሪ የስልክ ላይ ጥሪ"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"ምንም"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"ጥሪ ድምፆች"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"ያልታወቀ የስልክ ጥሪ ድምፅ"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="one">የWi-Fi አውታረ መረቦች አሉ</item> <item quantity="other">የWi-Fi አውታረ መረቦች አሉ</item> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index 3451bcc83d06..b3c24e59f6d6 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -1151,10 +1151,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"مستوى صوت الوسائط"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"مستوى صوت الإشعار"</string> <string name="ringtone_default" msgid="3789758980357696936">"نغمة الرنين الافتراضية"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"نغمة الرنين الافتراضية (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"لا شيء"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"نغمات الرنين"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"نغمة رنين غير معروفة"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="zero">لا تتوفر أية شبكات Wi-Fi</item> <item quantity="two">تتوفر شبكتا Wi-Fi</item> diff --git a/core/res/res/values-az-rAZ/strings.xml b/core/res/res/values-az-rAZ/strings.xml index 1f0d164c817f..7e9c5082e2e8 100644 --- a/core/res/res/values-az-rAZ/strings.xml +++ b/core/res/res/values-az-rAZ/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Media həcmi"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Bildiriş səsi"</string> <string name="ringtone_default" msgid="3789758980357696936">"Defolt rinqton"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Defolt rinqton (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Heç biri"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Zəng səsləri"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Naməlum rinqton"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">Əlçatan Wi-Fi şəbəkələri</item> <item quantity="one">Əlçatan Wi-Fi şəbəkəsi</item> diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml index 2509eae861f0..6caf561e366c 100644 --- a/core/res/res/values-b+sr+Latn/strings.xml +++ b/core/res/res/values-b+sr+Latn/strings.xml @@ -1082,10 +1082,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Jačina zvuka medija"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Jačina zvuka obaveštenja"</string> <string name="ringtone_default" msgid="3789758980357696936">"Podrazumevani zvuk zvona"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Podrazumevani zvuk zvona (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Bez zvuka"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Zvukovi zvona"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Nepoznati zvuk zvona"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="one">Wi-Fi mreže su dostupne</item> <item quantity="few">Wi-Fi mreže su dostupne</item> diff --git a/core/res/res/values-be-rBY/strings.xml b/core/res/res/values-be-rBY/strings.xml index f5f1e62483b1..c076db254310 100644 --- a/core/res/res/values-be-rBY/strings.xml +++ b/core/res/res/values-be-rBY/strings.xml @@ -1105,10 +1105,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Гучнасць прайгравальніка"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Гучнасць апавяшчэнняў"</string> <string name="ringtone_default" msgid="3789758980357696936">"Стандартны рынгтон"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Стандартны рынгтон (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Няма"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Рынгтоны"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Невядомы рынгтон"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="one">сетка Wi-Fi даступная</item> <item quantity="few">сеткі Wi-Fi даступныя</item> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index f6eb81093c73..2d6bdb2ed9f8 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Сила на звука"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Сила на звука при известие"</string> <string name="ringtone_default" msgid="3789758980357696936">"Стандартна мелодия"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Стандартна мелодия (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Без"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Мелодии"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Неизвестна мелодия"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">Има достъпни Wi-Fi мрежи</item> <item quantity="one">Има достъпна Wi-Fi мрежа</item> diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml index 993d49bebd08..21b737aa2b99 100644 --- a/core/res/res/values-bn-rBD/strings.xml +++ b/core/res/res/values-bn-rBD/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"মিডিয়ার ভলিউম"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"বিজ্ঞপ্তির ভলিউম"</string> <string name="ringtone_default" msgid="3789758980357696936">"ডিফল্ট রিংটোন"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"ডিফল্ট রিংটোন (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"কোনো কিছুই নয়"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"রিংটোনগুলি"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"অজানা রিংটোন"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="one">ওয়াই-ফাই নেটওয়ার্কগুলি উপলব্ধ রয়েছে</item> <item quantity="other">ওয়াই-ফাই নেটওয়ার্কগুলি উপলব্ধ রয়েছে</item> diff --git a/core/res/res/values-bs-rBA/strings.xml b/core/res/res/values-bs-rBA/strings.xml index 7cb46feabca7..80ee40753569 100644 --- a/core/res/res/values-bs-rBA/strings.xml +++ b/core/res/res/values-bs-rBA/strings.xml @@ -1084,10 +1084,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Jačina zvuka za medijske sadržaje"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Jačina zvuka za obavještenja"</string> <string name="ringtone_default" msgid="3789758980357696936">"Zadana melodija zvona"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Zadano zvono (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Bez zvuka"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Melodije zvona"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Nepoznato zvono"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="one">Wi-Fi mreže su dostupne</item> <item quantity="few">Wi-Fi mreže su dostupne</item> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index 522efc55c6dc..35b2918c79e1 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Volum de multimèdia"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Volum de notificació"</string> <string name="ringtone_default" msgid="3789758980357696936">"So predeterminat"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"So predeterminat (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Cap"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Sons"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"So desconegut"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">Xarxes Wi-Fi disponibles</item> <item quantity="one">Xarxa Wi-Fi disponible</item> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index 0e6ba82deeaf..95a672845b0e 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -1105,10 +1105,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Hlasitost médií"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Hlasitost oznámení"</string> <string name="ringtone_default" msgid="3789758980357696936">"Výchozí vyzváněcí tón"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Výchozí tón (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Žádný"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Vyzváněcí tóny"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Neznámý vyzváněcí tón"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="few">K dispozici jsou sítě Wi-Fi</item> <item quantity="many">K dispozici jsou sítě Wi-Fi</item> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index 628f9bbf23cf..a628e4244e0a 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Medielydstyrke"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Lydstyrke for meddelelser"</string> <string name="ringtone_default" msgid="3789758980357696936">"Standardringetone"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Standardringetone (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Ingen"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Ringetoner"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Ukendt ringetone"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="one">Tilgængelige Wi-Fi-netværk</item> <item quantity="other">Tilgængelige Wi-Fi-netværk</item> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 9d8c98be596e..86f2070853ad 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Medienlautstärke"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Benachrichtigungslautstärke"</string> <string name="ringtone_default" msgid="3789758980357696936">"Standard-Klingelton"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Standard-Klingelton (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Ohne"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Klingeltöne"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Unbekannter Klingelton"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">WLAN-Netzwerke verfügbar</item> <item quantity="one">WLAN-Netzwerk verfügbar</item> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 4283827debcb..4ce3a1f980b3 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Ένταση ήχου πολυμέσων"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Ένταση ήχου ειδοποιήσεων"</string> <string name="ringtone_default" msgid="3789758980357696936">"Προεπιλεγμένος ήχος κλήσης"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Προεπ. ήχος (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Κανένας"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Ήχοι κλήσης"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Άγνωστος ήχος κλήσης"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">Υπάρχουν διαθέσιμα δίκτυα Wi-Fi</item> <item quantity="one">Υπάρχει διαθέσιμο δίκτυο Wi-Fi</item> diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml index 38f2b888ae20..72c1271c07d3 100644 --- a/core/res/res/values-en-rAU/strings.xml +++ b/core/res/res/values-en-rAU/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Media volume"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Notification volume"</string> <string name="ringtone_default" msgid="3789758980357696936">"Default ringtone"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Default ringtone (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"None"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Ringtones"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Unknown ringtone"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">Wi-Fi networks available</item> <item quantity="one">Wi-Fi network available</item> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index 38f2b888ae20..72c1271c07d3 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Media volume"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Notification volume"</string> <string name="ringtone_default" msgid="3789758980357696936">"Default ringtone"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Default ringtone (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"None"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Ringtones"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Unknown ringtone"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">Wi-Fi networks available</item> <item quantity="one">Wi-Fi network available</item> diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml index 38f2b888ae20..72c1271c07d3 100644 --- a/core/res/res/values-en-rIN/strings.xml +++ b/core/res/res/values-en-rIN/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Media volume"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Notification volume"</string> <string name="ringtone_default" msgid="3789758980357696936">"Default ringtone"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Default ringtone (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"None"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Ringtones"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Unknown ringtone"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">Wi-Fi networks available</item> <item quantity="one">Wi-Fi network available</item> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index 1277acc06a08..738af8c9f17b 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Volumen de los medios"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Volumen de notificación"</string> <string name="ringtone_default" msgid="3789758980357696936">"Tono predeterminado"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Tono predeterminado (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Ninguno"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Tonos de llamada"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Tono de llamada desconocido"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">redes de Wi-Fi disponibles</item> <item quantity="one">red de Wi-Fi disponible</item> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index fa0389742386..3c2915d4d759 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Volumen multimedia"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Volumen de notificaciones"</string> <string name="ringtone_default" msgid="3789758980357696936">"Tono por defecto"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Tono predeterminado (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Ninguno"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Tonos"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Tono desconocido"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">Redes Wi-Fi disponibles</item> <item quantity="one">Red Wi-Fi disponible</item> diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml index d7ee50c45854..96b060f14d65 100644 --- a/core/res/res/values-et-rEE/strings.xml +++ b/core/res/res/values-et-rEE/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Meediumi helitugevus"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Teatise helitugevus"</string> <string name="ringtone_default" msgid="3789758980357696936">"Vaikehelin"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Vaikehelin (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Puudub"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Helinad"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Tundmatu helin"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">WiFi-võrgud on saadaval</item> <item quantity="one">WiFi-võrk on saadaval</item> diff --git a/core/res/res/values-eu-rES/strings.xml b/core/res/res/values-eu-rES/strings.xml index e7f3f0205f22..6ccd864ccc39 100644 --- a/core/res/res/values-eu-rES/strings.xml +++ b/core/res/res/values-eu-rES/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Euskarriaren bolumena"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Jakinarazpenen bolumena"</string> <string name="ringtone_default" msgid="3789758980357696936">"Tonu lehenetsia"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Tonu lehenetsia (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Bat ere ez"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Tonuak"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Tonu ezezaguna"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">Wi-Fi sareak erabilgarri</item> <item quantity="one">Wi-Fi sarea erabilgarri</item> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index 374183fd1218..e8e61f4bdc06 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"میزان صدای رسانه"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"میزان صدای اعلان"</string> <string name="ringtone_default" msgid="3789758980357696936">"آهنگ زنگ پیشفرض"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"آهنگ زنگ پیشفرض (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"هیچکدام"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"آهنگهای زنگ"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"آهنگ زنگ ناشناس"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="one">شبکه Wi-Fi در دسترس</item> <item quantity="other">شبکه Wi-Fi در دسترس</item> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index 9b6d57c68ed6..dbfd8ba21351 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Median äänenvoimakkuus"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Ilmoituksen äänenvoimakkuus"</string> <string name="ringtone_default" msgid="3789758980357696936">"Oletussoittoääni"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Oletussoittoääni (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Ei mitään"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Soittoäänet"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Tuntematon soittoääni"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">Wi-Fi-verkkoja käytettävissä</item> <item quantity="one">Wi-Fi-verkko käytettävissä</item> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index 034b291dd797..501627d9ae25 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Volume"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Volume des notifications"</string> <string name="ringtone_default" msgid="3789758980357696936">"Sonnerie par défaut"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Sonnerie par défaut (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Aucune"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Sonneries"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Sonnerie inconnue"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="one">Réseau Wi-Fi à proximité</item> <item quantity="other">Réseaux Wi-Fi à proximité</item> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 1e5f6a1a6f66..ccff4f36cb33 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Volume"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Volume des notifications"</string> <string name="ringtone_default" msgid="3789758980357696936">"Sonnerie par défaut"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Sonnerie par défaut (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Aucune"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Sonneries"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Sonnerie inconnue"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="one">Réseau Wi-Fi disponible</item> <item quantity="other">Réseaux Wi-Fi disponibles</item> diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml index 704667a4eebd..89a94718f6a7 100644 --- a/core/res/res/values-gl-rES/strings.xml +++ b/core/res/res/values-gl-rES/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Volume dos elementos multimedia"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Volume das notificacións"</string> <string name="ringtone_default" msgid="3789758980357696936">"Ton de chamada predeterminado"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Ton de chamada predeterminado (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Ningún"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Tons de chamada"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Ton de chamada descoñecido"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">Redes wifi dispoñibles</item> <item quantity="one">Rede wifi dispoñible</item> diff --git a/core/res/res/values-gu-rIN/strings.xml b/core/res/res/values-gu-rIN/strings.xml index cd3e7bee3864..cbb0d9e4a4e8 100644 --- a/core/res/res/values-gu-rIN/strings.xml +++ b/core/res/res/values-gu-rIN/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"મીડિયા વોલ્યુમ"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"સૂચના વૉલ્યૂમ"</string> <string name="ringtone_default" msgid="3789758980357696936">"ડિફોલ્ટ રિંગટોન"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"ડિફોલ્ટ રિંગટોન (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"કોઈ નહીં"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"રિંગટોન્સ"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"અજાણ રિંગટોન"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="one">Wi-Fi નેટવર્ક્સ ઉપલબ્ધ</item> <item quantity="other">Wi-Fi નેટવર્ક્સ ઉપલબ્ધ</item> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index c8b325682af7..e83305262c75 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -347,14 +347,14 @@ <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"ऐप्स को इनकमिंग और आउटगोइंग कॉल के डेटा सहित, आपके फ़ोन का कॉल लॉग संशोधित करने देता है. दुर्भावनापूर्ण ऐप्स आपके कॉल लॉग को मिटाने या संशोधित करने के लिए इसका उपयोग कर सकते हैं."</string> <string name="permlab_bodySensors" msgid="4683341291818520277">"शरीर संवेदक एक्सेस करें (जैसे हृदय गति मॉनीटर)"</string> <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"ऐप को आपकी शारीरिक स्थिति, जैसे आपकी हृदय गति पर नज़र रखने वाले संवेदकों का डेटा एक्सेस करने देती है."</string> - <string name="permlab_readCalendar" msgid="5972727560257612398">"केलैंडर ईवेंट के साथ-साथ गोपनीय जानकारी पढ़ें"</string> + <string name="permlab_readCalendar" msgid="5972727560257612398">"केलैंडर इवेंट के साथ-साथ गोपनीय जानकारी पढ़ें"</string> <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"ऐप्स को मित्रों या सहकर्मियों के कैलेंडर इवेंट सहित, आपके टेबलेट पर संग्रहीत कैलेंडर इवेंट पढ़ने देता है. इससे निजता या संवेदनशीलता पर ध्यान दिए बिना, ऐप्स आपके कैलेंडर डेटा को साझा कर सकता है या सहेज सकता है."</string> - <string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"ऐप को, मित्रों और सहकर्मियों के कैलेंडर ईवेंट सहित, आपके टीवी पर संग्रहीत सभी कैलेंडर ईवेंट पढ़ने देती है. इससे ऐप को निजता या संवेदनशीलता पर ध्यान दिए बिना, आपका कैलेडर डेटा साझा करने या सहेजने की अनुमति मिल जाती है."</string> + <string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"ऐप को, मित्रों और सहकर्मियों के कैलेंडर इवेंट सहित, आपके टीवी पर संग्रहीत सभी कैलेंडर इवेंट पढ़ने देती है. इससे ऐप को निजता या संवेदनशीलता पर ध्यान दिए बिना, आपका कैलेडर डेटा साझा करने या सहेजने की अनुमति मिल जाती है."</string> <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"ऐप्स को मित्रों या सहकर्मियों के कैलेंडर इवेंट सहित, आपके फ़ोन पर संग्रहीत कैलेंडर इवेंट पढ़ने देता है. इससे निजता या संवेदनशीलता पर ध्यान दिए बिना, ऐप्स आपके कैलेंडर डेटा को साझा कर सकता है या सहेज सकता है."</string> - <string name="permlab_writeCalendar" msgid="8438874755193825647">"अपनी जानकारी के बिना कैलेंडर ईवेंट जोड़ें या संशोधित करें और अतिथियों को ईमेल भेजें"</string> - <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"ऐप्स को मित्रों या सहकर्मियों के ईवेंट के साथ ही वे ईवेंट जोड़ने, निकालने, बदलने देता है जिन्हें आप अपने टेबलेट पर संशोधित कर सकते हैं. इससे ऐप्स ,अपनी जानकारी के बिना उन संदेशों को भेज सकता है जो कैलेंडर स्वामियों की ओर से आते दिखाई देते हैं, या ईवेंट संशोधित कर सकता है."</string> - <string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"ऐप को ऐसे ईवेंट जोड़ने, निकालने, बदलने देती है जिन्हें आप अपने डिवाइस पर बदल सकते हैं, जिनमें मित्रों या सहकर्मियों के ईवेंट शामिल हैं. इससे ऐप ऐसे संदेश भेज सकता है जो कैलेंडर स्वामी से आते हुए प्रतीत होते हैं या ऐप स्वामी की जानकारी के बिना ईवेंट बदल सकता है."</string> - <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"ऐप्स को मित्रों या सहकर्मियों के ईवेंट के साथ ही वे ईवेंट जोड़ने, निकालने, बदलने देता है जिन्हें आप अपने फ़ोन पर संशोधित कर सकते हैं. इससे ऐप्स , अपनी जानकारी के बिना उन संदेशों को भेज सकता है जो कैलेंडर स्वामियों की ओर से आते दिखाई देते हैं, या ईवेंट संशोधित कर सकता है."</string> + <string name="permlab_writeCalendar" msgid="8438874755193825647">"अपनी जानकारी के बिना कैलेंडर इवेंट जोड़ें या संशोधित करें और अतिथियों को ईमेल भेजें"</string> + <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"ऐप्स को मित्रों या सहकर्मियों के इवेंट के साथ ही वे इवेंट जोड़ने, निकालने, बदलने देता है जिन्हें आप अपने टेबलेट पर संशोधित कर सकते हैं. इससे ऐप्स ,अपनी जानकारी के बिना उन संदेशों को भेज सकता है जो कैलेंडर स्वामियों की ओर से आते दिखाई देते हैं, या इवेंट संशोधित कर सकता है."</string> + <string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"ऐप को ऐसे इवेंट जोड़ने, निकालने, बदलने देती है जिन्हें आप अपने डिवाइस पर बदल सकते हैं, जिनमें मित्रों या सहकर्मियों के इवेंट शामिल हैं. इससे ऐप ऐसे संदेश भेज सकता है जो कैलेंडर स्वामी से आते हुए प्रतीत होते हैं या ऐप स्वामी की जानकारी के बिना इवेंट बदल सकता है."</string> + <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"ऐप्स को मित्रों या सहकर्मियों के इवेंट के साथ ही वे इवेंट जोड़ने, निकालने, बदलने देता है जिन्हें आप अपने फ़ोन पर संशोधित कर सकते हैं. इससे ऐप्स , अपनी जानकारी के बिना उन संदेशों को भेज सकता है जो कैलेंडर स्वामियों की ओर से आते दिखाई देते हैं, या इवेंट संशोधित कर सकता है."</string> <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"अतिरिक्त स्थान प्रदाता आदेशों में पहुंचे"</string> <string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"ऐप्स को अतिरिक्त स्थान प्रदाता आदेशों पर पहुंचने देती है. इससे ऐप्स GPS या अन्य स्थान स्रोतों के संचालन में अवरोध पहुंचा सकता है."</string> <string name="permlab_accessFineLocation" msgid="251034415460950944">"सटीक स्थान एक्सेस करें (GPS और नेटवर्क-आधारित)"</string> @@ -459,7 +459,7 @@ <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"समन्वयन बंद या चालू टॉगल करें"</string> <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"ऐप्स को किसी खाते की समन्वयन सेटिंग संशोधित करने देता है. उदाहरण के लिए, इसका उपयोग लोग ऐप्स का समन्वयन किसी खाते से सक्षम करने में हो सकता है."</string> <string name="permlab_readSyncStats" msgid="7396577451360202448">"समन्वयन आंकड़े पढ़ें"</string> - <string name="permdesc_readSyncStats" msgid="1510143761757606156">"ऐप्स को किसी खाते के समन्वयन आंकड़े, साथ ही समन्वयित ईवेंट का इतिहास और समन्वयित डेटा की मात्रा पढ़ने देता है."</string> + <string name="permdesc_readSyncStats" msgid="1510143761757606156">"ऐप्स को किसी खाते के समन्वयन आंकड़े, साथ ही समन्वयित इवेंट का इतिहास और समन्वयित डेटा की मात्रा पढ़ने देता है."</string> <string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"अपने USB मेमोरी की सामग्री पढ़ें"</string> <string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"अपने SD कार्ड की सामग्री पढ़ें"</string> <string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"एप्लिकेशन को आपके USB मेमोरी की सामग्री पढ़ने की अनुमति देता है."</string> @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"मीडिया वॉल्यूम"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"नोटिफिकेशन वॉल्यूम"</string> <string name="ringtone_default" msgid="3789758980357696936">"डिफ़ॉल्ट रिंगटोन"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"डिफ़ॉल्ट रिंगटोन (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"कोई नहीं"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"रिंगटोन"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"अज्ञात रिंगटोन"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="one">वाई-फ़ाई नेटवर्क उपलब्ध</item> <item quantity="other">वाई-फ़ाई नेटवर्क उपलब्ध</item> @@ -1614,7 +1620,7 @@ <string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"बंद रहने का समय"</string> <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"सप्ताह की रात"</string> <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"सप्ताहांत"</string> - <string name="zen_mode_default_events_name" msgid="8158334939013085363">"ईवेंट"</string> + <string name="zen_mode_default_events_name" msgid="8158334939013085363">"इवेंट"</string> <string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> द्वारा म्यूट किया गया"</string> <string name="system_error_wipe_data" msgid="6608165524785354962">"आपके डिवाइस के साथ कोई आंतरिक त्रुटि हुई और यह तब तक अस्थिर रह सकता है, जब तक आप फ़ैक्टरी डेटा रीसेट नहीं करते हैं."</string> <string name="system_error_manufacturer" msgid="8086872414744210668">"आपके डिवाइस के साथ कोई आंतरिक त्रुटि हुई. विवरणों के लिए अपने निर्माता से संपर्क करें."</string> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index 3fc334631bae..e811b94f66a9 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -1082,10 +1082,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Glasnoća medija"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Glasnoća obavijesti"</string> <string name="ringtone_default" msgid="3789758980357696936">"Zadana melodija zvona"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Zadana melodija zvona (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Ništa"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Melodije zvona"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Nepoznata melodija zvona"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="one">Dostupne su Wi-Fi mreže</item> <item quantity="few">Dostupne su Wi-Fi mreže</item> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index 825672b82f4f..b0ce160480e9 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Média hangereje"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Értesítés hangereje"</string> <string name="ringtone_default" msgid="3789758980357696936">"Alapértelmezett csengőhang"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Alap csengőhang (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Egyik sem"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Csengőhangok"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Ismeretlen csengőhang"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">Wi-Fi hálózatok érhetők el</item> <item quantity="one">Van elérhető Wi-Fi hálózat</item> diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml index af7aaaf761ce..2ba22af70052 100644 --- a/core/res/res/values-hy-rAM/strings.xml +++ b/core/res/res/values-hy-rAM/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Մեդիա ձայնի բարձրություն"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Ծանուցումների ձայնի ուժգնությունը"</string> <string name="ringtone_default" msgid="3789758980357696936">"Կանխադրված զանգերանգ"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Կանխադրված զանգերանգ (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Ոչ մեկը"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Զանգերանգներ"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Անհայտ զանգերանգ"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="one">Հասանելի են Wi-Fi ցանցեր</item> <item quantity="other">Հասանելի են Wi-Fi ցանցեր</item> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index 05fe8d01cdc5..09223cd5dd7f 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Volume media"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Volume pemberitahuan"</string> <string name="ringtone_default" msgid="3789758980357696936">"Nada dering default"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Nada dering default (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Tidak Ada"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Nada dering"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Nada dering tidak dikenal"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">Jaringan Wi-Fi tersedia</item> <item quantity="one">Jaringan Wi-Fi tersedia</item> diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml index cd41f51ad0c9..105a647d72fe 100644 --- a/core/res/res/values-is-rIS/strings.xml +++ b/core/res/res/values-is-rIS/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Hljóðstyrkur efnisspilunar"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Hljóðstyrkur tilkynninga"</string> <string name="ringtone_default" msgid="3789758980357696936">"Sjálfgefinn hringitónn"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Sjálfg. hringitónn (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Ekkert"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Hringitónar"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Óþekktur hringitónn"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="one">Wi-Fi net í boði</item> <item quantity="other">Wi-Fi net í boði</item> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index ec7f8f964f5e..564472e6adf1 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Volume contenuti multimediali"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Volume notifiche"</string> <string name="ringtone_default" msgid="3789758980357696936">"Suoneria predefinita"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Suoneria predefinita (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Nessuna"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Suonerie"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Suoneria sconosciuta"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">Reti Wi-Fi disponibili</item> <item quantity="one">Rete Wi-Fi disponibile</item> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index 290a31ffa624..d4b9bf11b226 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -1105,10 +1105,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"עוצמת קול של מדיה"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"עוצמת קול של התראות"</string> <string name="ringtone_default" msgid="3789758980357696936">"רינגטון ברירת מחדל"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"רינגטון ברירת מחדל (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"ללא"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"רינגטונים"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"רינגטון לא ידוע"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="two">יש רשתות Wi-Fi זמינות</item> <item quantity="many">יש רשתות Wi-Fi זמינות</item> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index 02736ec15c59..e2432f1080fe 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"メディアの音量"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"通知音量"</string> <string name="ringtone_default" msgid="3789758980357696936">"プリセット着信音"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"端末の基本着信音(<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"なし"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"着信音"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"不明な着信音"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">複数のWi-Fiネットワークが利用できます</item> <item quantity="one">Wi-Fiネットワークが利用できます</item> diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml index 1e343476d7a7..5e069b6e5535 100644 --- a/core/res/res/values-ka-rGE/strings.xml +++ b/core/res/res/values-ka-rGE/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"მედიის ხმა"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"შეტყობინების ხმა"</string> <string name="ringtone_default" msgid="3789758980357696936">"ნაგულისხმევი ზარი"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"ნაგულის.ზარი (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"არც ერთი"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"ზარები"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"უცნობი ზარი"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">ხელმისაწვდომია Wi-Fi ქსელები</item> <item quantity="one">ხელმისაწვდომია Wi-Fi ქსელი</item> diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml index 9a227c43e7a2..729f726a8486 100644 --- a/core/res/res/values-kk-rKZ/strings.xml +++ b/core/res/res/values-kk-rKZ/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Meдиа дыбысының қаттылығы"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Хабар дыбысының қаттылығы"</string> <string name="ringtone_default" msgid="3789758980357696936">"Әдепкі рингтон"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Әдепкі рингтон (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Ешқандай"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Қоңырау әуендері"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Белгісіз қоңырау әуені"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">Wi-Fi желілері қол жетімді</item> <item quantity="one">Wi-Fi желісі қол жетімді</item> diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml index 2491f82c6e01..c3e939e6f5ce 100644 --- a/core/res/res/values-km-rKH/strings.xml +++ b/core/res/res/values-km-rKH/strings.xml @@ -1061,10 +1061,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"កម្រិតសំឡេងមេឌៀ"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"កម្រិតសំឡេងការជូនដំណឹង"</string> <string name="ringtone_default" msgid="3789758980357696936">"សំឡេងរោទ៍លំនាំដើម"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"សំឡេងរោទ៍លំនាំដើម (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"គ្មាន"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"សំឡេងរោទ៍"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"សំឡេងរោទ៍មិនស្គាល់"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">មានបណ្តាញ Wi-Fi</item> <item quantity="one">មានបណ្តាញ Wi-Fi</item> diff --git a/core/res/res/values-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml index 732a321c2104..7f80a299cf7a 100644 --- a/core/res/res/values-kn-rIN/strings.xml +++ b/core/res/res/values-kn-rIN/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"ಮೀಡಿಯಾ ವಾಲ್ಯೂಮ್"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"ಅಧಿಸೂಚನೆಯ ವಾಲ್ಯೂಮ್"</string> <string name="ringtone_default" msgid="3789758980357696936">"ಡಿಫಾಲ್ಟ್ ರಿಂಗ್ಟೋನ್"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"ಡಿಫಾಲ್ಟ್ ರಿಂಗ್ಟೋನ್ (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"ಯಾವುದೂ ಇಲ್ಲ"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"ರಿಂಗ್ಟೋನ್ಗಳು"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"ಅಪರಿಚಿತ ರಿಂಗ್ಟೋನ್"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="one">ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ಗಳು ಲಭ್ಯವಿವೆ</item> <item quantity="other">ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ಗಳು ಲಭ್ಯವಿವೆ</item> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index 6e1012a3cbfc..444c83dd7cbb 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"미디어 볼륨"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"알림 볼륨"</string> <string name="ringtone_default" msgid="3789758980357696936">"기본 벨소리"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"기본 벨소리(<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"없음"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"벨소리"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"알 수 없는 벨소리"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">Wi-Fi 네트워크 사용 가능</item> <item quantity="one">Wi-Fi 네트워크 사용 가능</item> diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml index 7a48ae58bd11..2b592bdf4588 100644 --- a/core/res/res/values-ky-rKG/strings.xml +++ b/core/res/res/values-ky-rKG/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Медиа үнүнүн деңгээли"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Эскертме үнүнүн деңгээли"</string> <string name="ringtone_default" msgid="3789758980357696936">"Демейки рингтон"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Демейки рингтон (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Эч бир"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Ринтондор"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Белгисиз рингтон"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">Wi-Fi тармагы жеткиликтүү</item> <item quantity="one">Wi-Fi тармагы жеткиликтүү</item> diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml index 26c90532476a..3a96743d569d 100644 --- a/core/res/res/values-lo-rLA/strings.xml +++ b/core/res/res/values-lo-rLA/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"ລະດັບສຽງຂອງສື່"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"ລະດັບສຽງການແຈ້ງເຕືອນ"</string> <string name="ringtone_default" msgid="3789758980357696936">"ຣິງໂທນເລີ່ມຕົ້ນ"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"ຣິງໂທນເລີ່ມຕົ້ນ (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"ບໍ່ມີ"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"ຣິງໂທນ"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"ຣິງໂທນທີ່ບໍ່ຮູ້ຈັກ"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">ເຄືອຂ່າຍ Wi-Fi ທີ່ມີໃຫ້</item> <item quantity="one">ເຄືອຂ່າຍ Wi-Fi ທີ່ມີໃຫ້</item> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index c7806f24eef6..d60a010a6f85 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -1105,10 +1105,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Medijos garsumas"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Pranešimo apimtis"</string> <string name="ringtone_default" msgid="3789758980357696936">"Numatytasis skambėjimo tonas"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Numatytasis skambėjimo tonas („<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>“)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Nėra"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Skambėjimo tonai"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Nežinomas skambėjimo tonas"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="one">Pasiekiami „Wi-Fi“ tinklai</item> <item quantity="few">Pasiekiami „Wi-Fi“ tinklai</item> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index 6ea7d6b192c0..7afb2ceda3da 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -1082,10 +1082,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Multivides skaļums"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Paziņojumu skaļums"</string> <string name="ringtone_default" msgid="3789758980357696936">"Noklusējuma zvana signāls"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Noklusējuma zvana signāls (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Nav"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Zvana signāli"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Nezināms zvana signāls"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="zero">Pieejami Wi-Fi tīkli</item> <item quantity="one">Pieejami Wi-Fi tīkli</item> diff --git a/core/res/res/values-mk-rMK/strings.xml b/core/res/res/values-mk-rMK/strings.xml index 3f228203a98d..139e02a0db5b 100644 --- a/core/res/res/values-mk-rMK/strings.xml +++ b/core/res/res/values-mk-rMK/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Јачина на звук на медиуми"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Јачина на звук на известување"</string> <string name="ringtone_default" msgid="3789758980357696936">"Стандардна мелодија"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Стандардна мелодија (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Ниедна"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Мелодии"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Непозната мелодија"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="one">Wi-Fi мрежи се достапни</item> <item quantity="other">Wi-Fi мрежи се достапни</item> diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml index beb6a67d3cc8..fc3eb40cdc5c 100644 --- a/core/res/res/values-ml-rIN/strings.xml +++ b/core/res/res/values-ml-rIN/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"മീഡിയ വോളിയം"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"അറിയിപ്പ് വോളിയം"</string> <string name="ringtone_default" msgid="3789758980357696936">"ഡിഫോൾട്ട് റിംഗ്ടോൺ"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"ഡിഫോൾട്ട് റിംഗ്ടോൺ (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"ഒന്നും വേണ്ട"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"റിംഗ്ടോണുകൾ"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"അജ്ഞാത റിംഗ്ടോൺ"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">വൈഫൈ നെറ്റ്വർക്കുകൾ ലഭ്യമാണ്</item> <item quantity="one">വൈഫൈ നെറ്റ്വർക്ക് ലഭ്യമാണ്</item> diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml index bd80f8414141..2faf163488c2 100644 --- a/core/res/res/values-mn-rMN/strings.xml +++ b/core/res/res/values-mn-rMN/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Медиа дууны хэмжээ"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Мэдэгдлийн дууны хэмжээ"</string> <string name="ringtone_default" msgid="3789758980357696936">"Үндсэн хонхны ая"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Үндсэн хонхны ая (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Алийг нь ч биш"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Хонхны ая"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Үл мэдэгдэх хонхны ая"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">Wi-Fi сүлжээ ашиглах боломжтой</item> <item quantity="one">Wi-Fi сүлжээ ашиглах боломжтой</item> diff --git a/core/res/res/values-mr-rIN/strings.xml b/core/res/res/values-mr-rIN/strings.xml index 758b21b7c896..99465cc641ca 100644 --- a/core/res/res/values-mr-rIN/strings.xml +++ b/core/res/res/values-mr-rIN/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"मीडिया व्हॉल्यूम"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"सूचना व्हॉल्यूम"</string> <string name="ringtone_default" msgid="3789758980357696936">"डीफॉल्ट रिंगटोन"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"डीफॉल्ट रिंगटोन (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"काहीही नाही"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"रिंगटोन"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"अज्ञात रिंगटोन"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="one">वाय-फाय नेटवर्क उपलब्ध</item> <item quantity="other">वाय-फाय नेटवर्क उपलब्ध</item> diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml index 60330e571401..1e7e2810f623 100644 --- a/core/res/res/values-ms-rMY/strings.xml +++ b/core/res/res/values-ms-rMY/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Kelantangan media"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Kelantangan pemberitahuan"</string> <string name="ringtone_default" msgid="3789758980357696936">"Nada dering lalai"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Nada dering lalai (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Tiada"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Nada dering"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Nada dering tidak diketahui"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">Rangkaian Wi-Fi tersedia</item> <item quantity="one">Rangkaian Wi-Fi tersedia</item> diff --git a/core/res/res/values-my-rMM/strings.xml b/core/res/res/values-my-rMM/strings.xml index c18ff7f6b8dd..99d64230f905 100644 --- a/core/res/res/values-my-rMM/strings.xml +++ b/core/res/res/values-my-rMM/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"မီဒီယာအသံအတိုးအကျယ်"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"အကြောင်းကြားသံအတိုးအကျယ်"</string> <string name="ringtone_default" msgid="3789758980357696936">"မူရင်းမြည်သံ"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"မူရင်းမြည်သံ (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"တစ်ခုမှမဟုတ်"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"မြည်သံများ"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"မသိသောမြည်သံ"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">Wi-Fi ကွန်ယက်များရရှိနိုင်သည်</item> <item quantity="one">Wi-Fi ကွန်ယက်ရရှိနိုင်သည်</item> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index 037154375c49..324f0d7a85ea 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Medievolum"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Varslingsvolum"</string> <string name="ringtone_default" msgid="3789758980357696936">"Standard ringetone"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Standard ringetone (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Ingen"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Ringelyder"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Ukjent ringetone"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">Wi-Fi-nettverk er tilgjengelig</item> <item quantity="one">Wi-Fi-nettverk er tilgjengelig</item> diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml index e039927f9dd7..caf36885db42 100644 --- a/core/res/res/values-ne-rNP/strings.xml +++ b/core/res/res/values-ne-rNP/strings.xml @@ -1065,10 +1065,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"मिडियाको मात्रा"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"सूचना भोल्युम"</string> <string name="ringtone_default" msgid="3789758980357696936">"पूर्वनिर्धारित रिङटोन"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"पूर्वनिर्धारित रिङटोन (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"कुनै पनि होइन"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"रिङटोनहरू"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"अज्ञात रिङटोन"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">Wi-Fi सञ्जालहरू उपलब्ध छन्</item> <item quantity="one">Wi-Fi सञ्जाल उपलब्ध छ</item> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index 9c263405c3c5..084830426549 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -204,9 +204,9 @@ <string name="shutdown_confirm" product="tv" msgid="476672373995075359">"Je tv wordt uitgeschakeld.."</string> <string name="shutdown_confirm" product="watch" msgid="3490275567476369184">"Je horloge wordt uitgeschakeld."</string> <string name="shutdown_confirm" product="default" msgid="649792175242821353">"Je telefoon wordt uitgeschakeld."</string> - <string name="shutdown_confirm_question" msgid="2906544768881136183">"Wilt u afsluiten?"</string> + <string name="shutdown_confirm_question" msgid="2906544768881136183">"Wil je afsluiten?"</string> <string name="reboot_safemode_title" msgid="7054509914500140361">"Opnieuw opstarten in veilige modus"</string> - <string name="reboot_safemode_confirm" msgid="55293944502784668">"Wilt u opnieuw opstarten in de veilige modus? Als u dit doet, worden alle geïnstalleerde applicaties van derden uitgeschakeld. Ze worden weer ingeschakeld als u weer opnieuw opstart."</string> + <string name="reboot_safemode_confirm" msgid="55293944502784668">"Wil je opnieuw opstarten in de veilige modus? Als u dit doet, worden alle geïnstalleerde applicaties van derden uitgeschakeld. Ze worden weer ingeschakeld als u weer opnieuw opstart."</string> <string name="recent_tasks_title" msgid="3691764623638127888">"Recent"</string> <string name="no_recent_tasks" msgid="8794906658732193473">"Geen recente apps."</string> <string name="global_actions" product="tablet" msgid="408477140088053665">"Tabletopties"</string> @@ -356,9 +356,9 @@ <string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Hiermee kan de app afspraken toevoegen, verwijderen en wijzigen die u op je tv kunt aanpassen, inclusief afspraken van vrienden of collega\'s. Met deze toestemming zou de app berichten kunnen verzenden die afkomstig lijken te zijn van agenda-eigenaren of afspraken kunnen aanpassen zonder medeweten van de eigenaar."</string> <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Hiermee kan de app afspraken toevoegen, verwijderen en wijzigen die u kunt bewerken op je telefoon, inclusief afspraken van vrienden of collega\'s. Zo kan de app berichten verzenden die afkomstig lijken te zijn van agenda-eigenaren, of afspraken aanpassen zonder medeweten van de eigenaar."</string> <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"toegang tot extra opdrachten van locatieaanbieder"</string> - <string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Hiermee kan de app toegang krijgen tot extra opdrachten voor de locatieprovider. De app kan hiermee de werking van GPS of andere locatiebronnen te verstoren."</string> - <string name="permlab_accessFineLocation" msgid="251034415460950944">"toegang tot precieze locatie (GPS- en netwerkgebaseerd)"</string> - <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Hiermee kan de app je precieze locatie bepalen via GPS (Global Positioning System) of netwerklocatiebronnen zoals zendmasten en wifi. Deze locatieservices moeten zijn ingeschakeld en beschikbaar zijn op je apparaat voordat de app ze kan gebruiken. Apps kunnen dit gebruiken om te bepalen waar u bent en verbruiken mogelijk extra acculading."</string> + <string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Hiermee kan de app toegang krijgen tot extra opdrachten voor de locatieprovider. De app kan hiermee de werking van gps of andere locatiebronnen te verstoren."</string> + <string name="permlab_accessFineLocation" msgid="251034415460950944">"toegang tot precieze locatie (gps- en netwerkgebaseerd)"</string> + <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Hiermee kan de app je precieze locatie bepalen via gps (Global Positioning System) of netwerklocatiebronnen zoals zendmasten en wifi. Deze locatieservices moeten zijn ingeschakeld en beschikbaar zijn op je apparaat voordat de app ze kan gebruiken. Apps kunnen dit gebruiken om te bepalen waar u bent en verbruiken mogelijk extra acculading."</string> <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"toegang tot geschatte locatie (netwerkgebaseerd)"</string> <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Hiermee kan de app beschikken over je geschatte locatie. Deze locatie wordt afgeleid van locatieservices die netwerklocatiebronnen zoals zendmasten en wifi gebruiken. Deze locatieservices moeten zijn ingeschakeld en beschikbaar zijn op je apparaat voordat de app ze kan gebruiken. Apps kunnen dit gebruiken om ongeveer te bepalen waar u zich bevindt."</string> <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"je audio-instellingen wijzigen"</string> @@ -804,7 +804,7 @@ <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Hiermee kan de app berichten toevoegen aan de inbox van je voicemail."</string> <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"geolocatiemachtigingen voor browser aanpassen"</string> <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Hiermee kan de app de geolocatiemachtigingen van de browser aanpassen. Schadelijke apps kunnen dit gebruiken om locatiegegevens te verzenden naar willekeurige websites."</string> - <string name="save_password_message" msgid="767344687139195790">"Wilt u dat de browser dit wachtwoord onthoudt?"</string> + <string name="save_password_message" msgid="767344687139195790">"Wil je dat de browser dit wachtwoord onthoudt?"</string> <string name="save_password_notnow" msgid="6389675316706699758">"Niet nu"</string> <string name="save_password_remember" msgid="6491879678996749466">"Onthouden"</string> <string name="save_password_never" msgid="8274330296785855105">"Nooit"</string> @@ -1010,7 +1010,7 @@ <string name="force_close" msgid="8346072094521265605">"OK"</string> <string name="report" msgid="4060218260984795706">"Melden"</string> <string name="wait" msgid="7147118217226317732">"Wachten"</string> - <string name="webpage_unresponsive" msgid="3272758351138122503">"De pagina reageert niet meer.\n\nWilt u de pagina sluiten?"</string> + <string name="webpage_unresponsive" msgid="3272758351138122503">"De pagina reageert niet meer.\n\nWil je de pagina sluiten?"</string> <string name="launch_warning_title" msgid="1547997780506713581">"App verplaatst"</string> <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> is nu actief."</string> <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> was het eerst gestart."</string> @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Mediavolume"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Meldingsvolume"</string> <string name="ringtone_default" msgid="3789758980357696936">"Standaardbeltoon"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Standaardbeltoon (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Geen"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Beltonen"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Onbekende beltoon"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">Wifi-netwerken beschikbaar</item> <item quantity="one">Wifi-netwerk beschikbaar</item> @@ -1111,7 +1117,7 @@ <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"De verbinding met het wifi-netwerk wordt tijdelijk uitgeschakeld terwijl de telefoon verbonden is met <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string> <string name="select_character" msgid="3365550120617701745">"Teken invoegen"</string> <string name="sms_control_title" msgid="7296612781128917719">"SMS-berichten verzenden"</string> - <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> verzendt moment een groot aantal sms-berichten. Wilt u toestaan dat deze app berichten blijft verzenden?"</string> + <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> verzendt moment een groot aantal sms-berichten. Wil je toestaan dat deze app berichten blijft verzenden?"</string> <string name="sms_control_yes" msgid="3663725993855816807">"Toestaan"</string> <string name="sms_control_no" msgid="625438561395534982">"Weigeren"</string> <string name="sms_short_code_confirm_message" msgid="1645436466285310855">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> wil graag een bericht verzenden naar <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>."</string> @@ -1220,7 +1226,7 @@ <string name="dial_number_using" msgid="5789176425167573586">"Nummer bellen\nmet <xliff:g id="NUMBER">%s</xliff:g>"</string> <string name="create_contact_using" msgid="4947405226788104538">"Contact maken\nmet <xliff:g id="NUMBER">%s</xliff:g>"</string> <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"De volgende apps verzoeken om toegang tot je account, nu en in de toekomst."</string> - <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Wilt u dit verzoek toestaan?"</string> + <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Wil je dit verzoek toestaan?"</string> <string name="grant_permissions_header_text" msgid="6874497408201826708">"Verzoek om toegang"</string> <string name="allow" msgid="7225948811296386551">"Toestaan"</string> <string name="deny" msgid="2081879885755434506">"Weigeren"</string> @@ -1277,7 +1283,7 @@ <string name="gpsVerifYes" msgid="2346566072867213563">"Ja"</string> <string name="gpsVerifNo" msgid="1146564937346454865">"Nee"</string> <string name="sync_too_many_deletes" msgid="5296321850662746890">"Verwijderingslimiet overschreden"</string> - <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"Er zijn <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> verwijderde items voor <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> , account <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> . Wat wilt u doen?"</string> + <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"Er zijn <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> verwijderde items voor <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g> , account <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> . Wat wil je doen?"</string> <string name="sync_really_delete" msgid="2572600103122596243">"De items verwijderen."</string> <string name="sync_undo_deletes" msgid="2941317360600338602">"Verwijderingen ongedaan maken"</string> <string name="sync_do_nothing" msgid="3743764740430821845">"Nu niets doen."</string> diff --git a/core/res/res/values-pa-rIN/strings.xml b/core/res/res/values-pa-rIN/strings.xml index d3476aaa7f51..3e886bccb907 100644 --- a/core/res/res/values-pa-rIN/strings.xml +++ b/core/res/res/values-pa-rIN/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"ਮੀਡੀਆ ਵੌਲਿਊਮ"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"ਸੂਚਨਾ ਵੌਲਿਊਮ"</string> <string name="ringtone_default" msgid="3789758980357696936">"ਪੂਰਵ-ਨਿਰਧਾਰਤ ਰਿੰਗਟੋਨ"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"ਪੂਰਵ-ਨਿਰਧਾਰਤ ਰਿੰਗਟੋਨ (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"ਕੋਈ ਨਹੀਂ"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"ਰਿੰਗਟੋਨਾਂ"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"ਅਗਿਆਤ ਰਿੰਗਟੋਨ"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="one">Wi-Fi ਨੈੱਟਵਰਕਸ ਉਪਲਬਧ</item> <item quantity="other">Wi-Fi ਨੈੱਟਵਰਕਸ ਉਪਲਬਧ</item> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index a7571ef3be75..92a2e2a395ca 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -1105,10 +1105,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Głośność multimediów"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Głośność powiadomień"</string> <string name="ringtone_default" msgid="3789758980357696936">"Dzwonek domyślny"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Dzwonek domyślny (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Brak"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Dzwonki"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Nieznany dzwonek"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="few">Dostępne są sieci Wi-Fi</item> <item quantity="many">Dostępne są sieci Wi-Fi</item> diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml index 24265eef7caf..bf9e15d6b1c6 100644 --- a/core/res/res/values-pt-rBR/strings.xml +++ b/core/res/res/values-pt-rBR/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Volume da mídia"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Volume da notificação"</string> <string name="ringtone_default" msgid="3789758980357696936">"Toque padrão"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Toque padrão (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Nenhum"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Toques"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Toque desconhecido"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="one">Redes Wi-Fi disponíveis</item> <item quantity="other">Redes Wi-Fi disponíveis</item> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index 627021077942..e09daa513c41 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Volume de multimédia"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Volume de notificações"</string> <string name="ringtone_default" msgid="3789758980357696936">"Toque predefinido"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Toque predefinido (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Nada"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Toques"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Toque desconhecido"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">Redes Wi-Fi disponíveis</item> <item quantity="one">Rede Wi-Fi disponível</item> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index 24265eef7caf..bf9e15d6b1c6 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Volume da mídia"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Volume da notificação"</string> <string name="ringtone_default" msgid="3789758980357696936">"Toque padrão"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Toque padrão (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Nenhum"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Toques"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Toque desconhecido"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="one">Redes Wi-Fi disponíveis</item> <item quantity="other">Redes Wi-Fi disponíveis</item> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 29c0a5985220..7f96d2e6afd8 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -1082,10 +1082,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Volumul media"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Volum notificare"</string> <string name="ringtone_default" msgid="3789758980357696936">"Ton de apel prestabilit"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Ton de apel prestabilit (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Niciunul"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Tonuri de sonerie"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Ton de apel necunoscut"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="few">Rețele Wi-Fi disponibile</item> <item quantity="other">Rețele Wi-Fi disponibile</item> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index ed6c798ab066..9e25bb7293cd 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -1105,10 +1105,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Громкость мультимедиа"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Громкость уведомлений"</string> <string name="ringtone_default" msgid="3789758980357696936">"Мелодия по умолчанию"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"По умолчанию (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Без звука"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Мелодии"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Неизвестная мелодия"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="one">Есть доступные сети Wi-Fi</item> <item quantity="few">Есть доступные сети Wi-Fi</item> diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml index 91d5bbed02b5..b106464cfba7 100644 --- a/core/res/res/values-si-rLK/strings.xml +++ b/core/res/res/values-si-rLK/strings.xml @@ -1061,10 +1061,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"මාධ්ය ශබ්දය"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"දැනුම්දීමේ ශබ්ද ත්රීවතාව"</string> <string name="ringtone_default" msgid="3789758980357696936">"සුපුරුදු රින්ටෝනය සකසන්න"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"සුපුරුදු රින්ටෝනය (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"කිසිවක් නැත"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"රිගින්ටෝන"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"නොදන්නා රින්ටෝනය"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="one">Wi-Fi ජාල තිබේ</item> <item quantity="other">Wi-Fi ජාල තිබේ</item> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index 5c129af1d65d..50af3ccbe611 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -1105,10 +1105,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Hlasitosť médií"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Hlasitosť upozornení"</string> <string name="ringtone_default" msgid="3789758980357696936">"Predvolený tón zvonenia"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Predvolený tón (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Žiadny"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Tóny zvonenia"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Neznámy tón zvonenia"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="few">K dispozícii sú siete Wi-Fi</item> <item quantity="many">K dispozícii sú siete Wi-Fi</item> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index 76f1e665f226..5bc756b7554a 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -1105,10 +1105,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Glasnost predstavnosti"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Glasnost obvestila"</string> <string name="ringtone_default" msgid="3789758980357696936">"Privzeta melodija zvonjenja"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Privzeta melodija zvonjenja (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Brez"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Melodije zvonjenja"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Neznana melodija zvonjenja"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="one">Na voljo so omrežja Wi-Fi</item> <item quantity="two">Na voljo so omrežja Wi-Fi</item> diff --git a/core/res/res/values-sq-rAL/strings.xml b/core/res/res/values-sq-rAL/strings.xml index 0fb3ebeec3b4..1095088806a9 100644 --- a/core/res/res/values-sq-rAL/strings.xml +++ b/core/res/res/values-sq-rAL/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"volumi i klipit \"media\""</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Volumi i njoftimeve"</string> <string name="ringtone_default" msgid="3789758980357696936">"Zile e paracaktuar."</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Zilja e paracaktuar (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Asnjë"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Zilet"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Zile e panjohur"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">Rrjete Wi-Fi ofrohen për përdorim</item> <item quantity="one">Një rrjet Wi-Fi ofrohet për përdorim</item> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index fdf8a6d23147..27d7cad02fb5 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -1082,10 +1082,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Јачина звука медија"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Јачина звука обавештења"</string> <string name="ringtone_default" msgid="3789758980357696936">"Подразумевани звук звона"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Подразумевани звук звона (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Без звука"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Звукови звона"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Непознати звук звона"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="one">Wi-Fi мреже су доступне</item> <item quantity="few">Wi-Fi мреже су доступне</item> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index 340010fa86e4..b048762ca934 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Mediavolym"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Meddelandevolym"</string> <string name="ringtone_default" msgid="3789758980357696936">"Standardringsignal"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Standardringsignal (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Ingen"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Ringsignaler"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Okänd ringsignal"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">Wi-Fi-nätverk är tillgängliga</item> <item quantity="one">Wi-Fi-nätverk är tillgängligt</item> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index 48325465cd6b..6cfd253b6f61 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -1057,10 +1057,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Sauti ya midia"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Sauti ya arifa"</string> <string name="ringtone_default" msgid="3789758980357696936">"Mlio chaguo-msingi"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Mlio chaguo-msingi (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Hamna"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Toni za mlio"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Mlio amabo haujulikani"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">Mitandao ya Wi-Fi inapatikana</item> <item quantity="one">Mtandao wa Wi-Fi unapatikana</item> diff --git a/core/res/res/values-ta-rIN/strings.xml b/core/res/res/values-ta-rIN/strings.xml index f6bb25cbf94f..b39191226846 100644 --- a/core/res/res/values-ta-rIN/strings.xml +++ b/core/res/res/values-ta-rIN/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"மீடியாவின் ஒலியளவு"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"அறிவிப்பின் ஒலியளவு"</string> <string name="ringtone_default" msgid="3789758980357696936">"இயல்புநிலை ரிங்டோன்"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"இயல்புநிலை ரிங்டோன் (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"ஏதுமில்லை"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"ரிங்டோன்கள்"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"அறியப்படாத ரிங்டோன்"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">வைஃபை நெட்வொர்க்குகள் உள்ளன</item> <item quantity="one">வைஃபை நெட்வொர்க் உள்ளது</item> diff --git a/core/res/res/values-te-rIN/strings.xml b/core/res/res/values-te-rIN/strings.xml index 24bfebd29e27..5ec586ffdd1e 100644 --- a/core/res/res/values-te-rIN/strings.xml +++ b/core/res/res/values-te-rIN/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"మీడియా వాల్యూమ్"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"నోటిఫికేషన్ వాల్యూమ్"</string> <string name="ringtone_default" msgid="3789758980357696936">"డిఫాల్ట్ రింగ్టోన్"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"డిఫాల్ట్ రింగ్టోన్ (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"ఏదీ వద్దు"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"రింగ్టోన్లు"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"తెలియని రింగ్టోన్"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">Wi-Fi నెట్వర్క్లు అందుబాటులో ఉన్నాయి</item> <item quantity="one">Wi-Fi నెట్వర్క్ అందుబాటులో ఉంది</item> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index 818bb9f835cc..15cbd94291d5 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"ระดับเสียงของสื่อ"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"ระดับเสียงของการแจ้งเตือน"</string> <string name="ringtone_default" msgid="3789758980357696936">"เสียงเรียกเข้าเริ่มต้น"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"เสียงเรียกเข้าเริ่มต้น (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"ไม่มี"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"เสียงเรียกเข้า"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"ไม่ทราบเสียงเรียกเข้า"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">มีหลายเครือข่าย Wi-Fi ที่ใช้งานได้</item> <item quantity="one">มี 1 เครือข่าย Wi-Fi ที่ใช้งานได้</item> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index 81c5fd052342..31666ee4f062 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Volume ng media"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Volume ng notification"</string> <string name="ringtone_default" msgid="3789758980357696936">"Default na ringtone"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Default na ringtone (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Wala"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Mga Ringtone"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Hindi kilalang ringtone"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="one">Available ang mga Wi-Fi network</item> <item quantity="other">Available ang mga Wi-Fi network</item> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index 12a5b7c1a025..012606833bb7 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Medya ses düzeyi"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Bildirim ses düzeyi"</string> <string name="ringtone_default" msgid="3789758980357696936">"Varsayılan zil sesi"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Varsayılan zil sesi (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Yok"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Zil sesleri"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Bilinmeyen zil sesi"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">Kablosuz ağlar var</item> <item quantity="one">Kablosuz ağ var</item> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index fb0fda886797..104badd52633 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -1105,10 +1105,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Гучність медіа"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Гучність сповіщення"</string> <string name="ringtone_default" msgid="3789758980357696936">"Мелодія за умовчанням"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Мелодія за умовчанням (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Немає"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Мелодії"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Невідома мелодія"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="one">Мережі Wi-Fi доступні</item> <item quantity="few">Мережі Wi-Fi доступні</item> diff --git a/core/res/res/values-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml index d6eae64a9f6d..f8224f29a948 100644 --- a/core/res/res/values-ur-rPK/strings.xml +++ b/core/res/res/values-ur-rPK/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"میڈیا والیوم"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"اطلاع کا والیوم"</string> <string name="ringtone_default" msgid="3789758980357696936">"ڈیفالٹ رنگ ٹون"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"ڈیفالٹ رنگ ٹون (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"کوئی نہیں"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"رنگ ٹونز"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"نامعلوم رنگ ٹون"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">Wi-Fi نیٹ ورکس دستیاب ہیں</item> <item quantity="one">Wi-Fi نیٹ ورک دستیاب ہے</item> diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml index 5b7cf74c732c..78b5400d6dc2 100644 --- a/core/res/res/values-uz-rUZ/strings.xml +++ b/core/res/res/values-uz-rUZ/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Multimedia ovozi"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Eslatma tovushi"</string> <string name="ringtone_default" msgid="3789758980357696936">"Standart rington"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Standart rington (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Yo‘q"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Ringtonlar"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Noma’lum rington"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">Wi-Fi tarmoqlari aniqlandi</item> <item quantity="one">Wi-Fi tarmog‘i aniqlandi</item> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index 42e0b0a74868..ca5e3bcc9ff9 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Âm lượng phương tiện"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Âm lượng thông báo"</string> <string name="ringtone_default" msgid="3789758980357696936">"Nhạc chuông mặc định"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Nhạc chuông mặc định (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Không"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Nhạc chuông"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Nhạc chuông không xác định"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">Các mạng Wi-Fi khả dụng</item> <item quantity="one">Mạng Wi-Fi khả dụng</item> diff --git a/core/res/res/values-watch/themes_device_defaults.xml b/core/res/res/values-watch/themes_device_defaults.xml index aa1594d46516..fbe780db6fae 100644 --- a/core/res/res/values-watch/themes_device_defaults.xml +++ b/core/res/res/values-watch/themes_device_defaults.xml @@ -314,7 +314,7 @@ a similar way. <item name="colorPrimary">@color/primary_device_default_dark</item> <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item> <item name="colorAccent">@color/accent_device_default_dark</item> - <item name="colorBackground">?attr/colorBackgroundFloating</item> + <item name="colorBackground">@color/background_device_default_dark</item> <item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item> <item name="colorBackgroundCacheHint">@color/background_cache_hint_selector_device_default</item> <item name="colorButtonNormal">@color/button_normal_device_default_dark</item> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index 68e87c265e18..2126d127967b 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"媒体音量"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"通知音量"</string> <string name="ringtone_default" msgid="3789758980357696936">"默认铃声"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"默认铃声(<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"无"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"铃声"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"未知铃声"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">有可用的 WLAN 网络</item> <item quantity="one">有可用的 WLAN 网络</item> diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index 62bb44af8b2d..bdd9fe3ee551 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"媒體音量"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"通知音量"</string> <string name="ringtone_default" msgid="3789758980357696936">"預設鈴聲"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"預設鈴聲 (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"無"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"鈴聲"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"不明鈴聲"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">有可用的 Wi-Fi 網絡</item> <item quantity="one">有可用的 Wi-Fi 網絡</item> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index 0500c0713413..3c2146bd2789 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"媒體音量"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"通知音量"</string> <string name="ringtone_default" msgid="3789758980357696936">"預設鈴聲"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"預設鈴聲 (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"無"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"鈴聲"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"未知的鈴聲"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="other">有多個可用的 Wi-Fi 網路</item> <item quantity="one">有一個可用的 Wi-Fi 網路</item> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index 849f292c196c..011e4f744d3b 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -1059,10 +1059,16 @@ <string name="volume_icon_description_media" msgid="4217311719665194215">"Ivolumu yemidiya"</string> <string name="volume_icon_description_notification" msgid="7044986546477282274">"Ivolumu yesaziso"</string> <string name="ringtone_default" msgid="3789758980357696936">"Iringithoni emisiwe"</string> - <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Iringithoni ezenzakalelayo <xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>"</string> + <!-- no translation found for ringtone_default_with_actual (1767304850491060581) --> + <skip /> <string name="ringtone_silent" msgid="7937634392408977062">"Akunalutho"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Amaringithoni"</string> - <string name="ringtone_unknown" msgid="5477919988701784788">"Iringithoni engaziwa"</string> + <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) --> + <skip /> + <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) --> + <skip /> + <!-- no translation found for ringtone_unknown (3914515995813061520) --> + <skip /> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="one">Amanethiwekhi we-Wi-Fi ayatholakala</item> <item quantity="other">Amanethiwekhi we-Wi-Fi ayatholakala</item> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 2d61e6ec3bc5..acafbcfd428a 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -582,7 +582,7 @@ <!-- Image elements --> <!-- ============== --> <eat-comment /> -i + <!-- Background that can be used behind parts of a UI that provide details on data the user is selecting. For example, this is the background element of PreferenceActivity's embedded @@ -1008,6 +1008,15 @@ i <!-- Background to use for toasts --> <attr name="toastFrameBackground" format="reference" /> + <!-- Background to use for tooltip popups --> + <attr name="tooltipFrameBackground" format="reference" /> + + <!-- Foreground color to use for tooltip popups --> + <attr name="tooltipForegroundColor" format="reference|color" /> + + <!-- Background color to use for tooltip popups --> + <attr name="tooltipBackgroundColor" format="reference|color" /> + <!-- Theme to use for Search Dialogs --> <attr name="searchDialogTheme" format="reference" /> @@ -2865,6 +2874,9 @@ i {@link android.view.View#forceHasOverlappingRendering(boolean)}. --> <attr name="forceHasOverlappingRendering" format="boolean" /> + <!-- Defines text displayed in a small popup window on hover or long press. --> + <attr name="tooltip" format="string" localization="suggested" /> + </declare-styleable> <!-- Attributes that can be assigned to a tag for a particular View. --> diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml index de86cefb5bc7..0995bc3f0799 100644 --- a/core/res/res/values/colors.xml +++ b/core/res/res/values/colors.xml @@ -186,4 +186,7 @@ <color name="resize_shadow_start_color">#2a000000</color> <color name="resize_shadow_end_color">#00000000</color> + + <color name="tooltip_background_dark">#e6616161</color> + <color name="tooltip_background_light">#e6FFFFFF</color> </resources> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index d4119d072a46..a7c5b2ab3c80 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -128,6 +128,9 @@ <integer name="config_activityShortDur">150</integer> <integer name="config_activityDefaultDur">220</integer> + <!-- The duration (in milliseconds) of the tooltip show/hide animations. --> + <integer name="config_tooltipAnimTime">150</integer> + <!-- Duration for the dim animation behind a dialog. This may be either a percentage, which is relative to the duration of the enter/open animation of the window being shown that is dimming behind, or it may diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index 91d7227c6a60..5efa55ca1138 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -487,4 +487,19 @@ <!-- Minimum "smallest width" of the display for cascading menus to be enabled. --> <dimen name="cascading_menus_min_smallest_width">720dp</dimen> + + <!-- Tooltip dimensions. --> + <!-- Vertical offset from the edge of the anchor view. --> + <dimen name="tooltip_y_offset">20dp</dimen> + <!-- Height of the tooltip. --> + <dimen name="tooltip_height">32dp</dimen> + <!-- The tooltip does not get closer than this to the window edge --> + <dimen name="tooltip_margin">8dp</dimen> + <!-- Left/right padding of the tooltip text. --> + <dimen name="tooltip_horizontal_padding">16dp</dimen> + <!-- Border corner radius of the tooltip window. --> + <dimen name="tooltip_corner_radius">2dp</dimen> + <!-- View with the height equal or above this threshold will have a tooltip anchored + to the mouse/touch position --> + <dimen name="tooltip_precise_anchor_threshold">96dp</dimen> </resources> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index ed685822ee51..ae82128b88cf 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -2759,6 +2759,7 @@ <public name="fontStyle" /> <public name="font" /> <public name="fontWeight" /> + <public name="tooltip" /> </public-group> <public-group type="style" first-id="0x010302e0"> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index d42ec9067ac4..baf3cd817d5b 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -4450,4 +4450,7 @@ <!-- Label used by Telephony code, assigned as the display name for conference calls [CHAR LIMIT=60] --> <string name="conference_call">Conference Call</string> + + <!-- Title for a tooltip popup window [CHAR LIMIT=NONE] --> + <string name="tooltip_popup_title">Tooltip Popup</string> </resources> diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml index 937428b12c60..0f756b94a321 100644 --- a/core/res/res/values/styles.xml +++ b/core/res/res/values/styles.xml @@ -159,6 +159,11 @@ please see styles_device_defaults.xml. <item name="windowExitAnimation">@anim/toast_exit</item> </style> + <style name="Animation.Tooltip"> + <item name="windowEnterAnimation">@anim/tooltip_enter</item> + <item name="windowExitAnimation">@anim/tooltip_exit</item> + </style> + <style name="Animation.DropDownDown"> <item name="windowEnterAnimation">@anim/grow_fade_in</item> <item name="windowExitAnimation">@anim/shrink_fade_out</item> @@ -950,6 +955,11 @@ please see styles_device_defaults.xml. <item name="fontFamily">sans-serif-condensed</item> </style> + <style name="TextAppearance.Tooltip"> + <item name="fontFamily">sans-serif</item> + <item name="textSize">14sp</item> + </style> + <style name="Widget.ActivityChooserView"> <item name="gravity">center</item> <item name="background">@drawable/ab_share_pack_holo_dark</item> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index c719664c38a8..5b608b84c51d 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -435,6 +435,8 @@ <java-symbol type="dimen" name="search_view_preferred_height" /> <java-symbol type="dimen" name="textview_error_popup_default_width" /> <java-symbol type="dimen" name="toast_y_offset" /> + <java-symbol type="dimen" name="tooltip_precise_anchor_threshold" /> + <java-symbol type="dimen" name="tooltip_y_offset" /> <java-symbol type="dimen" name="action_bar_stacked_max_height" /> <java-symbol type="dimen" name="action_bar_stacked_tab_max_width" /> <java-symbol type="dimen" name="notification_text_size" /> @@ -1123,6 +1125,7 @@ <java-symbol type="string" name="demo_starting_message" /> <java-symbol type="string" name="demo_restarting_message" /> <java-symbol type="string" name="conference_call" /> + <java-symbol type="string" name="tooltip_popup_title" /> <java-symbol type="plurals" name="bugreport_countdown" /> @@ -1373,6 +1376,7 @@ <java-symbol type="layout" name="textview_hint" /> <java-symbol type="layout" name="time_picker_legacy" /> <java-symbol type="layout" name="time_picker_dialog" /> + <java-symbol type="layout" name="tooltip" /> <java-symbol type="layout" name="transient_notification" /> <java-symbol type="layout" name="voice_interaction_session" /> <java-symbol type="layout" name="web_text_view_dropdown" /> @@ -1423,6 +1427,7 @@ <java-symbol type="style" name="Animation.DropDownUp" /> <java-symbol type="style" name="Animation.DropDownDown" /> <java-symbol type="style" name="Animation.PopupWindow" /> + <java-symbol type="style" name="Animation.Tooltip" /> <java-symbol type="style" name="Animation.TypingFilter" /> <java-symbol type="style" name="Animation.TypingFilterRestore" /> <java-symbol type="style" name="Animation.Dream" /> diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml index 5b2522f97c8b..357eb4b88c52 100644 --- a/core/res/res/values/themes.xml +++ b/core/res/res/values/themes.xml @@ -439,6 +439,11 @@ please see themes_device_defaults.xml. <item name="lightRadius">@dimen/light_radius</item> <item name="ambientShadowAlpha">@dimen/ambient_shadow_alpha</item> <item name="spotShadowAlpha">@dimen/spot_shadow_alpha</item> + + <!-- Tooltip popup properties --> + <item name="tooltipFrameBackground">@drawable/tooltip_frame</item> + <item name="tooltipForegroundColor">@color/bright_foreground_light</item> + <item name="tooltipBackgroundColor">@color/tooltip_background_light</item> </style> <!-- Variant of {@link #Theme} with no title bar --> @@ -553,6 +558,10 @@ please see themes_device_defaults.xml. <item name="floatingToolbarItemBackgroundDrawable">@drawable/item_background_material_light</item> <item name="floatingToolbarOpenDrawable">@drawable/ic_menu_moreoverflow_material_light</item> <item name="floatingToolbarPopupBackgroundDrawable">@drawable/floating_popup_background_light</item> + + <!-- Tooltip popup colors --> + <item name="tooltipForegroundColor">@color/bright_foreground_dark</item> + <item name="tooltipBackgroundColor">@color/tooltip_background_dark</item> </style> <!-- Variant of {@link #Theme_Light} with no title bar --> diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml index 0de773bc3724..92bb3ea4681d 100644 --- a/core/res/res/values/themes_material.xml +++ b/core/res/res/values/themes_material.xml @@ -398,6 +398,10 @@ please see themes_device_defaults.xml. <item name="colorControlHighlight">@color/ripple_material_dark</item> <item name="colorButtonNormal">@color/btn_default_material_dark</item> <item name="colorSwitchThumbNormal">@color/switch_thumb_material_dark</item> + + <!-- Tooltip popup properties --> + <item name="tooltipForegroundColor">@color/foreground_material_light</item> + <item name="tooltipBackgroundColor">@color/tooltip_background_light</item> </style> <!-- Material theme (light version). --> @@ -762,6 +766,10 @@ please see themes_device_defaults.xml. <item name="colorControlHighlight">@color/ripple_material_light</item> <item name="colorButtonNormal">@color/btn_default_material_light</item> <item name="colorSwitchThumbNormal">@color/switch_thumb_material_light</item> + + <!-- Tooltip popup properties --> + <item name="tooltipForegroundColor">@color/foreground_material_dark</item> + <item name="tooltipBackgroundColor">@color/tooltip_background_dark</item> </style> <!-- Variant of the material (light) theme that has a solid (opaque) action bar diff --git a/core/tests/coretests/src/android/provider/SettingsProviderTest.java b/core/tests/coretests/src/android/provider/SettingsProviderTest.java index e6d315844d72..0a32e4353e1c 100644 --- a/core/tests/coretests/src/android/provider/SettingsProviderTest.java +++ b/core/tests/coretests/src/android/provider/SettingsProviderTest.java @@ -349,6 +349,7 @@ public class SettingsProviderTest extends AndroidTestCase { assertCanBeHandled(new Intent(Settings.ACTION_USER_DICTIONARY_SETTINGS)); assertCanBeHandled(new Intent(Settings.ACTION_WIFI_IP_SETTINGS)); assertCanBeHandled(new Intent(Settings.ACTION_WIFI_SETTINGS)); + assertCanBeHandled(new Intent(Settings.ACTION_WIFI_SAVED_NETWORK_SETTINGS)); assertCanBeHandled(new Intent(Settings.ACTION_WIRELESS_SETTINGS)); } diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java index 40a2833977af..00b5eda6d7ff 100644 --- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java @@ -15,14 +15,14 @@ package android.graphics.drawable; import android.animation.Animator; +import android.animation.Animator.AnimatorListener; import android.animation.AnimatorInflater; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; -import android.animation.Animator.AnimatorListener; +import android.animation.ObjectAnimator; import android.animation.PropertyValuesHolder; import android.animation.TimeInterpolator; import android.animation.ValueAnimator; -import android.animation.ObjectAnimator; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityThread; @@ -55,11 +55,8 @@ import android.view.RenderNodeAnimatorSetHelper; import android.view.View; import com.android.internal.R; - import com.android.internal.util.VirtualRefBasePtr; -import dalvik.annotation.optimization.FastNative; - import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -67,6 +64,8 @@ import java.io.IOException; import java.lang.ref.WeakReference; import java.util.ArrayList; +import dalvik.annotation.optimization.FastNative; + /** * This class animates properties of a {@link android.graphics.drawable.VectorDrawable} with * animations defined using {@link android.animation.ObjectAnimator} or @@ -91,9 +90,77 @@ import java.util.ArrayList; * <a name="VDExample"></a> * <li><h4>XML for the VectorDrawable containing properties to be animated</h4> * <p> - * Animations can be performed on both group and path attributes, which requires groups and paths to - * have unique names in the same VectorDrawable. Groups and paths without animations do not need to - * be named. + * Animations can be performed on the animatable attributes in + * {@link android.graphics.drawable.VectorDrawable}. These attributes will be animated by + * {@link android.animation.ObjectAnimator}. The ObjectAnimator's target can be the root element, + * a group element or a path element. The targeted elements need to be named uniquely within + * the same VectorDrawable. Elements without animation do not need to be named. + * </p> + * <p> + * Here are all the animatable attributes in {@link android.graphics.drawable.VectorDrawable}: + * <table border="2" align="center" cellpadding="5"> + * <thead> + * <tr> + * <th>Element Name</th> + * <th>Animatable attribute name</th> + * </tr> + * </thead> + * <tr> + * <td><vector></td> + * <td>alpha</td> + * </tr> + * <tr> + * <td rowspan="7"><group></td> + * <td>rotation</td> + * </tr> + * <tr> + * <td>pivotX</td> + * </tr> + * <tr> + * <td>pivotY</td> + * </tr> + * <tr> + * <td>scaleX</td> + * </tr> + * <tr> + * <td>scaleY</td> + * </tr> + * <tr> + * <td>translateX</td> + * </tr> + * <tr> + * <td>translateY</td> + * </tr> + * <tr> + * <td rowspan="8"><path></td> + * <td>pathData</td> + * </tr> + * <tr> + * <td>fillColor</td> + * </tr> + * <tr> + * <td>strokeColor</td> + * </tr> + * <tr> + * <td>strokeWidth</td> + * </tr> + * <tr> + * <td>strokeAlpha</td> + * </tr> + * <tr> + * <td>fillAlpha</td> + * </tr> + * <tr> + * <td>trimPathStart</td> + * </tr> + * <tr> + * <td>trimPathOffset</td> + * </tr> + * <tr> + * <td><clip-path></td> + * <td>pathData</td> + * </tr> + * </table> * </p> * Below is an example of a VectorDrawable defined in vectordrawable.xml. This VectorDrawable is * referred to by its file name (not including file suffix) in the @@ -121,9 +188,8 @@ import java.util.ArrayList; * <li><h4>XML for AnimatedVectorDrawable</h4> * <p> * An AnimatedVectorDrawable element has a VectorDrawable attribute, and one or more target - * element(s). The target elements can be the path or group to be animated. Each target element - * contains a name attribute that references a property (of a path or a group) to animate, and an - * animation attribute that points to an ObjectAnimator or an AnimatorSet. + * element(s). The target element can specify its target by android:name attribute, and link the + * target with the proper ObjectAnimator or AnimatorSet by android:animation attribute. * </p> * The following code sample defines an AnimatedVectorDrawable. Note that the names refer to the * groups and paths in the <a href="#VDExample">VectorDrawable XML above</a>. @@ -176,7 +242,8 @@ import java.util.ArrayList; * merge the XML files from the previous examples into one XML file: * </p> * <pre> - * <animated-vector xmlns:android="http://schemas.android.com/apk/res/android" > + * <animated-vector xmlns:android="http://schemas.android.com/apk/res/android" + * xmlns:aapt="http://schemas.android.com/aapt" > * <aapt:attr name="android:drawable"> * <vector * android:height="64dp" diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java index e83104deb134..3a12419c8774 100644 --- a/graphics/java/android/graphics/drawable/VectorDrawable.java +++ b/graphics/java/android/graphics/drawable/VectorDrawable.java @@ -77,36 +77,27 @@ import dalvik.system.VMRuntime; * <dl> * <dt><code>android:name</code></dt> * <dd>Defines the name of this vector drawable.</dd> - * <dd>Animatable : No.</dd> * <dt><code>android:width</code></dt> * <dd>Used to define the intrinsic width of the drawable. * This support all the dimension units, normally specified with dp.</dd> - * <dd>Animatable : No.</dd> * <dt><code>android:height</code></dt> * <dd>Used to define the intrinsic height the drawable. * This support all the dimension units, normally specified with dp.</dd> - * <dd>Animatable : No.</dd> * <dt><code>android:viewportWidth</code></dt> * <dd>Used to define the width of the viewport space. Viewport is basically * the virtual canvas where the paths are drawn on.</dd> - * <dd>Animatable : No.</dd> * <dt><code>android:viewportHeight</code></dt> * <dd>Used to define the height of the viewport space. Viewport is basically * the virtual canvas where the paths are drawn on.</dd> - * <dd>Animatable : No.</dd> * <dt><code>android:tint</code></dt> * <dd>The color to apply to the drawable as a tint. By default, no tint is applied.</dd> - * <dd>Animatable : No.</dd> * <dt><code>android:tintMode</code></dt> - * <dd>The Porter-Duff blending mode for the tint color. The default value is src_in.</dd> - * <dd>Animatable : No.</dd> + * <dd>The Porter-Duff blending mode for the tint color. Default is src_in.</dd> * <dt><code>android:autoMirrored</code></dt> * <dd>Indicates if the drawable needs to be mirrored when its layout direction is - * RTL (right-to-left).</dd> - * <dd>Animatable : No.</dd> + * RTL (right-to-left). Default is false.</dd> * <dt><code>android:alpha</code></dt> - * <dd>The opacity of this drawable.</dd> - * <dd>Animatable : Yes.</dd> + * <dd>The opacity of this drawable. Default is 1.0.</dd> * </dl></dd> * </dl> * @@ -118,32 +109,24 @@ import dalvik.system.VMRuntime; * <dl> * <dt><code>android:name</code></dt> * <dd>Defines the name of the group.</dd> - * <dd>Animatable : No.</dd> * <dt><code>android:rotation</code></dt> - * <dd>The degrees of rotation of the group.</dd> - * <dd>Animatable : Yes.</dd> + * <dd>The degrees of rotation of the group. Default is 0.</dd> * <dt><code>android:pivotX</code></dt> * <dd>The X coordinate of the pivot for the scale and rotation of the group. - * This is defined in the viewport space.</dd> - * <dd>Animatable : Yes.</dd> + * This is defined in the viewport space. Default is 0.</dd> * <dt><code>android:pivotY</code></dt> * <dd>The Y coordinate of the pivot for the scale and rotation of the group. - * This is defined in the viewport space.</dd> - * <dd>Animatable : Yes.</dd> + * This is defined in the viewport space. Default is 0.</dd> * <dt><code>android:scaleX</code></dt> - * <dd>The amount of scale on the X Coordinate.</dd> - * <dd>Animatable : Yes.</dd> + * <dd>The amount of scale on the X Coordinate. Default is 1.</dd> * <dt><code>android:scaleY</code></dt> - * <dd>The amount of scale on the Y coordinate.</dd> - * <dd>Animatable : Yes.</dd> + * <dd>The amount of scale on the Y coordinate. Default is 1.</dd> * <dt><code>android:translateX</code></dt> * <dd>The amount of translation on the X coordinate. - * This is defined in the viewport space.</dd> - * <dd>Animatable : Yes.</dd> + * This is defined in the viewport space. Default is 0.</dd> * <dt><code>android:translateY</code></dt> * <dd>The amount of translation on the Y coordinate. - * This is defined in the viewport space.</dd> - * <dd>Animatable : Yes.</dd> + * This is defined in the viewport space. Default is 0.</dd> * </dl></dd> * </dl> * @@ -153,58 +136,44 @@ import dalvik.system.VMRuntime; * <dl> * <dt><code>android:name</code></dt> * <dd>Defines the name of the path.</dd> - * <dd>Animatable : No.</dd> * <dt><code>android:pathData</code></dt> * <dd>Defines path data using exactly same format as "d" attribute * in the SVG's path data. This is defined in the viewport space.</dd> - * <dd>Animatable : Yes.</dd> * <dt><code>android:fillColor</code></dt> * <dd>Specifies the color used to fill the path. May be a color or, for SDK 24+, a color state list * or a gradient color (See {@link android.R.styleable#GradientColor} * and {@link android.R.styleable#GradientColorItem}). * If this property is animated, any value set by the animation will override the original value. * No path fill is drawn if this property is not specified.</dd> - * <dd>Animatable : Yes.</dd> * <dt><code>android:strokeColor</code></dt> * <dd>Specifies the color used to draw the path outline. May be a color or, for SDK 24+, a color * state list or a gradient color (See {@link android.R.styleable#GradientColor} * and {@link android.R.styleable#GradientColorItem}). * If this property is animated, any value set by the animation will override the original value. * No path outline is drawn if this property is not specified.</dd> - * <dd>Animatable : Yes.</dd> * <dt><code>android:strokeWidth</code></dt> - * <dd>The width a path stroke.</dd> - * <dd>Animatable : Yes.</dd> + * <dd>The width a path stroke. Default is 0.</dd> * <dt><code>android:strokeAlpha</code></dt> - * <dd>The opacity of a path stroke.</dd> - * <dd>Animatable : Yes.</dd> + * <dd>The opacity of a path stroke. Default is 1.</dd> * <dt><code>android:fillAlpha</code></dt> - * <dd>The opacity to fill the path with.</dd> - * <dd>Animatable : Yes.</dd> + * <dd>The opacity to fill the path with. Default is 1.</dd> * <dt><code>android:trimPathStart</code></dt> - * <dd>The fraction of the path to trim from the start, in the range from 0 to 1.</dd> - * <dd>Animatable : Yes.</dd> + * <dd>The fraction of the path to trim from the start, in the range from 0 to 1. Default is 0.</dd> * <dt><code>android:trimPathEnd</code></dt> - * <dd>The fraction of the path to trim from the end, in the range from 0 to 1.</dd> - * <dd>Animatable : Yes.</dd> + * <dd>The fraction of the path to trim from the end, in the range from 0 to 1. Default is 1.</dd> * <dt><code>android:trimPathOffset</code></dt> * <dd>Shift trim region (allows showed region to include the start and end), in the range - * from 0 to 1.</dd> - * <dd>Animatable : Yes.</dd> + * from 0 to 1. Default is 0.</dd> * <dt><code>android:strokeLineCap</code></dt> - * <dd>Sets the linecap for a stroked path: butt, round, square.</dd> - * <dd>Animatable : No.</dd> + * <dd>Sets the linecap for a stroked path: butt, round, square. Default is butt.</dd> * <dt><code>android:strokeLineJoin</code></dt> - * <dd>Sets the lineJoin for a stroked path: miter,round,bevel.</dd> - * <dd>Animatable : No.</dd> + * <dd>Sets the lineJoin for a stroked path: miter,round,bevel. Default is miter.</dd> * <dt><code>android:strokeMiterLimit</code></dt> - * <dd>Sets the Miter limit for a stroked path.</dd> - * <dd>Animatable : No.</dd> + * <dd>Sets the Miter limit for a stroked path. Default is 4.</dd> * <dt><code>android:fillType</code></dt> - * <dd>Sets the fillType for a path. The types can be either "evenOdd" or "nonZero". They behave the - * same as SVG's "fill-rule" properties. For more details, see + * <dd>For SDK 24+, sets the fillType for a path. The types can be either "evenOdd" or "nonZero". They behave the + * same as SVG's "fill-rule" properties. Default is nonZero. For more details, see * <a href="https://www.w3.org/TR/SVG/painting.html#FillRuleProperty">FillRuleProperty</a></dd> - * <dd>Animatable : No.</dd> * </dl></dd> * * </dl> diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java index 89709ee6b95a..5440f0fc214f 100644 --- a/media/java/android/media/AudioAttributes.java +++ b/media/java/android/media/AudioAttributes.java @@ -584,6 +584,10 @@ public final class AudioAttributes implements Parcelable { * @return the same Builder instance. */ public Builder setLegacyStreamType(int streamType) { + if (streamType == AudioManager.STREAM_ACCESSIBILITY) { + throw new IllegalArgumentException("STREAM_ACCESSIBILITY is not a legacy stream " + + "type that was used for audio playback"); + } return setInternalLegacyStreamType(streamType); } @@ -624,12 +628,15 @@ public final class AudioAttributes implements Parcelable { mContentType = CONTENT_TYPE_SONIFICATION; break; case AudioSystem.STREAM_TTS: + mContentType = CONTENT_TYPE_SONIFICATION; + break; + case AudioSystem.STREAM_ACCESSIBILITY: mContentType = CONTENT_TYPE_SPEECH; break; default: Log.e(TAG, "Invalid stream type " + streamType + " for AudioAttributes"); } - mUsage = usageForLegacyStreamType(streamType); + mUsage = usageForStreamType(streamType); return this; } @@ -842,8 +849,7 @@ public final class AudioAttributes implements Parcelable { } } - /** @hide */ - public static int usageForLegacyStreamType(int streamType) { + private static int usageForStreamType(int streamType) { switch(streamType) { case AudioSystem.STREAM_VOICE_CALL: return USAGE_VOICE_COMMUNICATION; @@ -862,8 +868,9 @@ public final class AudioAttributes implements Parcelable { return USAGE_VOICE_COMMUNICATION; case AudioSystem.STREAM_DTMF: return USAGE_VOICE_COMMUNICATION_SIGNALLING; - case AudioSystem.STREAM_TTS: + case AudioSystem.STREAM_ACCESSIBILITY: return USAGE_ASSISTANCE_ACCESSIBILITY; + case AudioSystem.STREAM_TTS: default: return USAGE_UNKNOWN; } @@ -915,7 +922,6 @@ public final class AudioAttributes implements Parcelable { switch (aa.getUsage()) { case USAGE_MEDIA: case USAGE_GAME: - case USAGE_ASSISTANCE_ACCESSIBILITY: case USAGE_ASSISTANCE_NAVIGATION_GUIDANCE: return AudioSystem.STREAM_MUSIC; case USAGE_ASSISTANCE_SONIFICATION: @@ -935,6 +941,8 @@ public final class AudioAttributes implements Parcelable { case USAGE_NOTIFICATION_COMMUNICATION_DELAYED: case USAGE_NOTIFICATION_EVENT: return AudioSystem.STREAM_NOTIFICATION; + case USAGE_ASSISTANCE_ACCESSIBILITY: + return AudioSystem.STREAM_ACCESSIBILITY; case USAGE_UNKNOWN: return fromGetVolumeControlStream ? AudioManager.USE_DEFAULT_STREAM_TYPE : AudioSystem.STREAM_MUSIC; diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index f24bf095eb10..435e6ba159e9 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -335,6 +335,9 @@ public class AudioManager { /** @hide Used to identify the volume of audio streams exclusively transmitted through the * speaker (TTS) of the device */ public static final int STREAM_TTS = AudioSystem.STREAM_TTS; + /** Used to identify the volume of audio streams for accessibility prompts */ + public static final int STREAM_ACCESSIBILITY = AudioSystem.STREAM_ACCESSIBILITY; + /** Number of audio streams */ /** * @deprecated Do not iterate on volume stream type values. diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java index 384be5cb88d0..28c7253f8c76 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -63,13 +63,15 @@ public class AudioSystem /** Used to identify the volume of audio streams exclusively transmitted through the * speaker (TTS) of the device */ public static final int STREAM_TTS = 9; + /** Used to identify the volume of audio streams for accessibility prompts */ + public static final int STREAM_ACCESSIBILITY = 10; /** * @deprecated Use {@link #numStreamTypes() instead} */ public static final int NUM_STREAMS = 5; // Expose only the getter method publicly so we can change it in the future - private static final int NUM_STREAM_TYPES = 10; + private static final int NUM_STREAM_TYPES = 11; public static final int getNumStreamTypes() { return NUM_STREAM_TYPES; } public static final String[] STREAM_NAMES = new String[] { @@ -82,7 +84,8 @@ public class AudioSystem "STREAM_BLUETOOTH_SCO", "STREAM_SYSTEM_ENFORCED", "STREAM_DTMF", - "STREAM_TTS" + "STREAM_TTS", + "STREAM_ACCESSIBILITY" }; /* @@ -773,7 +776,8 @@ public class AudioSystem 7, // STREAM_BLUETOOTH_SCO 7, // STREAM_SYSTEM_ENFORCED 11, // STREAM_DTMF - 11 // STREAM_TTS + 11, // STREAM_TTS + 11, // STREAM_ACCESSIBILITY }; public static String streamToString(int stream) { diff --git a/media/java/android/media/MediaHTTPService.java b/media/java/android/media/MediaHTTPService.java index 2348ab7c7585..52a68bfd96f9 100644 --- a/media/java/android/media/MediaHTTPService.java +++ b/media/java/android/media/MediaHTTPService.java @@ -17,6 +17,7 @@ package android.media; import android.os.IBinder; +import android.util.Log; /** @hide */ public class MediaHTTPService extends IMediaHTTPService.Stub { @@ -31,10 +32,10 @@ public class MediaHTTPService extends IMediaHTTPService.Stub { /* package private */static IBinder createHttpServiceBinderIfNecessary( String path) { - if (path.startsWith("http://") - || path.startsWith("https://") - || path.startsWith("widevine://")) { + if (path.startsWith("http://") || path.startsWith("https://")) { return (new MediaHTTPService()).asBinder(); + } else if (path.startsWith("widevine://")) { + Log.d(TAG, "Widevine classic is no longer supported"); } return null; diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml index 295248c81888..34d236bcf619 100644 --- a/packages/SettingsLib/res/values-af/strings.xml +++ b/packages/SettingsLib/res/values-af/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Gepasmaak (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Hulp en terugvoer"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Kieslys"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml index bb500872ff5f..d0abbf983ff5 100644 --- a/packages/SettingsLib/res/values-am/strings.xml +++ b/packages/SettingsLib/res/values-am/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"ብጁ (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"እገዛ እና ግብረመልስ"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"ምናሌ"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml index 829123c54ab6..0eebcd7cbe68 100644 --- a/packages/SettingsLib/res/values-ar/strings.xml +++ b/packages/SettingsLib/res/values-ar/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"مخصص (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"المساعدة والتعليقات"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"القائمة"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-az-rAZ/strings.xml b/packages/SettingsLib/res/values-az-rAZ/strings.xml index 483770f34726..c0b776eeb9e8 100644 --- a/packages/SettingsLib/res/values-az-rAZ/strings.xml +++ b/packages/SettingsLib/res/values-az-rAZ/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Fərdi (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Yardım və rəy"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Menyu"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml index 5498580a8f15..cbb227138e67 100644 --- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml +++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Prilagođeni (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Pomoć i povratne informacije"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Meni"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-be-rBY/strings.xml b/packages/SettingsLib/res/values-be-rBY/strings.xml index f233db935712..12f103d5b216 100644 --- a/packages/SettingsLib/res/values-be-rBY/strings.xml +++ b/packages/SettingsLib/res/values-be-rBY/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Карыстальніцкі (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Даведка і водгукі"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Меню"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml index cd77792305e4..23adb5a2438d 100644 --- a/packages/SettingsLib/res/values-bg/strings.xml +++ b/packages/SettingsLib/res/values-bg/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Персонализирано (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Помощ и отзиви"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Меню"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-bn-rBD/strings.xml b/packages/SettingsLib/res/values-bn-rBD/strings.xml index a011fcfa3038..09988ed2a932 100644 --- a/packages/SettingsLib/res/values-bn-rBD/strings.xml +++ b/packages/SettingsLib/res/values-bn-rBD/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"কাস্টম (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"সহায়তা ও মতামত"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"মেনু"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-bs-rBA/strings.xml b/packages/SettingsLib/res/values-bs-rBA/strings.xml index 1df5ec97c2b0..561af9270365 100644 --- a/packages/SettingsLib/res/values-bs-rBA/strings.xml +++ b/packages/SettingsLib/res/values-bs-rBA/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Prilagodi (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Pomoć i povratne informacije"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Meni"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml index 92e90055e44b..19382ecf6c49 100644 --- a/packages/SettingsLib/res/values-ca/strings.xml +++ b/packages/SettingsLib/res/values-ca/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalitzat (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Ajuda i suggeriments"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Menú"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml index 8ec531ce3675..5276b3a50af7 100644 --- a/packages/SettingsLib/res/values-cs/strings.xml +++ b/packages/SettingsLib/res/values-cs/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Vlastní (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Nápověda a zpětná vazba"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Nabídka"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml index a65c58f5eea2..0c56b8d9ed09 100644 --- a/packages/SettingsLib/res/values-da/strings.xml +++ b/packages/SettingsLib/res/values-da/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Tilpasset (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Hjælp og feedback"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml index 923eca167299..60f373b5791b 100644 --- a/packages/SettingsLib/res/values-de/strings.xml +++ b/packages/SettingsLib/res/values-de/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Benutzerdefiniert (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Hilfe & Feedback"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Menü"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml index 3c0247d1bd27..032d73daae58 100644 --- a/packages/SettingsLib/res/values-el/strings.xml +++ b/packages/SettingsLib/res/values-el/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Προσαρμοσμένη (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Βοήθεια και σχόλια"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Μενού"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml index 8ed7444d10fb..57738e8ff495 100644 --- a/packages/SettingsLib/res/values-en-rAU/strings.xml +++ b/packages/SettingsLib/res/values-en-rAU/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Custom (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Help & feedback"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml index 8ed7444d10fb..57738e8ff495 100644 --- a/packages/SettingsLib/res/values-en-rGB/strings.xml +++ b/packages/SettingsLib/res/values-en-rGB/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Custom (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Help & feedback"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml index 8ed7444d10fb..57738e8ff495 100644 --- a/packages/SettingsLib/res/values-en-rIN/strings.xml +++ b/packages/SettingsLib/res/values-en-rIN/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Custom (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Help & feedback"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml index cdfbc019347e..e0b5bb78c3a6 100644 --- a/packages/SettingsLib/res/values-es-rUS/strings.xml +++ b/packages/SettingsLib/res/values-es-rUS/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizado (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Ayuda y comentarios"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Menú"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml index 2a21d2239900..259e7fbc0b23 100644 --- a/packages/SettingsLib/res/values-es/strings.xml +++ b/packages/SettingsLib/res/values-es/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizado (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Ayuda y sugerencias"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Menú"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-et-rEE/strings.xml b/packages/SettingsLib/res/values-et-rEE/strings.xml index 644bf59eeeef..7d70efe3d169 100644 --- a/packages/SettingsLib/res/values-et-rEE/strings.xml +++ b/packages/SettingsLib/res/values-et-rEE/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Kohandatud (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Abi ja tagasiside"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Menüü"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-eu-rES/strings.xml b/packages/SettingsLib/res/values-eu-rES/strings.xml index 2217611ab76e..952fda8d0168 100644 --- a/packages/SettingsLib/res/values-eu-rES/strings.xml +++ b/packages/SettingsLib/res/values-eu-rES/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Pertsonalizatua (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Laguntza eta iritziak"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Menua"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml index 88ed7fa0bbfa..e998b6970dc8 100644 --- a/packages/SettingsLib/res/values-fa/strings.xml +++ b/packages/SettingsLib/res/values-fa/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"سفارشی (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"راهنما و بازخورد"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"منو"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml index d26fc051f3dc..bf96b59b9179 100644 --- a/packages/SettingsLib/res/values-fi/strings.xml +++ b/packages/SettingsLib/res/values-fi/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Muokattu (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Ohje ja palaute"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Valikko"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml index 58aab1d61ebb..e2eb10d6d8f0 100644 --- a/packages/SettingsLib/res/values-fr-rCA/strings.xml +++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personnalisée (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Aide et commentaires"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml index 91bbaf0fb3e9..282ae4aa97e4 100644 --- a/packages/SettingsLib/res/values-fr/strings.xml +++ b/packages/SettingsLib/res/values-fr/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personnalisé (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Aide et commentaires"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-gl-rES/strings.xml b/packages/SettingsLib/res/values-gl-rES/strings.xml index b71738294c5f..f4bb7ad2b83a 100644 --- a/packages/SettingsLib/res/values-gl-rES/strings.xml +++ b/packages/SettingsLib/res/values-gl-rES/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizado (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Axuda e suxestións"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Menú"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-gu-rIN/strings.xml b/packages/SettingsLib/res/values-gu-rIN/strings.xml index 560518929309..1cded3d3cfe3 100644 --- a/packages/SettingsLib/res/values-gu-rIN/strings.xml +++ b/packages/SettingsLib/res/values-gu-rIN/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"કસ્ટમ (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"સહાય અને પ્રતિસાદ"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"મેનુ"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml index d579ec4508b9..a2a6e0459bb2 100644 --- a/packages/SettingsLib/res/values-hi/strings.xml +++ b/packages/SettingsLib/res/values-hi/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"कस्टम (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"सहायता और फ़ीडबैक"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"मेनू"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml index 94229b14c9f1..76f04bdf9dbf 100644 --- a/packages/SettingsLib/res/values-hr/strings.xml +++ b/packages/SettingsLib/res/values-hr/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Prilagođeno (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Pomoć i povratne informacije"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Izbornik"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml index 34f06e5e3cc2..f5f69168b61f 100644 --- a/packages/SettingsLib/res/values-hu/strings.xml +++ b/packages/SettingsLib/res/values-hu/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Egyéni (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Súgó és visszajelzés"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Menü"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-hy-rAM/strings.xml b/packages/SettingsLib/res/values-hy-rAM/strings.xml index 9428e17010ee..6dcb74567029 100644 --- a/packages/SettingsLib/res/values-hy-rAM/strings.xml +++ b/packages/SettingsLib/res/values-hy-rAM/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Հատուկ (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Օգնություն և հետադարձ կապ"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Ընտրացանկ"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml index a382e3782ae5..07241b5bf8e5 100644 --- a/packages/SettingsLib/res/values-in/strings.xml +++ b/packages/SettingsLib/res/values-in/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"(<xliff:g id="DENSITYDPI">%d</xliff:g>) khusus"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Bantuan & masukan"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-is-rIS/strings.xml b/packages/SettingsLib/res/values-is-rIS/strings.xml index 44517a89f48b..8e8307b8b9e1 100644 --- a/packages/SettingsLib/res/values-is-rIS/strings.xml +++ b/packages/SettingsLib/res/values-is-rIS/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Sérsniðið (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Hjálp og ábendingar"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Valmynd"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml index 7a32827b9511..d894ccf6c33e 100644 --- a/packages/SettingsLib/res/values-it/strings.xml +++ b/packages/SettingsLib/res/values-it/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizzato (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Guida e feedback"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml index 2e85770b898b..2ee38ef9095a 100644 --- a/packages/SettingsLib/res/values-iw/strings.xml +++ b/packages/SettingsLib/res/values-iw/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"מותאם אישית (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"עזרה ומשוב"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"תפריט"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml index 00e323c449d1..8b2d7845935a 100644 --- a/packages/SettingsLib/res/values-ja/strings.xml +++ b/packages/SettingsLib/res/values-ja/strings.xml @@ -343,4 +343,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"カスタム(<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"ヘルプとフィードバック"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"メニュー"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ka-rGE/strings.xml b/packages/SettingsLib/res/values-ka-rGE/strings.xml index 2b9e8cb93941..609cb339059c 100644 --- a/packages/SettingsLib/res/values-ka-rGE/strings.xml +++ b/packages/SettingsLib/res/values-ka-rGE/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"მორგებული (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"დახმარება და გამოხმაურება"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"მენიუ"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-kk-rKZ/strings.xml b/packages/SettingsLib/res/values-kk-rKZ/strings.xml index 0037c11c244b..92d7783e4672 100644 --- a/packages/SettingsLib/res/values-kk-rKZ/strings.xml +++ b/packages/SettingsLib/res/values-kk-rKZ/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Арнаулы (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Анықтама және пікір"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Mәзір"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-km-rKH/strings.xml b/packages/SettingsLib/res/values-km-rKH/strings.xml index 235ea6aa6d26..46cc6ce04982 100644 --- a/packages/SettingsLib/res/values-km-rKH/strings.xml +++ b/packages/SettingsLib/res/values-km-rKH/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"ផ្ទាល់ខ្លួន (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"ជំនួយ និងមតិស្ថាបនា"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"ម៉ឺនុយ"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-kn-rIN/strings.xml b/packages/SettingsLib/res/values-kn-rIN/strings.xml index d7c8d03c0b3b..cf8f3823d1ed 100644 --- a/packages/SettingsLib/res/values-kn-rIN/strings.xml +++ b/packages/SettingsLib/res/values-kn-rIN/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"ಕಸ್ಟಮ್ (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"ಸಹಾಯ ಮತ್ತು ಪ್ರತಿಕ್ರಿಯೆ"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"ಮೆನು"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml index 21bbc3f8778e..03c0edf7031d 100644 --- a/packages/SettingsLib/res/values-ko/strings.xml +++ b/packages/SettingsLib/res/values-ko/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"맞춤(<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"고객센터"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"메뉴"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ky-rKG/strings.xml b/packages/SettingsLib/res/values-ky-rKG/strings.xml index ca716caece02..a2eb86d470df 100644 --- a/packages/SettingsLib/res/values-ky-rKG/strings.xml +++ b/packages/SettingsLib/res/values-ky-rKG/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Ыңгайлаштырылган (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Жардам жана жооп пикир"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Меню"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-lo-rLA/strings.xml b/packages/SettingsLib/res/values-lo-rLA/strings.xml index 0108c2c89cf9..41a8eef6b15c 100644 --- a/packages/SettingsLib/res/values-lo-rLA/strings.xml +++ b/packages/SettingsLib/res/values-lo-rLA/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"ປັບແຕ່ງເອງ (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"ຊ່ວຍເຫຼືອ & ຄຳຕິຊົມ"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"ເມນູ"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml index 154864f2bf0f..6930c7abbacf 100644 --- a/packages/SettingsLib/res/values-lt/strings.xml +++ b/packages/SettingsLib/res/values-lt/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Tinkintas (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Pagalba ir atsiliepimai"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Meniu"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml index df91cb15d622..77348812cc5c 100644 --- a/packages/SettingsLib/res/values-lv/strings.xml +++ b/packages/SettingsLib/res/values-lv/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Pielāgots (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Palīdzība un atsauksmes"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Izvēlne"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-mk-rMK/strings.xml b/packages/SettingsLib/res/values-mk-rMK/strings.xml index 42bc33fd71ae..711b949bedad 100644 --- a/packages/SettingsLib/res/values-mk-rMK/strings.xml +++ b/packages/SettingsLib/res/values-mk-rMK/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Приспособен (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Помош и повратни информации"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Мени"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ml-rIN/strings.xml b/packages/SettingsLib/res/values-ml-rIN/strings.xml index a6017d51d349..8bcbf79dc06f 100644 --- a/packages/SettingsLib/res/values-ml-rIN/strings.xml +++ b/packages/SettingsLib/res/values-ml-rIN/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"ഇഷ്ടാനുസൃതം ( <xliff:g id="DENSITYDPI">%d</xliff:g> )"</string> <string name="help_feedback_label" msgid="6815040660801785649">"സഹായവും പ്രതികരണവും"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"മെനു"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-mn-rMN/strings.xml b/packages/SettingsLib/res/values-mn-rMN/strings.xml index cb6327a52ec4..4fa377927675 100644 --- a/packages/SettingsLib/res/values-mn-rMN/strings.xml +++ b/packages/SettingsLib/res/values-mn-rMN/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Тогтмол утга (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Тусламж, санал хүсэлт"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Цэс"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-mr-rIN/strings.xml b/packages/SettingsLib/res/values-mr-rIN/strings.xml index b6adb4fc169b..20f64fe40a28 100644 --- a/packages/SettingsLib/res/values-mr-rIN/strings.xml +++ b/packages/SettingsLib/res/values-mr-rIN/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"सानुकूल करा (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"मदत आणि अभिप्राय"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"मेनू"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ms-rMY/strings.xml b/packages/SettingsLib/res/values-ms-rMY/strings.xml index 9886d3e5773b..cf7725495029 100644 --- a/packages/SettingsLib/res/values-ms-rMY/strings.xml +++ b/packages/SettingsLib/res/values-ms-rMY/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Tersuai (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Bantuan & maklum balas"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-my-rMM/strings.xml b/packages/SettingsLib/res/values-my-rMM/strings.xml index 935ad4027a9f..9db8348177ca 100644 --- a/packages/SettingsLib/res/values-my-rMM/strings.xml +++ b/packages/SettingsLib/res/values-my-rMM/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"စိတ်ကြိုက် (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"အကူအညီနှင့် အကြံပြုချက်"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"မီနူး"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml index 18b6f60bc92f..cc4e5678014b 100644 --- a/packages/SettingsLib/res/values-nb/strings.xml +++ b/packages/SettingsLib/res/values-nb/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Egendefinert (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Hjelp og tilbakemelding"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Meny"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ne-rNP/strings.xml b/packages/SettingsLib/res/values-ne-rNP/strings.xml index 478e19d831f1..a8a918b549f1 100644 --- a/packages/SettingsLib/res/values-ne-rNP/strings.xml +++ b/packages/SettingsLib/res/values-ne-rNP/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"अनुकूलन (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"मद्दत र प्रतिक्रिया"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"मेनु"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml index 3b8431387ac8..8bb4579f0b19 100644 --- a/packages/SettingsLib/res/values-nl/strings.xml +++ b/packages/SettingsLib/res/values-nl/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Aangepast (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Help en feedback"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-pa-rIN/strings.xml b/packages/SettingsLib/res/values-pa-rIN/strings.xml index b678aac86a9c..f19ba3ea04cd 100644 --- a/packages/SettingsLib/res/values-pa-rIN/strings.xml +++ b/packages/SettingsLib/res/values-pa-rIN/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"ਵਿਸ਼ੇਸ਼-ਵਿਉਂਤਬੱਧ (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"ਮਦਦ ਅਤੇ ਪ੍ਰਤੀਕਰਮ"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"ਮੀਨੂ"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml index 77a23f220f95..4db3e6e4fa7b 100644 --- a/packages/SettingsLib/res/values-pl/strings.xml +++ b/packages/SettingsLib/res/values-pl/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Niestandardowe (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Pomoc i opinie"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml index 588ca67f2151..7855beb3d1fe 100644 --- a/packages/SettingsLib/res/values-pt-rBR/strings.xml +++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizada (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Ajuda e feedback"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml index 763cb70ff483..2c366c6197a9 100644 --- a/packages/SettingsLib/res/values-pt-rPT/strings.xml +++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizado (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Ajuda e comentários"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml index 588ca67f2151..7855beb3d1fe 100644 --- a/packages/SettingsLib/res/values-pt/strings.xml +++ b/packages/SettingsLib/res/values-pt/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizada (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Ajuda e feedback"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml index 6a2122a2de31..5d0b965ad3cc 100644 --- a/packages/SettingsLib/res/values-ro/strings.xml +++ b/packages/SettingsLib/res/values-ro/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizat (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Ajutor și feedback"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Meniu"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml index 1f192c173abb..d301ce1f6e42 100644 --- a/packages/SettingsLib/res/values-ru/strings.xml +++ b/packages/SettingsLib/res/values-ru/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Другой (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Справка/отзыв"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Меню"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-si-rLK/strings.xml b/packages/SettingsLib/res/values-si-rLK/strings.xml index e415544e5f10..f21793bee3c0 100644 --- a/packages/SettingsLib/res/values-si-rLK/strings.xml +++ b/packages/SettingsLib/res/values-si-rLK/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"අභිරුචි (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"උදව් සහ ප්රතිපෝෂණ"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"මෙනුව"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml index 7e636fe7bd62..b478ecf88c2e 100644 --- a/packages/SettingsLib/res/values-sk/strings.xml +++ b/packages/SettingsLib/res/values-sk/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Vlastné (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Pomocník a spätná väzba"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Ponuka"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml index 78fa3fd07c78..b9da0eb0b7bf 100644 --- a/packages/SettingsLib/res/values-sl/strings.xml +++ b/packages/SettingsLib/res/values-sl/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Po meri (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Pomoč in povratne informacije"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Meni"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-sq-rAL/strings.xml b/packages/SettingsLib/res/values-sq-rAL/strings.xml index ad4cf61b7349..c17376b232f5 100644 --- a/packages/SettingsLib/res/values-sq-rAL/strings.xml +++ b/packages/SettingsLib/res/values-sq-rAL/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"I personalizuar (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Ndihma dhe komentet"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Menyja"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml index 02eb61534b8d..2cf68a537064 100644 --- a/packages/SettingsLib/res/values-sr/strings.xml +++ b/packages/SettingsLib/res/values-sr/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Прилагођени (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Помоћ и повратне информације"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Мени"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml index a936c3eb610a..975a4aa13571 100644 --- a/packages/SettingsLib/res/values-sv/strings.xml +++ b/packages/SettingsLib/res/values-sv/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Anpassad (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Hjälp och feedback"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Meny"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml index 25f79b62d5cb..f14cbdd3de68 100644 --- a/packages/SettingsLib/res/values-sw/strings.xml +++ b/packages/SettingsLib/res/values-sw/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Kiwango maalum (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Usaidizi na maoni"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Menyu"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ta-rIN/strings.xml b/packages/SettingsLib/res/values-ta-rIN/strings.xml index 9e9e92cd3206..26401227bdbf 100644 --- a/packages/SettingsLib/res/values-ta-rIN/strings.xml +++ b/packages/SettingsLib/res/values-ta-rIN/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"தனிப்பயன் (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"உதவி & கருத்து"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"மெனு"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-te-rIN/strings.xml b/packages/SettingsLib/res/values-te-rIN/strings.xml index 27f8e09bd54f..60a4d7220fc8 100644 --- a/packages/SettingsLib/res/values-te-rIN/strings.xml +++ b/packages/SettingsLib/res/values-te-rIN/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"అనుకూలం (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"సహాయం & అభిప్రాయం"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"మెను"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml index 600597281b3c..fbb67bc4e960 100644 --- a/packages/SettingsLib/res/values-th/strings.xml +++ b/packages/SettingsLib/res/values-th/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"กำหนดเอง (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"ความช่วยเหลือและความคิดเห็น"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"เมนู"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml index e9feded8c087..50c43bb01db3 100644 --- a/packages/SettingsLib/res/values-tl/strings.xml +++ b/packages/SettingsLib/res/values-tl/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Custom (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Tulong at feedback"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml index 0e73b7be6c9c..c5ae71c634a5 100644 --- a/packages/SettingsLib/res/values-tr/strings.xml +++ b/packages/SettingsLib/res/values-tr/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Özel (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Yardım ve geri bildirim"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Menü"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml index 1015e1cf543c..b538545f9b3b 100644 --- a/packages/SettingsLib/res/values-uk/strings.xml +++ b/packages/SettingsLib/res/values-uk/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Спеціальний масштаб (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Довідка й відгуки"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Меню"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-ur-rPK/strings.xml b/packages/SettingsLib/res/values-ur-rPK/strings.xml index 61dc5abcb387..0b5e8a008b2f 100644 --- a/packages/SettingsLib/res/values-ur-rPK/strings.xml +++ b/packages/SettingsLib/res/values-ur-rPK/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"حسب ضرورت (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"مدد اور تاثرات"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"مینو"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-uz-rUZ/strings.xml b/packages/SettingsLib/res/values-uz-rUZ/strings.xml index a6f9ab817d18..8d1056a1bca8 100644 --- a/packages/SettingsLib/res/values-uz-rUZ/strings.xml +++ b/packages/SettingsLib/res/values-uz-rUZ/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Moslashtirilgan (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Yordam va fikr-mulohaza"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Menyu"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml index f09e0e5ea77a..21e5b7575367 100644 --- a/packages/SettingsLib/res/values-vi/strings.xml +++ b/packages/SettingsLib/res/values-vi/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Tùy chỉnh (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Trợ giúp và phản hồi"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml index 7268dcd347b8..ba657c6792f3 100644 --- a/packages/SettingsLib/res/values-zh-rCN/strings.xml +++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"自定义 (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"帮助和反馈"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"菜单"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml index ea03fb607964..60f56f13b91d 100644 --- a/packages/SettingsLib/res/values-zh-rHK/strings.xml +++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"自訂 (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"說明和意見反映"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"選單"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml index f17b5234afe5..6bb730874b87 100644 --- a/packages/SettingsLib/res/values-zh-rTW/strings.xml +++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"自訂 (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"說明與意見回饋"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"選單"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml index 1fc551fc6195..6714b27bec86 100644 --- a/packages/SettingsLib/res/values-zu/strings.xml +++ b/packages/SettingsLib/res/values-zu/strings.xml @@ -341,4 +341,6 @@ <string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Ngokwezifiso (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string> <string name="help_feedback_label" msgid="6815040660801785649">"Usizo nempendulo"</string> <string name="content_description_menu_button" msgid="8182594799812351266">"Imenyu"</string> + <!-- no translation found for time_zone_gmt (2587097992671450782) --> + <skip /> </resources> diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/doze/DozeProvider.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/doze/DozeProvider.java new file mode 100644 index 000000000000..688df466d244 --- /dev/null +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/doze/DozeProvider.java @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.plugins.doze; + +import android.app.PendingIntent; +import android.content.Context; + +import com.android.systemui.plugins.Plugin; + +/** + * Provides a {@link DozeUi}. + */ +public interface DozeProvider extends Plugin { + + String ACTION = "com.android.systemui.action.PLUGIN_DOZE"; + int VERSION = 1; + + /** + * Caution: Even if this is called, the DozeUi provided may still be in use until it transitions + * to DozeState.FINISH + */ + @Override + default void onDestroy() { + } + + /** + * @return the plugin's implementation of DozeUi. + */ + DozeUi provideDozeUi(Context context, DozeMachine machine, WakeLock wakeLock); + + /** + * If true, the plugin allows the default pulse triggers to fire, otherwise they are disabled. + */ + default boolean allowDefaultPulseTriggers() { + return false; + } + + /** + * Ui for use in DozeMachine. + */ + interface DozeUi { + /** Called whenever the DozeMachine state transitions */ + void transitionTo(DozeState oldState, DozeState newState); + } + + /** WakeLock wrapper for testability */ + interface WakeLock { + /** @see android.os.PowerManager.WakeLock#acquire() */ + void acquire(); + /** @see android.os.PowerManager.WakeLock#release() */ + void release(); + /** @see android.os.PowerManager.WakeLock#wrap(Runnable) */ + Runnable wrap(Runnable r); + } + + /** Plugin version of the DozeMachine's state */ + enum DozeState { + /** Default state. Transition to INITIALIZED to get Doze going. */ + UNINITIALIZED, + /** Doze components are set up. Followed by transition to DOZE or DOZE_AOD. */ + INITIALIZED, + /** Regular doze. Device is asleep and listening for pulse triggers. */ + DOZE, + /** Always-on doze. Device is asleep, showing UI and listening for pulse triggers. */ + DOZE_AOD, + /** Pulse has been requested. Device is awake and preparing UI */ + DOZE_REQUEST_PULSE, + /** Pulse is showing. Device is awake and showing UI. */ + DOZE_PULSING, + /** Pulse is done showing. Followed by transition to DOZE or DOZE_AOD. */ + DOZE_PULSE_DONE, + /** Doze is done. DozeService is finished. */ + FINISH, + /** WakeUp. */ + WAKE_UP, + } + + /** Plugin interface for the doze machine. */ + interface DozeMachine { + /** Request that the DozeMachine transitions to {@code state} */ + void requestState(DozeState state); + + /** Request that the PendingIntent is sent. */ + void requestSendIntent(PendingIntent intent); + } +} diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index 502a94eda666..a1a8f8d2d0f2 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -198,13 +198,13 @@ <string name="accessibility_quick_settings_airplane_on" msgid="6406141469157599296">"تشغيل وضع الطائرة."</string> <string name="accessibility_quick_settings_airplane_changed_off" msgid="66846307818850664">"تم إيقاف وضع الطائرة."</string> <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"تم تشغيل وضع الطائرة."</string> - <string name="accessibility_quick_settings_dnd_priority_on" msgid="1448402297221249355">"تم تشغيل الرجاء عدم الإزعاج، الأولوية فقط."</string> - <string name="accessibility_quick_settings_dnd_none_on" msgid="6882582132662613537">"تم تشغيل الرجاء عدم الإزعاج، كتم الصوت تمامًا."</string> - <string name="accessibility_quick_settings_dnd_alarms_on" msgid="9152834845587554157">"تم تشغيل الرجاء عدم الإزعاج، التنبيهات فقط."</string> + <string name="accessibility_quick_settings_dnd_priority_on" msgid="1448402297221249355">"تم تشغيل \"عدم الإزعاج، الأولوية فقط\"."</string> + <string name="accessibility_quick_settings_dnd_none_on" msgid="6882582132662613537">"تم تشغيل \"عدم الإزعاج، كتم الصوت تمامًا\"."</string> + <string name="accessibility_quick_settings_dnd_alarms_on" msgid="9152834845587554157">"تم تشغيل \"عدم الإزعاج، التنبيهات فقط\"."</string> <string name="accessibility_quick_settings_dnd" msgid="6607873236717185815">"الرجاء عدم الإزعاج."</string> <string name="accessibility_quick_settings_dnd_off" msgid="2371832603753738581">"تم تعطيل \"الرجاء عدم الإزعاج\"."</string> <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"تم تعطيل \"الرجاء عدم الإزعاج\"."</string> - <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"تم تشغيل \"الرجاء عدم الإزعاج\"."</string> + <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"تم تشغيل \"عدم الإزعاج\"."</string> <string name="accessibility_quick_settings_bluetooth" msgid="6341675755803320038">"البلوتوث."</string> <string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"إيقاف البلوتوث."</string> <string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"تشغيل البلوتوث."</string> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index f482caaa393a..97f3926c940c 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -342,7 +342,7 @@ <string name="description_target_search" msgid="3091587249776033139">"खोजें"</string> <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए ऊपर स्लाइड करें."</string> <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए बाएं स्लाइड करें."</string> - <string name="zen_priority_introduction" msgid="3070506961866919502">"आपको आपके द्वारा निर्दिष्ट किए गए अलार्म, रिमाइंडर्स, ईवेंट और कॉलर को छोड़कर अन्य ध्वनियों और कंपनों के द्वारा परेशान नहीं किया जाएगा."</string> + <string name="zen_priority_introduction" msgid="3070506961866919502">"आपको आपके द्वारा निर्दिष्ट किए गए अलार्म, रिमाइंडर्स, इवेंट और कॉलर को छोड़कर अन्य ध्वनियों और कंपनों के द्वारा परेशान नहीं किया जाएगा."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"कस्टमाइज़ करें"</string> <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"इससे अलार्म, संगीत, वीडियो और गेम सहित सभी ध्वनियां और कंपन अवरुद्ध हो जाते हैं. आप अभी भी फ़ोन काॅल कर सकेंगे."</string> <string name="zen_silence_introduction" msgid="3137882381093271568">"इससे अलार्म, संगीत, वीडियो और गेम सहित सभी ध्वनियां और कंपन अवरुद्ध हो जाते हैं."</string> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index 8217ee5afe46..29f8875667b6 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -164,8 +164,8 @@ <string name="accessibility_settings_button" msgid="799583911231893380">"Systeeminstellingen."</string> <string name="accessibility_notifications_button" msgid="4498000369779421892">"Meldingen."</string> <string name="accessibility_remove_notification" msgid="3603099514902182350">"Melding wissen"</string> - <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS ingeschakeld."</string> - <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Verbinding maken met GPS."</string> + <string name="accessibility_gps_enabled" msgid="3511469499240123019">"gps ingeschakeld."</string> + <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Verbinding maken met gps."</string> <string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter ingeschakeld."</string> <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Belsoftware trilt."</string> <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Belsoftware stil."</string> @@ -241,8 +241,8 @@ <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"Hervatten"</string> <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Geen internetverbinding"</string> <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Verbonden via wifi"</string> - <string name="gps_notification_searching_text" msgid="8574247005642736060">"Zoeken naar GPS"</string> - <string name="gps_notification_found_text" msgid="4619274244146446464">"Locatie bepaald met GPS"</string> + <string name="gps_notification_searching_text" msgid="8574247005642736060">"Zoeken naar gps"</string> + <string name="gps_notification_found_text" msgid="4619274244146446464">"Locatie bepaald met gps"</string> <string name="accessibility_location_active" msgid="2427290146138169014">"Locatieverzoeken actief"</string> <string name="accessibility_clear_all" msgid="5235938559247164925">"Alle meldingen wissen."</string> <string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string> @@ -376,7 +376,7 @@ <string name="guest_exit_guest_dialog_message" msgid="4155503224769676625">"Alle apps en gegevens in deze sessie worden verwijderd."</string> <string name="guest_exit_guest_dialog_remove" msgid="7402231963862520531">"Verwijderen"</string> <string name="guest_wipe_session_title" msgid="6419439912885956132">"Welkom terug, gast!"</string> - <string name="guest_wipe_session_message" msgid="8476238178270112811">"Wilt u doorgaan met je sessie?"</string> + <string name="guest_wipe_session_message" msgid="8476238178270112811">"Wil je doorgaan met je sessie?"</string> <string name="guest_wipe_session_wipe" msgid="5065558566939858884">"Opnieuw starten"</string> <string name="guest_wipe_session_dontwipe" msgid="1401113462524894716">"Ja, doorgaan"</string> <string name="guest_notification_title" msgid="1585278533840603063">"Gastgebruiker"</string> diff --git a/packages/SystemUI/res/values-pl/strings_car.xml b/packages/SystemUI/res/values-pl/strings_car.xml index d6e02d6c0454..dbb0373e161f 100644 --- a/packages/SystemUI/res/values-pl/strings_car.xml +++ b/packages/SystemUI/res/values-pl/strings_car.xml @@ -20,5 +20,5 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="car_lockscreen_disclaimer_title" msgid="7997539137376896441">"Jedź bezpiecznie"</string> - <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Uważnie obserwuj warunki na drodze i zawsze przestrzegaj obowiązującego prawa. Wskazówki mogą być niedokładne, niekompletne, niebezpieczne, nieprzydatne lub niezgodne z prawem, mogą też obejmować przekraczanie obszarów administracyjnych. Informacje o firmach również mogą być niedokładne lub niekompletne. Dane nie są podawane w czasie rzeczywistym. Nie ma gwarancji, że dane o lokalizacji są dokładne. Podczas prowadzenia samochodu nie obsługuj urządzenia mobilnego ani nie używaj aplikacji nieprzeznaczonych na Android Auto."</string> + <string name="car_lockscreen_disclaimer_text" msgid="3061224684092952864">"Uważnie obserwuj warunki na drodze i zawsze przestrzegaj obowiązującego prawa. Wskazówki mogą być niedokładne, niekompletne, niebezpieczne, nieprzydatne lub niezgodne z prawem, mogą też obejmować przekraczanie obszarów administracyjnych. Informacje o firmach również mogą być niedokładne lub niekompletne. Dane nie są podawane w czasie rzeczywistym. Nie ma gwarancji, że dane o lokalizacji są dokładne. Podczas prowadzenia samochodu nie obsługuj urządzenia mobilnego ani nie używaj aplikacji nieprzeznaczonych na Androida Auto."</string> </resources> diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java index 6802fd7acbd4..b20798481a58 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java @@ -29,6 +29,7 @@ import android.os.SystemProperties; import android.os.UserHandle; import android.util.Log; +import com.android.systemui.doze.DozeFactory; import com.android.systemui.fragments.FragmentService; import com.android.systemui.keyboard.KeyboardUI; import com.android.systemui.keyguard.KeyguardViewMediator; @@ -76,7 +77,8 @@ public class SystemUIApplication extends Application { PipUI.class, ShortcutKeyDispatcher.class, VendorServices.class, - LatencyTester.class + LatencyTester.class, + DozeFactory.Initializer.class, }; /** diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java index 4cfc811de1a0..5b10756988a4 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java @@ -17,19 +17,52 @@ package com.android.systemui.doze; import android.app.Application; +import android.app.PendingIntent; import android.content.Context; import android.hardware.SensorManager; import android.os.Handler; import android.os.PowerManager; +import android.os.SystemClock; import com.android.internal.hardware.AmbientDisplayConfiguration; +import com.android.systemui.SystemUI; import com.android.systemui.SystemUIApplication; +import com.android.systemui.plugins.PluginListener; +import com.android.systemui.plugins.PluginManager; +import com.android.systemui.plugins.doze.DozeProvider; import com.android.systemui.statusbar.phone.DozeParameters; public class DozeFactory { + private static DozeFactory sInstance; + + private DozeProvider mDozePlugin; + + /** Returns the singleton instance. */ + public static DozeFactory getInstance(Context context) { + if (sInstance == null) { + sInstance = new DozeFactory(); + PluginManager.getInstance(context).addPluginListener(DozeProvider.ACTION, + new PluginListener<DozeProvider>() { + @Override + public void onPluginConnected(DozeProvider plugin) { + sInstance.mDozePlugin = plugin; + } + + @Override + public void onPluginDisconnected(DozeProvider plugin) { + if (sInstance.mDozePlugin == plugin) { + sInstance.mDozePlugin = null; + } + } + }, + DozeProvider.VERSION, false /* Only one */); + } + return sInstance; + } + /** Creates a DozeMachine with its parts for {@code dozeService}. */ - public static DozeMachine assembleMachine(DozeService dozeService) { + public DozeMachine assembleMachine(DozeService dozeService) { Context context = dozeService; SensorManager sensorManager = context.getSystemService(SensorManager.class); PowerManager powerManager = context.getSystemService(PowerManager.class); @@ -43,14 +76,103 @@ public class DozeFactory { DozeMachine machine = new DozeMachine(dozeService, params, wakeLock); machine.setParts(new DozeMachine.Part[]{ - new DozeTriggers(context, machine, host, config, params, - sensorManager, handler, wakeLock), - new DozeUi(context, machine, wakeLock, host), + createDozeTriggers(context, sensorManager, host, config, params, handler, wakeLock, + machine), + createDozeUi(context, host, wakeLock, machine), }); return machine; } + private DozeTriggers createDozeTriggers(Context context, SensorManager sensorManager, + DozeHost host, AmbientDisplayConfiguration config, DozeParameters params, + Handler handler, WakeLock wakeLock, DozeMachine machine) { + boolean allowPulseTriggers = mDozePlugin == null || mDozePlugin.allowDefaultPulseTriggers(); + return new DozeTriggers(context, machine, host, config, params, + sensorManager, handler, wakeLock, allowPulseTriggers); + } + + private DozeMachine.Part createDozeUi(Context context, DozeHost host, WakeLock wakeLock, + DozeMachine machine) { + if (mDozePlugin != null) { + DozeProvider.DozeUi dozeUi = mDozePlugin.provideDozeUi(context, + pluginMachine(context, machine, host), + wakeLock); + return (oldState, newState) -> { + dozeUi.transitionTo(pluginState(oldState), + pluginState(newState)); + }; + } else { + return new DozeUi(context, machine, wakeLock, host); + } + } + + private DozeProvider.DozeMachine pluginMachine(Context context, DozeMachine machine, + DozeHost host) { + return new DozeProvider.DozeMachine() { + @Override + public void requestState(DozeProvider.DozeState state) { + if (state == DozeProvider.DozeState.WAKE_UP) { + PowerManager pm = context.getSystemService(PowerManager.class); + pm.wakeUp(SystemClock.uptimeMillis(), "com.android.systemui:NODOZE"); + return; + } + machine.requestState(implState(state)); + } + + @Override + public void requestSendIntent(PendingIntent intent) { + host.startPendingIntentDismissingKeyguard(intent); + } + }; + } + + private DozeMachine.State implState(DozeProvider.DozeState s) { + switch (s) { + case UNINITIALIZED: + return DozeMachine.State.UNINITIALIZED; + case INITIALIZED: + return DozeMachine.State.INITIALIZED; + case DOZE: + return DozeMachine.State.DOZE; + case DOZE_AOD: + return DozeMachine.State.DOZE_AOD; + case DOZE_REQUEST_PULSE: + return DozeMachine.State.DOZE_REQUEST_PULSE; + case DOZE_PULSING: + return DozeMachine.State.DOZE_PULSING; + case DOZE_PULSE_DONE: + return DozeMachine.State.DOZE_PULSE_DONE; + case FINISH: + return DozeMachine.State.FINISH; + default: + throw new IllegalArgumentException("Unknown state: " + s); + } + } + + private DozeProvider.DozeState pluginState(DozeMachine.State s) { + switch (s) { + case UNINITIALIZED: + return DozeProvider.DozeState.UNINITIALIZED; + case INITIALIZED: + return DozeProvider.DozeState.INITIALIZED; + case DOZE: + return DozeProvider.DozeState.DOZE; + case DOZE_AOD: + return DozeProvider.DozeState.DOZE_AOD; + case DOZE_REQUEST_PULSE: + return DozeProvider.DozeState.DOZE_REQUEST_PULSE; + case DOZE_PULSING: + return DozeProvider.DozeState.DOZE_PULSING; + case DOZE_PULSE_DONE: + return DozeProvider.DozeState.DOZE_PULSE_DONE; + case FINISH: + return DozeProvider.DozeState.FINISH; + default: + throw new IllegalArgumentException("Unknown state: " + s); + } + } + private static DozeHost getHost(DozeService service) { Application appCandidate = service.getApplication(); final SystemUIApplication app = (SystemUIApplication) appCandidate; @@ -58,7 +180,7 @@ public class DozeFactory { } /** A wrapper around {@link PowerManager.WakeLock} for testability. */ - public static class WakeLock { + public static class WakeLock implements DozeProvider.WakeLock { private final PowerManager.WakeLock mInner; public WakeLock(PowerManager.WakeLock inner) { @@ -80,4 +202,13 @@ public class DozeFactory { return mInner.wrap(runnable); } } + + /** Hack: We need to initialize the plugin listener before doze actually starts. + * This will be unnecessary once we have proper one-shot support */ + public static class Initializer extends SystemUI { + @Override + public void start() { + getInstance(mContext); + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java index fb940b511b24..e081b53ffda3 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java @@ -17,6 +17,7 @@ package com.android.systemui.doze; import android.annotation.NonNull; +import android.app.PendingIntent; /** * Interface the doze service uses to communicate with the rest of system UI. @@ -32,14 +33,16 @@ public interface DozeHost { boolean isNotificationLightOn(); boolean isPulsingBlocked(); - public interface Callback { - void onNewNotifications(); - void onBuzzBeepBlinked(); - void onNotificationLight(boolean on); - void onPowerSaveChanged(boolean active); + void startPendingIntentDismissingKeyguard(PendingIntent intent); + + interface Callback { + default void onNewNotifications() {} + default void onBuzzBeepBlinked() {} + default void onNotificationLight(boolean on) {} + default void onPowerSaveChanged(boolean active) {} } - public interface PulseCallback { + interface PulseCallback { void onPulseStarted(); void onPulseFinished(); } diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java index 94cbdd41e220..78b96b34efad 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java @@ -38,7 +38,7 @@ public class DozeService extends DreamService implements DozeMachine.Service { setWindowless(true); - mDozeMachine = DozeFactory.assembleMachine(this); + mDozeMachine = DozeFactory.getInstance(getApplication()).assembleMachine(this); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java index 9f26b0c57dbe..84b22ea93b81 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java @@ -58,6 +58,7 @@ public class DozeTriggers implements DozeMachine.Part { private final SensorManager mSensorManager; private final Handler mHandler; private final DozeFactory.WakeLock mWakeLock; + private final boolean mAllowPulseTriggers; private final UiModeManager mUiModeManager; private final TriggerReceiver mBroadcastReceiver = new TriggerReceiver(); @@ -68,7 +69,7 @@ public class DozeTriggers implements DozeMachine.Part { public DozeTriggers(Context context, DozeMachine machine, DozeHost dozeHost, AmbientDisplayConfiguration config, DozeParameters dozeParameters, SensorManager sensorManager, Handler handler, - DozeFactory.WakeLock wakeLock) { + DozeFactory.WakeLock wakeLock, boolean allowPulseTriggers) { mContext = context; mMachine = machine; mDozeHost = dozeHost; @@ -77,6 +78,7 @@ public class DozeTriggers implements DozeMachine.Part { mSensorManager = sensorManager; mHandler = handler; mWakeLock = wakeLock; + mAllowPulseTriggers = allowPulseTriggers; mDozeSensors = new DozeSensors(context, mSensorManager, dozeParameters, config, wakeLock, this::onSensor); mUiModeManager = mContext.getSystemService(UiModeManager.class); @@ -149,7 +151,7 @@ public class DozeTriggers implements DozeMachine.Part { private void requestPulse(final int reason, boolean performedProxCheck) { Assert.isMainThread(); - if (mPulsePending || !canPulse()) { + if (mPulsePending || !mAllowPulseTriggers || !canPulse()) { return; } @@ -307,20 +309,11 @@ public class DozeTriggers implements DozeMachine.Part { private DozeHost.Callback mHostCallback = new DozeHost.Callback() { @Override - public void onNewNotifications() { - } - - @Override public void onBuzzBeepBlinked() { onNotification(); } @Override - public void onNotificationLight(boolean on) { - - } - - @Override public void onPowerSaveChanged(boolean active) { if (active) { onPowerSave(); diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java index 5bfc17fcaaf9..9b48e4d02623 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java @@ -104,8 +104,8 @@ public class RecentsTaskLoadPlan { int currentUserId = UserHandle.USER_CURRENT; updateCurrentQuietProfilesCache(currentUserId); SystemServicesProxy ssp = Recents.getSystemServices(); - mRawTasks = new ArrayList<>(ssp.getRecentTasks(ActivityManager.getMaxRecentTasksStatic(), - currentUserId, includeFrontMostExcludedTask, mCurrentQuietProfiles)); + mRawTasks = ssp.getRecentTasks(ActivityManager.getMaxRecentTasksStatic(), + currentUserId, includeFrontMostExcludedTask, mCurrentQuietProfiles); // Since the raw tasks are given in most-recent to least-recent order, we need to reverse it Collections.reverse(mRawTasks); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index c4fb21eda982..6f13ba50b22f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -5167,5 +5167,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, return mNotificationLightOn; } + @Override + public void startPendingIntentDismissingKeyguard(PendingIntent intent) { + PhoneStatusBar.this.startPendingIntentDismissingKeyguard(intent); + } + } } diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index de700266e4c2..5eceb9f1395b 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -5342,6 +5342,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // notify only this one new request of the current state protected void notifyNetworkCallback(NetworkAgentInfo nai, NetworkRequestInfo nri) { int notifyType = ConnectivityManager.CALLBACK_AVAILABLE; + mHandler.removeMessages(EVENT_TIMEOUT_NETWORK_REQUEST, nri); if (nri.mPendingIntent == null) { callCallbackForRequest(nri, nai, notifyType, 0); } else { diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java index f4ddc06d381c..67014314595f 100644 --- a/services/core/java/com/android/server/LockSettingsService.java +++ b/services/core/java/com/android/server/LockSettingsService.java @@ -249,16 +249,13 @@ public class LockSettingsService extends ILockSettings.Stub { try { randomLockSeed = SecureRandom.getInstance("SHA1PRNG").generateSeed(40); String newPassword = String.valueOf(HexEncoding.encode(randomLockSeed)); - tieProfileLockToParent(managedUserId, newPassword); setLockPasswordInternal(newPassword, managedUserPassword, managedUserId); // We store a private credential for the managed user that's unlocked by the primary // account holder's credential. As such, the user will never be prompted to enter this // password directly, so we always store a password. setLong(LockPatternUtils.PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC, managedUserId); - } catch (KeyStoreException e) { - // Bug: 32490092 - Slog.e(TAG, "Not able to set keys to keystore", e); + tieProfileLockToParent(managedUserId, newPassword); } catch (NoSuchAlgorithmException | RemoteException e) { Slog.e(TAG, "Fail to tie managed profile", e); // Nothing client can do to fix this issue, so we do not throw exception out @@ -779,7 +776,6 @@ public class LockSettingsService extends ILockSettings.Stub { } private void unlockChildProfile(int profileHandle) throws RemoteException { - if (DEBUG) Slog.v(TAG, "Unlock child profile"); try { doVerifyPassword(getDecryptedPasswordForTiedProfile(profileHandle), false, 0 /* no challenge */, profileHandle, null /* progressCallback */); @@ -1039,7 +1035,7 @@ public class LockSettingsService extends ILockSettings.Stub { } } - private void tieProfileLockToParent(int userId, String password) throws KeyStoreException { + private void tieProfileLockToParent(int userId, String password) { if (DEBUG) Slog.v(TAG, "tieProfileLockToParent for user: " + userId); byte[] randomLockSeed = password.getBytes(StandardCharsets.UTF_8); byte[] encryptionResult; @@ -1081,7 +1077,7 @@ public class LockSettingsService extends ILockSettings.Stub { keyStore.deleteEntry(LockPatternUtils.PROFILE_KEY_NAME_ENCRYPT + userId); } } catch (CertificateException | UnrecoverableKeyException - | IOException | BadPaddingException | IllegalBlockSizeException + | IOException | BadPaddingException | IllegalBlockSizeException | KeyStoreException | NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException e) { throw new RuntimeException("Failed to encrypt key", e); } @@ -1223,11 +1219,7 @@ public class LockSettingsService extends ILockSettings.Stub { } finally { if (managedUserId != -1 && managedUserDecryptedPassword != null) { if (DEBUG) Slog.v(TAG, "Restore tied profile lock"); - try { - tieProfileLockToParent(managedUserId, managedUserDecryptedPassword); - } catch (KeyStoreException e) { - throw new RuntimeException("Failed to tie profile lock", e); - } + tieProfileLockToParent(managedUserId, managedUserDecryptedPassword); } } } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 1437c8385d42..c8ed872932c7 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -1520,7 +1520,7 @@ public class ActivityManagerService extends IActivityManager.Stub static final int PERSIST_URI_GRANTS_MSG = 38; static final int REQUEST_ALL_PSS_MSG = 39; static final int START_PROFILES_MSG = 40; - static final int UPDATE_TIME = 41; + static final int UPDATE_TIME_PREFERENCE_MSG = 41; static final int SYSTEM_USER_START_MSG = 42; static final int SYSTEM_USER_CURRENT_MSG = 43; static final int ENTER_ANIMATION_COMPLETE_MSG = 44; @@ -2026,15 +2026,18 @@ public class ActivityManagerService extends IActivityManager.Stub } break; } - case UPDATE_TIME: { + case UPDATE_TIME_PREFERENCE_MSG: { + // The user's time format preference might have changed. + // For convenience we re-use the Intent extra values. synchronized (ActivityManagerService.this) { - for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { + for (int i = mLruProcesses.size() - 1; i >= 0; i--) { ProcessRecord r = mLruProcesses.get(i); if (r.thread != null) { try { - r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); + r.thread.updateTimePrefs(msg.arg1); } catch (RemoteException ex) { - Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); + Slog.w(TAG, "Failed to update preferences for: " + + r.info.processName); } } } @@ -8103,7 +8106,12 @@ public class ActivityManagerService extends IActivityManager.Stub // Third... does the caller itself have permission to access // this uri? - if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { + final int callingAppId = UserHandle.getAppId(callingUid); + if ((callingAppId == Process.SYSTEM_UID) || (callingAppId == Process.ROOT_UID)) { + Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission" + + " grant to " + grantUri + "; use startActivityAsCaller() instead"); + return -1; + } else { if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { // Require they hold a strong enough Uri permission if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { @@ -10338,6 +10346,46 @@ public class ActivityManagerService extends IActivityManager.Stub } /** + * Check if the calling UID has a possible chance at accessing the provider + * at the given authority and user. + */ + public String checkContentProviderAccess(String authority, int userId) { + if (userId == UserHandle.USER_ALL) { + mContext.enforceCallingOrSelfPermission( + Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG); + userId = UserHandle.getCallingUserId(); + } + + ProviderInfo cpi = null; + try { + cpi = AppGlobals.getPackageManager().resolveContentProvider(authority, + STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS + | PackageManager.MATCH_DIRECT_BOOT_AWARE + | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, + userId); + } catch (RemoteException ignored) { + } + if (cpi == null) { + // TODO: make this an outright failure in a future platform release; + // until then anonymous content notifications are unprotected + //return "Failed to find provider " + authority + " for user " + userId; + return null; + } + + ProcessRecord r = null; + synchronized (mPidsSelfLocked) { + r = mPidsSelfLocked.get(Binder.getCallingPid()); + } + if (r == null) { + return "Failed to find PID " + Binder.getCallingPid(); + } + + synchronized (this) { + return checkContentProviderPermissionLocked(cpi, r, userId, true); + } + } + + /** * Check if {@link ProcessRecord} has a possible chance at accessing the * given {@link ProviderInfo}. Final permission checking is always done * in {@link ContentProvider}. @@ -18124,11 +18172,20 @@ public class ActivityManagerService extends IActivityManager.Stub mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); break; case Intent.ACTION_TIME_CHANGED: - // If the user set the time, let all running processes know. - final int is24Hour = - intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 - : 0; - mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); + // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between + // the tri-state value it may contain and "unknown". + // For convenience we re-use the Intent extra values. + final int NO_EXTRA_VALUE_FOUND = -1; + final int timeFormatPreferenceMsgValue = intent.getIntExtra( + Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, + NO_EXTRA_VALUE_FOUND /* defaultValue */); + // Only send a message if the time preference is available. + if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) { + Message updateTimePreferenceMsg = + mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG, + timeFormatPreferenceMsgValue, 0); + mHandler.sendMessage(updateTimePreferenceMsg); + } BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); synchronized (stats) { stats.noteCurrentTimeChangedLocked(); @@ -22070,6 +22127,11 @@ public class ActivityManagerService extends IActivityManager.Stub private final class LocalService extends ActivityManagerInternal { @Override + public String checkContentProviderAccess(String authority, int userId) { + return ActivityManagerService.this.checkContentProviderAccess(authority, userId); + } + + @Override public void onWakefulnessChanged(int wakefulness) { ActivityManagerService.this.onWakefulnessChanged(wakefulness); } diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index 1bdef433483a..473b1a34a892 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -1471,7 +1471,7 @@ final class ActivityStack extends ConfigurationContainer { return STACK_INVISIBLE; } - if (mStackSupervisor.isFrontStack(this) || mStackSupervisor.isFocusedStack(this)) { + if (mStackSupervisor.isFrontStackOnDisplay(this) || mStackSupervisor.isFocusedStack(this)) { return STACK_VISIBLE; } diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 539ac1620961..5d8d79fd52c2 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -612,6 +612,15 @@ public class ActivityStackSupervisor extends ConfigurationContainer /** The top most stack. */ boolean isFrontStack(ActivityStack stack) { + return isFrontOfStackList(stack, mHomeStack.mStacks); + } + + /** The top most stack on its display. */ + boolean isFrontStackOnDisplay(ActivityStack stack) { + return isFrontOfStackList(stack, stack.mActivityContainer.mActivityDisplay.mStacks); + } + + private boolean isFrontOfStackList(ActivityStack stack, List<ActivityStack> stackList) { if (stack == null) { return false; } @@ -620,7 +629,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer if (parent != null) { stack = parent.getStack(); } - return stack == mHomeStack.mStacks.get((mHomeStack.mStacks.size() - 1)); + return stack == stackList.get((stackList.size() - 1)); } /** NOTE: Should only be called from {@link ActivityStack#moveToFront} */ diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index da016da9fa59..ac9545c06c10 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -272,7 +272,8 @@ public class AudioService extends IAudioService.Stub { 15, // STREAM_BLUETOOTH_SCO 7, // STREAM_SYSTEM_ENFORCED 15, // STREAM_DTMF - 15 // STREAM_TTS + 15, // STREAM_TTS + 15 // STREAM_ACCESSIBILITY }; /** Minimum volume index values for audio streams */ @@ -286,7 +287,8 @@ public class AudioService extends IAudioService.Stub { 0, // STREAM_BLUETOOTH_SCO 0, // STREAM_SYSTEM_ENFORCED 0, // STREAM_DTMF - 0 // STREAM_TTS + 0, // STREAM_TTS + 0 // STREAM_ACCESSIBILITY }; /* mStreamVolumeAlias[] indicates for each stream if it uses the volume settings @@ -308,7 +310,8 @@ public class AudioService extends IAudioService.Stub { AudioSystem.STREAM_BLUETOOTH_SCO, // STREAM_BLUETOOTH_SCO AudioSystem.STREAM_RING, // STREAM_SYSTEM_ENFORCED AudioSystem.STREAM_RING, // STREAM_DTMF - AudioSystem.STREAM_MUSIC // STREAM_TTS + AudioSystem.STREAM_MUSIC, // STREAM_TTS + AudioSystem.STREAM_MUSIC // STREAM_ACCESSIBILITY }; private final int[] STREAM_VOLUME_ALIAS_TELEVISION = new int[] { AudioSystem.STREAM_MUSIC, // STREAM_VOICE_CALL @@ -320,7 +323,8 @@ public class AudioService extends IAudioService.Stub { AudioSystem.STREAM_MUSIC, // STREAM_BLUETOOTH_SCO AudioSystem.STREAM_MUSIC, // STREAM_SYSTEM_ENFORCED AudioSystem.STREAM_MUSIC, // STREAM_DTMF - AudioSystem.STREAM_MUSIC // STREAM_TTS + AudioSystem.STREAM_MUSIC, // STREAM_TTS + AudioSystem.STREAM_MUSIC // STREAM_ACCESSIBILITY }; private final int[] STREAM_VOLUME_ALIAS_DEFAULT = new int[] { AudioSystem.STREAM_VOICE_CALL, // STREAM_VOICE_CALL @@ -332,7 +336,8 @@ public class AudioService extends IAudioService.Stub { AudioSystem.STREAM_BLUETOOTH_SCO, // STREAM_BLUETOOTH_SCO AudioSystem.STREAM_RING, // STREAM_SYSTEM_ENFORCED AudioSystem.STREAM_RING, // STREAM_DTMF - AudioSystem.STREAM_MUSIC // STREAM_TTS + AudioSystem.STREAM_MUSIC, // STREAM_TTS + AudioSystem.STREAM_MUSIC // STREAM_ACCESSIBILITY }; private int[] mStreamVolumeAlias; @@ -351,6 +356,7 @@ public class AudioService extends IAudioService.Stub { AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_SYSTEM_ENFORCED AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_DTMF AppOpsManager.OP_AUDIO_MEDIA_VOLUME, // STREAM_TTS + AppOpsManager.OP_AUDIO_ACCESSIBILITY_VOLUME, // STREAM_ACCESSIBILITY }; private final boolean mUseFixedVolume; diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java index 3b4cef4be3d3..886c97f4ce17 100644 --- a/services/core/java/com/android/server/content/ContentService.java +++ b/services/core/java/com/android/server/content/ContentService.java @@ -20,11 +20,11 @@ import android.Manifest; import android.accounts.Account; import android.annotation.Nullable; import android.app.ActivityManager; +import android.app.ActivityManagerInternal; import android.app.AppOpsManager; import android.app.job.JobInfo; import android.content.BroadcastReceiver; import android.content.ComponentName; -import android.content.ContentProvider; import android.content.ContentResolver; import android.content.Context; import android.content.IContentService; @@ -65,7 +65,6 @@ import com.android.server.SystemService; import java.io.FileDescriptor; import java.io.PrintWriter; -import java.security.InvalidParameterException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -295,24 +294,15 @@ public final class ContentService extends IContentService.Stub { final int uid = Binder.getCallingUid(); final int pid = Binder.getCallingPid(); - final int callingUserHandle = UserHandle.getCallingUserId(); - // Registering an observer for any user other than the calling user requires uri grant or - // cross user permission - if (callingUserHandle != userHandle) { - if (checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_READ_URI_PERMISSION, userHandle) - != PackageManager.PERMISSION_GRANTED) { - enforceCrossUserPermission(userHandle, - "no permission to observe other users' provider view"); - } - } - if (userHandle < 0) { - if (userHandle == UserHandle.USER_CURRENT) { - userHandle = ActivityManager.getCurrentUser(); - } else if (userHandle != UserHandle.USER_ALL) { - throw new InvalidParameterException("Bad user handle for registerContentObserver: " - + userHandle); - } + userHandle = handleIncomingUser(uri, pid, uid, + Intent.FLAG_GRANT_READ_URI_PERMISSION, userHandle); + + final String msg = LocalServices.getService(ActivityManagerInternal.class) + .checkContentProviderAccess(uri.getAuthority(), userHandle); + if (msg != null) { + Log.w(TAG, "Ignoring content changes for " + uri + " from " + uid + ": " + msg); + return; } synchronized (mRootNode) { @@ -362,22 +352,15 @@ public final class ContentService extends IContentService.Stub { final int uid = Binder.getCallingUid(); final int pid = Binder.getCallingPid(); final int callingUserHandle = UserHandle.getCallingUserId(); - // Notify for any user other than the caller requires uri grant or cross user permission - if (callingUserHandle != userHandle) { - if (checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, - userHandle) != PackageManager.PERMISSION_GRANTED) { - enforceCrossUserPermission(userHandle, "no permission to notify other users"); - } - } - // We passed the permission check; resolve pseudouser targets as appropriate - if (userHandle < 0) { - if (userHandle == UserHandle.USER_CURRENT) { - userHandle = ActivityManager.getCurrentUser(); - } else if (userHandle != UserHandle.USER_ALL) { - throw new InvalidParameterException("Bad user handle for notifyChange: " - + userHandle); - } + userHandle = handleIncomingUser(uri, pid, uid, + Intent.FLAG_GRANT_WRITE_URI_PERMISSION, userHandle); + + final String msg = LocalServices.getService(ActivityManagerInternal.class) + .checkContentProviderAccess(uri.getAuthority(), userHandle); + if (msg != null) { + Log.w(TAG, "Ignoring notify for " + uri + " from " + uid + ": " + msg); + return; } // This makes it so that future permission checks will be in the context of this @@ -1142,6 +1125,27 @@ public final class ContentService extends IContentService.Stub { } } + private int handleIncomingUser(Uri uri, int pid, int uid, int modeFlags, int userId) { + if (userId == UserHandle.USER_CURRENT) { + userId = ActivityManager.getCurrentUser(); + } + + if (userId == UserHandle.USER_ALL) { + mContext.enforceCallingOrSelfPermission( + Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG); + } else if (userId < 0) { + throw new IllegalArgumentException("Invalid user: " + userId); + } else if (userId != UserHandle.getCallingUserId()) { + if (checkUriPermission(uri, pid, uid, modeFlags, + userId) != PackageManager.PERMISSION_GRANTED) { + mContext.enforceCallingOrSelfPermission( + Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG); + } + } + + return userId; + } + /** * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS_FULL * permission, if the userHandle is not for the caller. diff --git a/services/core/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java index e1b598a03204..c42647ed0aee 100644 --- a/services/core/java/com/android/server/wm/AppWindowAnimator.java +++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java @@ -411,7 +411,7 @@ public class AppWindowAnimator { } if (mService.mInputMethodTarget != null && mService.mInputMethodTarget.mAppToken == mAppToken) { - mAppToken.getDisplayContent().moveInputMethodWindowsIfNeeded(true); + mAppToken.getDisplayContent().computeImeTarget(true /* updateImeTarget */); } if (DEBUG_ANIM) Slog.v(TAG, "Animation done in " + mAppToken diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index 5d739d13c898..45695960853f 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -1006,10 +1006,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree tStartingWindow.mToken = this; tStartingWindow.mAppToken = this; - if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, - "Removing starting window: " + tStartingWindow); - getDisplayContent().removeFromWindowList(tStartingWindow); - if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, + if (DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Removing starting " + tStartingWindow + " from " + fromToken); fromToken.removeChild(tStartingWindow); fromToken.postWindowRemoveStartingWindowCleanup(tStartingWindow); @@ -1259,18 +1256,6 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree } } - int rebuildWindowListUnchecked(int addIndex) { - return super.rebuildWindowList(addIndex); - } - - @Override - int rebuildWindowList(int addIndex) { - if (mIsExiting && !waitingForReplacement()) { - return addIndex; - } - return rebuildWindowListUnchecked(addIndex); - } - @Override boolean forAllWindows(ToBooleanFunction<WindowState> callback, boolean traverseTopToBottom) { // For legacy reasons we process the TaskStack.mExitingAppTokens first in DisplayContent @@ -1332,6 +1317,32 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree mLastContainsShowWhenLockedWindow = containsShowWhenLocked; } + WindowState getImeTargetBelowWindow(WindowState w) { + final int index = mChildren.indexOf(w); + if (index > 0) { + final WindowState target = mChildren.get(index - 1); + if (target.canBeImeTarget()) { + return target; + } + } + return null; + } + + WindowState getHighestAnimLayerWindow(WindowState currentTarget) { + WindowState candidate = null; + for (int i = mChildren.indexOf(currentTarget); i >= 0; i--) { + final WindowState w = mChildren.get(i); + if (w.mRemoved) { + continue; + } + if (candidate == null || w.mWinAnimator.mAnimLayer > + candidate.mWinAnimator.mAnimLayer) { + candidate = w; + } + } + return candidate; + } + @Override void dump(PrintWriter pw, String prefix) { super.dump(pw, prefix); diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index e73acde65a3d..24b9d6944ecc 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -33,10 +33,6 @@ import static android.view.View.GONE; import static android.view.WindowManager.DOCKED_BOTTOM; import static android.view.WindowManager.DOCKED_INVALID; import static android.view.WindowManager.DOCKED_TOP; -import static android.view.WindowManager.INPUT_CONSUMER_NAVIGATION; -import static android.view.WindowManager.INPUT_CONSUMER_PIP; -import static android.view.WindowManager.INPUT_CONSUMER_WALLPAPER; -import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; @@ -44,13 +40,10 @@ import static android.view.WindowManager.LayoutParams.FLAG_SECURE; import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; import static android.view.WindowManager.LayoutParams.NEEDS_MENU_SET_TRUE; import static android.view.WindowManager.LayoutParams.NEEDS_MENU_UNSET; -import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; -import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS; -import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER; import static android.view.WindowManager.LayoutParams.TYPE_DRAWN_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_DREAM; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; @@ -64,7 +57,6 @@ import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM; import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG; import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT; import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_BOOT; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS; @@ -77,10 +69,8 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREEN_ON; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT; import static com.android.server.wm.WindowManagerDebugConfig.SHOW_STACK_CRAWLS; import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; @@ -94,7 +84,6 @@ import static com.android.server.wm.WindowManagerService.TYPE_LAYER_OFFSET; import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES; import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_TIMEOUT; import static com.android.server.wm.WindowManagerService.dipToPixel; -import static com.android.server.wm.WindowManagerService.localLOGV; import static com.android.server.wm.WindowManagerService.logSurface; import static com.android.server.wm.WindowState.RESIZE_HANDLE_WIDTH_IN_DP; import static com.android.server.wm.WindowStateAnimator.DRAW_PENDING; @@ -120,29 +109,21 @@ import android.util.DisplayMetrics; import android.util.Slog; import android.view.Display; import android.view.DisplayInfo; -import android.view.IWindow; -import android.view.InputChannel; import android.view.Surface; import android.view.SurfaceControl; import android.view.WindowManagerPolicy; -import com.android.internal.util.FastPrintWriter; import com.android.internal.util.ToBooleanFunction; import com.android.internal.view.IInputMethodClient; -import com.android.server.input.InputWindowHandle; import java.io.FileDescriptor; import java.io.PrintWriter; -import java.io.StringWriter; import java.util.ArrayList; -import java.util.Arrays; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; -import java.util.function.Consumer; -import java.util.function.Function; /** * Utility class for keeping track of the WindowStates and other pertinent contents of a @@ -174,8 +155,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo private final NonAppWindowContainers mImeWindowsContainers = new NonAppWindowContainers("mImeWindowsContainers"); - // Z-ordered (bottom-most first) list of all Window objects. - private final WindowList mWindows = new WindowList(); + private WindowState mTmpWindow; // Mapping from a token IBinder to a WindowToken object on this display. private final HashMap<IBinder, WindowToken> mTokenMap = new HashMap(); @@ -232,21 +212,19 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo final ArrayList<WindowState> mTapExcludedWindows = new ArrayList<>(); - /** Used when rebuilding window list to keep track of windows that have been removed. */ - private WindowState[] mRebuildTmp = new WindowState[20]; - - /** - * Temporary list for comparison. Always clear this after use so we don't end up with - * orphaned windows references - */ - private final ArrayList<WindowState> mTmpWindows = new ArrayList<>(); + private boolean mHaveBootMsg = false; + private boolean mHaveApp = false; + private boolean mHaveWallpaper = false; + private boolean mHaveKeyguard = true; private final LinkedList<AppWindowToken> mTmpUpdateAllDrawn = new LinkedList(); private final TaskForResizePointSearchResult mTmpTaskForResizePointSearchResult = new TaskForResizePointSearchResult(); - private final GetWindowOnDisplaySearchResult mTmpGetWindowOnDisplaySearchResult = - new GetWindowOnDisplaySearchResult(); + private final ApplySurfaceChangesTransactionState mTmpApplySurfaceChangesTransactionState = + new ApplySurfaceChangesTransactionState(); + private final ScreenshotApplicationState mScreenshotApplicationState = + new ScreenshotApplicationState(); // True if this display is in the process of being removed. Used to determine if the removal of // the display's direct children should be allowed. @@ -455,17 +433,13 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo @Override void onAppTransitionDone() { super.onAppTransitionDone(); - rebuildAppWindowList(); + mService.mWindowsChanged = true; } @Override int getOrientation() { final WindowManagerPolicy policy = mService.mPolicy; - // TODO: All the logic before the last return statement in this method should really go in - // #NonAppWindowContainer.getOrientation() since it is trying to decide orientation based - // on non-app windows. But, we can not do that until the window list is always correct in - // terms of z-ordering based on layers. if (mService.mDisplayFrozen) { if (mService.mLastWindowForcedOrientation != SCREEN_ORIENTATION_UNSPECIFIED) { if (DEBUG_ORIENTATION) Slog.v(TAG_WM, @@ -486,31 +460,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo return mService.mLastOrientation; } } else { - for (int pos = mWindows.size() - 1; pos >= 0; --pos) { - final WindowState win = mWindows.get(pos); - if (win.mAppToken != null) { - // We hit an application window. so the orientation will be determined by the - // app window. No point in continuing further. - break; - } - if (!win.isVisibleLw() || !win.mPolicyVisibilityAfterAnim) { - continue; - } - int req = win.mAttrs.screenOrientation; - if(req == SCREEN_ORIENTATION_UNSPECIFIED || req == SCREEN_ORIENTATION_BEHIND) { - continue; - } - - if (DEBUG_ORIENTATION) Slog.v(TAG_WM, win + " forcing orientation to " + req); - if (policy.isKeyguardHostWindow(win.mAttrs)) { - mService.mLastKeyguardForcedOrientation = req; - } - return (mService.mLastWindowForcedOrientation = req); - } - mService.mLastWindowForcedOrientation = SCREEN_ORIENTATION_UNSPECIFIED; - - if (policy.isKeyguardShowingAndNotOccluded()) { - return mService.mLastKeyguardForcedOrientation; + final int orientation = mAboveAppWindowsContainers.getOrientation(); + if (orientation != SCREEN_ORIENTATION_UNSET) { + return orientation; } } @@ -738,22 +690,10 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } } + @Override void switchUser() { - final int count = mWindows.size(); - for (int i = 0; i < count; i++) { - final WindowState win = mWindows.get(i); - if (win.isHiddenFromUserLocked()) { - if (DEBUG_VISIBILITY) Slog.w(TAG_WM, "user changing, hiding " + win - + ", attrs=" + win.mAttrs.type + ", belonging to " + win.mOwnerUid); - win.hideLw(false); - } - } - - for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) { - mTaskStackContainers.get(stackNdx).switchUser(); - } - - rebuildAppWindowList(); + super.switchUser(); + mService.mWindowsChanged = true; } private void resetAnimationBackgroundAnimator() { @@ -915,19 +855,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo void setInputMethodAnimLayerAdjustment(int adj) { if (DEBUG_LAYERS) Slog.v(TAG_WM, "Setting im layer adj to " + adj); mInputMethodAnimLayerAdjustment = adj; - final WindowState imw = mService.mInputMethodWindow; - if (imw != null) { - imw.adjustAnimLayer(adj); - } - for (int i = mService.mInputMethodDialogs.size() - 1; i >= 0; i--) { - final WindowState dialog = mService.mInputMethodDialogs.get(i); - // TODO: This and other places setting mAnimLayer can probably use WS.adjustAnimLayer, - // but need to make sure we are not setting things twice for child windows that are - // already in the list. - dialog.mWinAnimator.mAnimLayer = dialog.mLayer + adj; - if (DEBUG_LAYERS) Slog.v(TAG_WM, "IM win " + imw - + " anim layer: " + dialog.mWinAnimator.mAnimLayer); - } + mImeWindowsContainers.forAllWindows(w -> { + w.adjustAnimLayer(adj); + }, true /* traverseTopToBottom */); } /** @@ -936,11 +866,11 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo * suddenly disappear. */ int getLayerForAnimationBackground(WindowStateAnimator winAnimator) { - for (int i = mWindows.size() - 1; i >= 0; --i) { - final WindowState win = mWindows.get(i); - if (win.mIsWallpaper && win.isVisibleNow()) { - return win.mWinAnimator.mAnimLayer; - } + final WindowState visibleWallpaper = mBelowAppWindowsContainers.getWindow( + w -> w.mIsWallpaper && w.isVisibleNow()); + + if (visibleWallpaper != null) { + return visibleWallpaper.mWinAnimator.mAnimLayer; } return winAnimator.mAnimLayer; } @@ -1088,48 +1018,37 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo /** Find the visible, touch-deliverable window under the given point */ WindowState getTouchableWinAtPointLocked(float xf, float yf) { - WindowState touchedWin = null; final int x = (int) xf; final int y = (int) yf; - - for (int i = mWindows.size() - 1; i >= 0; i--) { - WindowState window = mWindows.get(i); - final int flags = window.mAttrs.flags; - if (!window.isVisibleLw()) { - continue; + final WindowState touchedWin = getWindow(w -> { + final int flags = w.mAttrs.flags; + if (!w.isVisibleLw()) { + return false; } if ((flags & FLAG_NOT_TOUCHABLE) != 0) { - continue; + return false; } - window.getVisibleBounds(mTmpRect); + w.getVisibleBounds(mTmpRect); if (!mTmpRect.contains(x, y)) { - continue; + return false; } - window.getTouchableRegion(mTmpRegion); + w.getTouchableRegion(mTmpRegion); final int touchFlags = flags & (FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL); - if (mTmpRegion.contains(x, y) || touchFlags == 0) { - touchedWin = window; - break; - } - } + return mTmpRegion.contains(x, y) || touchFlags == 0; + }); return touchedWin; } boolean canAddToastWindowForUid(int uid) { // We allow one toast window per UID being shown at a time. - final int windowCount = mWindows.size(); - for (int i = 0; i < windowCount; i++) { - final WindowState window = mWindows.get(i); - if (window.mAttrs.type == TYPE_TOAST && window.mOwnerUid == uid - && !window.mPermanentlyHidden && !window.mWindowRemovalAllowed) { - return false; - } - } - return true; + final WindowState win = getWindow(w -> + w.mAttrs.type == TYPE_TOAST && w.mOwnerUid == uid && !w.mPermanentlyHidden + && !w.mWindowRemovalAllowed); + return win == null; } void scheduleToastWindowsTimeoutIfNeededLocked(WindowState oldFocus, WindowState newFocus) { @@ -1137,268 +1056,76 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo return; } final int lostFocusUid = oldFocus.mOwnerUid; - final int windowCount = mWindows.size(); final Handler handler = mService.mH; - for (int i = 0; i < windowCount; i++) { - final WindowState window = mWindows.get(i); - if (window.mAttrs.type == TYPE_TOAST && window.mOwnerUid == lostFocusUid) { - if (!handler.hasMessages(WINDOW_HIDE_TIMEOUT, window)) { - handler.sendMessageDelayed(handler.obtainMessage(WINDOW_HIDE_TIMEOUT, window), - window.mAttrs.hideTimeoutMilliseconds); + + forAllWindows(w -> { + if (w.mAttrs.type == TYPE_TOAST && w.mOwnerUid == lostFocusUid) { + if (!handler.hasMessages(WINDOW_HIDE_TIMEOUT, w)) { + handler.sendMessageDelayed(handler.obtainMessage(WINDOW_HIDE_TIMEOUT, w), + w.mAttrs.hideTimeoutMilliseconds); } } - } + }, false /* traverseTopToBottom */); } WindowState findFocusedWindow() { final AppWindowToken focusedApp = mService.mFocusedApp; + mTmpWindow = null; - for (int i = mWindows.size() - 1; i >= 0; i--) { - final WindowState win = mWindows.get(i); + forAllWindows(w -> { + if (DEBUG_FOCUS) Slog.v(TAG_WM, "Looking for focus: " + w + + ", flags=" + w.mAttrs.flags + ", canReceive=" + w.canReceiveKeys()); - if (DEBUG_FOCUS) Slog.v(TAG_WM, "Looking for focus: " + i + " = " + win - + ", flags=" + win.mAttrs.flags + ", canReceive=" + win.canReceiveKeys()); - - if (!win.canReceiveKeys()) { - continue; + if (!w.canReceiveKeys()) { + return false; } - final AppWindowToken wtoken = win.mAppToken; + final AppWindowToken wtoken = w.mAppToken; // If this window's application has been removed, just skip it. if (wtoken != null && (wtoken.removed || wtoken.sendingToBottom)) { if (DEBUG_FOCUS) Slog.v(TAG_WM, "Skipping " + wtoken + " because " + (wtoken.removed ? "removed" : "sendingToBottom")); - continue; + return false; } if (focusedApp == null) { if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: focusedApp=null" - + " using new focus @ " + i + " = " + win); - return win; + + " using new focus @ " + w); + mTmpWindow = w; + return true; } if (!focusedApp.windowsAreFocusable()) { // Current focused app windows aren't focusable... if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: focusedApp windows not" - + " focusable using new focus @ " + i + " = " + win); - return win; + + " focusable using new focus @ " + w); + mTmpWindow = w; + return true; } // Descend through all of the app tokens and find the first that either matches // win.mAppToken (return win) or mFocusedApp (return null). - if (wtoken != null && win.mAttrs.type != TYPE_APPLICATION_STARTING) { + if (wtoken != null && w.mAttrs.type != TYPE_APPLICATION_STARTING) { if (focusedApp.compareTo(wtoken) > 0) { // App stack below focused app stack. No focus for you!!! if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: Reached focused app=" + focusedApp); - return null; - } - } - - if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: Found new focus @ " - + i + " = " + win); - return win; - } - - if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: No focusable windows."); - return null; - } - - void addAppWindowToWindowList(final WindowState win) { - final IWindow client = win.mClient; - - WindowList tokenWindowList = getTokenWindowsOnDisplay(win.mToken); - if (!tokenWindowList.isEmpty()) { - addAppWindowExisting(win, tokenWindowList); - return; - } - - // No windows from this token on this display - if (localLOGV) Slog.v(TAG_WM, "Figuring out where to add app window " - + client.asBinder() + " (token=" + this + ")"); - - final WindowToken wToken = win.mToken; - - // Figure out where the window should go, based on the order of applications. - mTmpGetWindowOnDisplaySearchResult.reset(); - for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) { - final TaskStack stack = mTaskStackContainers.get(i); - stack.getWindowOnDisplayBeforeToken(this, wToken, mTmpGetWindowOnDisplaySearchResult); - if (mTmpGetWindowOnDisplaySearchResult.reachedToken) { - // We have reach the token we are interested in. End search. - break; - } - } - - WindowState pos = mTmpGetWindowOnDisplaySearchResult.foundWindow; - - // We now know the index into the apps. If we found an app window above, that gives us the - // position; else we need to look some more. - if (pos != null) { - // Move behind any windows attached to this one. - final WindowToken atoken = getWindowToken(pos.mClient.asBinder()); - if (atoken != null) { - tokenWindowList = getTokenWindowsOnDisplay(atoken); - final int NC = tokenWindowList.size(); - if (NC > 0) { - WindowState bottom = tokenWindowList.get(0); - if (bottom.mSubLayer < 0) { - pos = bottom; - } - } - } - addWindowToListBefore(win, pos); - return; - } - - // Continue looking down until we find the first token that has windows on this display. - mTmpGetWindowOnDisplaySearchResult.reset(); - for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) { - final TaskStack stack = mTaskStackContainers.get(i); - stack.getWindowOnDisplayAfterToken(this, wToken, mTmpGetWindowOnDisplaySearchResult); - if (mTmpGetWindowOnDisplaySearchResult.foundWindow != null) { - // We have found a window after the token. End search. - break; - } - } - - pos = mTmpGetWindowOnDisplaySearchResult.foundWindow; - - if (pos != null) { - // Move in front of any windows attached to this one. - final WindowToken atoken = getWindowToken(pos.mClient.asBinder()); - if (atoken != null) { - final WindowState top = atoken.getTopWindow(); - if (top != null && top.mSubLayer >= 0) { - pos = top; + mTmpWindow = null; + return true; } } - addWindowToListAfter(win, pos); - return; - } - - // Just search for the start of this layer. - final int myLayer = win.mBaseLayer; - int i; - for (i = mWindows.size() - 1; i >= 0; --i) { - final WindowState w = mWindows.get(i); - // Dock divider shares the base layer with application windows, but we want to always - // keep it above the application windows. The sharing of the base layer is intended - // for window animations, which need to be above the dock divider for the duration - // of the animation. - if (w.mBaseLayer <= myLayer && w.mAttrs.type != TYPE_DOCK_DIVIDER) { - break; - } - } - if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM, - "Based on layer: Adding window " + win + " at " + (i + 1) + " of " - + mWindows.size()); - mWindows.add(i + 1, win); - mService.mWindowsChanged = true; - } - /** Adds this non-app window to the window list. */ - void addNonAppWindowToWindowList(WindowState win) { - // Figure out where window should go, based on layer. - int i; - for (i = mWindows.size() - 1; i >= 0; i--) { - final WindowState otherWin = mWindows.get(i); - if (otherWin.getBaseType() != TYPE_WALLPAPER && otherWin.mBaseLayer <= win.mBaseLayer) { - // Wallpaper wanders through the window list, for example to position itself - // directly behind keyguard. Because of this it will break the ordering based on - // WindowState.mBaseLayer. There might windows with higher mBaseLayer behind it and - // we don't want the new window to appear above them. An example of this is adding - // of the docked stack divider. Consider a scenario with the following ordering (top - // to bottom): keyguard, wallpaper, assist preview, apps. We want the dock divider - // to land below the assist preview, so the dock divider must ignore the wallpaper, - // with which it shares the base layer. - break; - } - } - - i++; - if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM, - "Free window: Adding window " + this + " at " + i + " of " + mWindows.size()); - mWindows.add(i, win); - mService.mWindowsChanged = true; - } - - void addToWindowList(WindowState win, int index) { - mService.mWindowsChanged = true; - mWindows.add(index, win); - } - - boolean removeFromWindowList(WindowState win) { - mService.mWindowsChanged = true; - return mWindows.remove(win); - } - - private int removeWindowAndChildrenFromWindowList(WindowState win, int interestingPos) { - int wpos = mWindows.indexOf(win); - if (wpos < 0) { - return interestingPos; - } - - if (wpos < interestingPos) interestingPos--; - if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Temp removing at " + wpos + ": " + this); - mWindows.remove(wpos); - mService.mWindowsChanged = true; - int childWinCount = win.mChildren.size(); - while (childWinCount > 0) { - childWinCount--; - final WindowState cw = win.mChildren.get(childWinCount); - int cpos = mWindows.indexOf(cw); - if (cpos >= 0) { - if (cpos < interestingPos) interestingPos--; - if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, - "Temp removing child at " + cpos + ": " + cw); - mWindows.remove(cpos); - } - } - return interestingPos; - } - - void addChildWindowToWindowList(WindowState win) { - final WindowState parentWindow = win.getParentWindow(); - - WindowList windowsOnSameDisplay = getTokenWindowsOnDisplay(win.mToken); + if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: Found new focus @ " + w); + mTmpWindow = w; + return true; + }, true /* traverseTopToBottom */); - // Figure out this window's ordering relative to the parent window. - final int wCount = windowsOnSameDisplay.size(); - final int sublayer = win.mSubLayer; - int largestSublayer = Integer.MIN_VALUE; - WindowState windowWithLargestSublayer = null; - int i; - for (i = 0; i < wCount; i++) { - WindowState w = windowsOnSameDisplay.get(i); - final int wSublayer = w.mSubLayer; - if (wSublayer >= largestSublayer) { - largestSublayer = wSublayer; - windowWithLargestSublayer = w; - } - if (sublayer < 0) { - // For negative sublayers, we go below all windows in the same sublayer. - if (wSublayer >= sublayer) { - addWindowToListBefore(win, wSublayer >= 0 ? parentWindow : w); - break; - } - } else { - // For positive sublayers, we go above all windows in the same sublayer. - if (wSublayer > sublayer) { - addWindowToListBefore(win, w); - break; - } - } - } - if (i >= wCount) { - if (sublayer < 0) { - addWindowToListBefore(win, parentWindow); - } else { - addWindowToListAfter(win, - largestSublayer >= 0 ? windowWithLargestSublayer : parentWindow); - } + if (mTmpWindow == null) { + if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: No focusable windows."); + return null; } + return mTmpWindow; } /** Updates the layer assignment of windows on this display. */ @@ -1409,136 +1136,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } } - void adjustWallpaperWindows() { - mWallpaperController.adjustWallpaperWindows(this); - } - - /** - * Z-orders the display window list so that: - * <ul> - * <li>Any windows that are currently below the wallpaper window stay below the wallpaper - * window. - * <li>Exiting application windows are at the bottom, but above the wallpaper window. - * <li>All other application windows are above the exiting application windows and ordered based - * on the ordering of their stacks and tasks on the display. - * <li>Non-application windows are at the very top. - * </ul> - * <p> - * NOTE: This isn't a complete picture of what the user see. Further manipulation of the window - * surface layering is done in {@link WindowLayersController}. - */ - void rebuildAppWindowList() { - int count = mWindows.size(); - int i; - int lastBelow = -1; - int numRemoved = 0; - - if (mRebuildTmp.length < count) { - mRebuildTmp = new WindowState[count + 10]; - } - - // First remove all existing app windows. - i = 0; - while (i < count) { - final WindowState w = mWindows.get(i); - if (w.mAppToken != null) { - final WindowState win = mWindows.remove(i); - win.mRebuilding = true; - mRebuildTmp[numRemoved] = win; - mService.mWindowsChanged = true; - if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Rebuild removing window: " + win); - count--; - numRemoved++; - continue; - } else if (lastBelow == i-1) { - if (w.mAttrs.type == TYPE_WALLPAPER) { - lastBelow = i; - } - } - i++; - } - - // Keep whatever windows were below the app windows still below, by skipping them. - lastBelow++; - i = lastBelow; - - // First add all of the exiting app tokens... these are no longer in the main app list, - // but still have windows shown. We put them in the back because now that the animation is - // over we no longer will care about them. - final int numStacks = mTaskStackContainers.size(); - for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { - AppTokenList exitingAppTokens = mTaskStackContainers.get(stackNdx).mExitingAppTokens; - int NT = exitingAppTokens.size(); - for (int j = 0; j < NT; j++) { - i = exitingAppTokens.get(j).rebuildWindowListUnchecked(i); - } - } - - // And add in the still active app tokens in Z order. - for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { - i = mTaskStackContainers.get(stackNdx).rebuildWindowList(i); - } - - i -= lastBelow; - if (i != numRemoved) { - setLayoutNeeded(); - Slog.w(TAG_WM, "On display=" + mDisplayId + " Rebuild removed " + numRemoved - + " windows but added " + i + " rebuildAppWindowListLocked() " - + " callers=" + Debug.getCallers(10)); - for (i = 0; i < numRemoved; i++) { - WindowState ws = mRebuildTmp[i]; - if (ws.mRebuilding) { - StringWriter sw = new StringWriter(); - PrintWriter pw = new FastPrintWriter(sw, false, 1024); - ws.dump(pw, "", true); - pw.flush(); - Slog.w(TAG_WM, "This window was lost: " + ws); - Slog.w(TAG_WM, sw.toString()); - ws.mWinAnimator.destroySurfaceLocked(); - } - } - Slog.w(TAG_WM, "Current window hierarchy:"); - dumpChildrenNames(); - Slog.w(TAG_WM, "Final window list:"); - dumpWindows(); - } - Arrays.fill(mRebuildTmp, null); - } - - /** Rebuilds the display's window list and does a relayout if something changed. */ - void rebuildAppWindowsAndLayoutIfNeeded() { - mTmpWindows.clear(); - mTmpWindows.addAll(mWindows); - - rebuildAppWindowList(); - - // Set displayContent.mLayoutNeeded if window order changed. - final int tmpSize = mTmpWindows.size(); - final int winSize = mWindows.size(); - int tmpNdx = 0, winNdx = 0; - while (tmpNdx < tmpSize && winNdx < winSize) { - // Skip over all exiting windows, they've been moved out of order. - WindowState tmp; - do { - tmp = mTmpWindows.get(tmpNdx++); - } while (tmpNdx < tmpSize && tmp.mAppToken != null && tmp.mAppToken.mIsExiting); - - WindowState win; - do { - win = mWindows.get(winNdx++); - } while (winNdx < winSize && win.mAppToken != null && win.mAppToken.mIsExiting); - - if (tmp != win) { - // Window order changed. - setLayoutNeeded(); - break; - } - } - if (tmpNdx != winNdx) { - // One list was different from the other. - setLayoutNeeded(); - } - mTmpWindows.clear(); + void layoutAndAssignWindowLayersIfNeeded() { + mService.mWindowsChanged = true; + setLayoutNeeded(); if (!mService.updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/)) { @@ -1550,321 +1150,69 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo mService.mInputMonitor.updateInputWindowsLw(false /*force*/); } - void updateInputWindows(InputMonitor inputMonitor, WindowState inputFocus, boolean inDrag) { - final InputConsumerImpl navInputConsumer = - mService.mInputMonitor.getInputConsumer(INPUT_CONSUMER_NAVIGATION, mDisplayId); - final InputConsumerImpl pipInputConsumer = - mService.mInputMonitor.getInputConsumer(INPUT_CONSUMER_PIP, mDisplayId); - final InputConsumerImpl wallpaperInputConsumer = - mService.mInputMonitor.getInputConsumer(INPUT_CONSUMER_WALLPAPER, mDisplayId); - boolean addInputConsumerHandle = navInputConsumer != null; - boolean addPipInputConsumerHandle = pipInputConsumer != null; - boolean addWallpaperInputConsumerHandle = wallpaperInputConsumer != null; - final Rect pipTouchableBounds = addPipInputConsumerHandle ? new Rect() : null; - boolean disableWallpaperTouchEvents = false; - - for (int winNdx = mWindows.size() - 1; winNdx >= 0; --winNdx) { - final WindowState child = mWindows.get(winNdx); - final InputChannel inputChannel = child.mInputChannel; - final InputWindowHandle inputWindowHandle = child.mInputWindowHandle; - if (inputChannel == null || inputWindowHandle == null || child.mRemoved - || child.isAdjustedForMinimizedDock()) { - // Skip this window because it cannot possibly receive input. - continue; - } - - if (addPipInputConsumerHandle - && child.getStackId() == PINNED_STACK_ID - && inputWindowHandle.layer <= pipInputConsumer.mWindowHandle.layer) { - // Update the bounds of the Pip input consumer to match the Pinned stack - child.getStack().getBounds(pipTouchableBounds); - pipInputConsumer.mWindowHandle.touchableRegion.set(pipTouchableBounds); - inputMonitor.addInputWindowHandle(pipInputConsumer.mWindowHandle); - addPipInputConsumerHandle = false; - } - - if (addInputConsumerHandle - && inputWindowHandle.layer <= navInputConsumer.mWindowHandle.layer) { - inputMonitor.addInputWindowHandle(navInputConsumer.mWindowHandle); - addInputConsumerHandle = false; - } - - if (addWallpaperInputConsumerHandle) { - if (child.mAttrs.type == TYPE_WALLPAPER && child.isVisibleLw()) { - // Add the wallpaper input consumer above the first visible wallpaper. - inputMonitor.addInputWindowHandle(wallpaperInputConsumer.mWindowHandle); - addWallpaperInputConsumerHandle = false; - } - } - - final int flags = child.mAttrs.flags; - final int privateFlags = child.mAttrs.privateFlags; - final int type = child.mAttrs.type; - - final boolean hasFocus = child == inputFocus; - final boolean isVisible = child.isVisibleLw(); - if ((privateFlags & PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS) != 0) { - disableWallpaperTouchEvents = true; - } - final boolean hasWallpaper = mWallpaperController.isWallpaperTarget(child) - && (privateFlags & PRIVATE_FLAG_KEYGUARD) == 0 - && !disableWallpaperTouchEvents; - - // If there's a drag in progress and 'child' is a potential drop target, - // make sure it's been told about the drag - if (inDrag && isVisible && isDefaultDisplay) { - mService.mDragState.sendDragStartedIfNeededLw(child); - } - - inputMonitor.addInputWindowHandle( - inputWindowHandle, child, flags, type, isVisible, hasFocus, hasWallpaper); - } - - if (addWallpaperInputConsumerHandle) { - // No visible wallpaper found, add the wallpaper input consumer at the end. - inputMonitor.addInputWindowHandle(wallpaperInputConsumer.mWindowHandle); - } - } - /** Returns true if a leaked surface was destroyed */ boolean destroyLeakedSurfaces() { - boolean leakedSurface = false; - final int numWindows = mWindows.size(); - for (int winNdx = 0; winNdx < numWindows; ++winNdx) { - final WindowState ws = mWindows.get(winNdx); - final WindowStateAnimator wsa = ws.mWinAnimator; + // Used to indicate that a surface was leaked. + mTmpWindow = null; + forAllWindows(w -> { + final WindowStateAnimator wsa = w.mWinAnimator; if (wsa.mSurfaceController == null) { - continue; + return; } if (!mService.mSessions.contains(wsa.mSession)) { Slog.w(TAG_WM, "LEAKED SURFACE (session doesn't exist): " - + ws + " surface=" + wsa.mSurfaceController - + " token=" + ws.mToken - + " pid=" + ws.mSession.mPid - + " uid=" + ws.mSession.mUid); + + w + " surface=" + wsa.mSurfaceController + + " token=" + w.mToken + + " pid=" + w.mSession.mPid + + " uid=" + w.mSession.mUid); wsa.destroySurface(); - mService.mForceRemoves.add(ws); - leakedSurface = true; - } else if (ws.mAppToken != null && ws.mAppToken.clientHidden) { + mService.mForceRemoves.add(w); + mTmpWindow = w; + } else if (w.mAppToken != null && w.mAppToken.clientHidden) { Slog.w(TAG_WM, "LEAKED SURFACE (app token hidden): " - + ws + " surface=" + wsa.mSurfaceController - + " token=" + ws.mAppToken - + " saved=" + ws.hasSavedSurface()); - if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", false); + + w + " surface=" + wsa.mSurfaceController + + " token=" + w.mAppToken + + " saved=" + w.hasSavedSurface()); + if (SHOW_TRANSACTIONS) logSurface(w, "LEAK DESTROY", false); wsa.destroySurface(); - leakedSurface = true; + mTmpWindow = w; } - } - - return leakedSurface; - } - - /** Return the list of Windows on this display associated with the input token. */ - WindowList getTokenWindowsOnDisplay(WindowToken token) { - final WindowList windowList = new WindowList(); - final int count = mWindows.size(); - for (int i = 0; i < count; i++) { - final WindowState win = mWindows.get(i); - if (win.mToken == token) { - windowList.add(win); - } - } - return windowList; - } - - private void reAddToWindowList(WindowState win) { - win.mToken.addWindow(win); - // This is a hack to get all of the child windows added as well at the right position. Child - // windows should be rare and this case should be rare, so it shouldn't be that big a deal. - int wpos = mWindows.indexOf(win); - if (wpos >= 0) { - if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "ReAdd removing from " + wpos + ": " + win); - mWindows.remove(wpos); - mService.mWindowsChanged = true; - win.reAddWindow(wpos); - } - } + }, false /* traverseTopToBottom */); - void moveInputMethodDialogs(int pos) { - ArrayList<WindowState> dialogs = mService.mInputMethodDialogs; - - final int N = dialogs.size(); - if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Removing " + N + " dialogs w/pos=" + pos); - for (int i = 0; i < N; i++) { - pos = removeWindowAndChildrenFromWindowList(dialogs.get(i), pos); - } - if (DEBUG_INPUT_METHOD) { - Slog.v(TAG_WM, "Window list w/pos=" + pos); - logWindowList(mWindows, " "); - } - - WindowState ime = mService.mInputMethodWindow; - if (pos >= 0) { - // Skip windows owned by the input method. - if (ime != null) { - while (pos < mWindows.size()) { - WindowState wp = mWindows.get(pos); - if (wp == ime || wp.getParentWindow() == ime) { - pos++; - continue; - } - break; - } - } - if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Adding " + N + " dialogs at pos=" + pos); - for (int i=0; i<N; i++) { - WindowState win = dialogs.get(i); - pos = win.reAddWindow(pos); - } - if (DEBUG_INPUT_METHOD) { - Slog.v(TAG_WM, "Final window list:"); - logWindowList(mWindows, " "); - } - return; - } - for (int i=0; i<N; i++) { - WindowState win = dialogs.get(i); - reAddToWindowList(win); - if (DEBUG_INPUT_METHOD) { - Slog.v(TAG_WM, "No IM target, final list:"); - logWindowList(mWindows, " "); - } - } - } - - boolean moveInputMethodWindowsIfNeeded(boolean needAssignLayers) { - final WindowState imWin = mService.mInputMethodWindow; - final int DN = mService.mInputMethodDialogs.size(); - if (imWin == null && DN == 0) { - return false; - } - - // TODO(multidisplay): IMEs are only supported on the default display. - int imPos = findDesiredInputMethodWindowIndex(true); - if (imPos >= 0) { - // In this case, the input method windows are to be placed - // immediately above the window they are targeting. - - // First check to see if the input method windows are already - // located here, and contiguous. - final int N = mWindows.size(); - final WindowState firstImWin = imPos < N ? mWindows.get(imPos) : null; - - // Figure out the actual input method window that should be - // at the bottom of their stack. - WindowState baseImWin = imWin != null ? imWin : mService.mInputMethodDialogs.get(0); - final WindowState cw = baseImWin.getBottomChild(); - if (cw != null && cw.mSubLayer < 0) { - baseImWin = cw; - } - - if (firstImWin == baseImWin) { - // The windows haven't moved... but are they still contiguous? - // First find the top IM window. - int pos = imPos+1; - while (pos < N) { - if (!(mWindows.get(pos)).mIsImWindow) { - break; - } - pos++; - } - pos++; - // Now there should be no more input method windows above. - while (pos < N) { - if ((mWindows.get(pos)).mIsImWindow) { - break; - } - pos++; - } - if (pos >= N) { - return false; - } - } - - if (imWin != null) { - if (DEBUG_INPUT_METHOD) { - Slog.v(TAG_WM, "Moving IM from " + imPos); - logWindowList(mWindows, " "); - } - imPos = removeWindowAndChildrenFromWindowList(imWin, imPos); - if (DEBUG_INPUT_METHOD) { - Slog.v(TAG_WM, "List after removing with new pos " + imPos + ":"); - logWindowList(mWindows, " "); - } - imWin.reAddWindow(imPos); - if (DEBUG_INPUT_METHOD) { - Slog.v(TAG_WM, "List after moving IM to " + imPos + ":"); - logWindowList(mWindows, " "); - } - if (DN > 0) moveInputMethodDialogs(imPos+1); - } else { - moveInputMethodDialogs(imPos); - } - - } else { - // In this case, the input method windows go in a fixed layer, - // because they aren't currently associated with a focus window. - - if (imWin != null) { - if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Moving IM from " + imPos); - removeWindowAndChildrenFromWindowList(imWin, 0); - reAddToWindowList(imWin); - if (DEBUG_INPUT_METHOD) { - Slog.v(TAG_WM, "List with no IM target:"); - logWindowList(mWindows, " "); - } - if (DN > 0) moveInputMethodDialogs(-1); - } else { - moveInputMethodDialogs(-1); - } - - } - - if (needAssignLayers) { - assignWindowLayers(false /* setLayoutNeeded */); - } - - return true; + return mTmpWindow != null; } /** - * Dig through the WindowStates and find the one that the Input Method will target. - * @param willMove - * @return The index+1 in mWindows of the discovered target. + * Determine and return the window that should be the IME target. + * @param updateImeTarget If true the system IME target will be updated to match what we found. + * @return The window that should be used as the IME target or null if there isn't any. */ - int findDesiredInputMethodWindowIndex(boolean willMove) { + WindowState computeImeTarget(boolean updateImeTarget) { // TODO(multidisplay): Needs some serious rethought when the target and IME are not on the // same display. Or even when the current IME/target are not on the same screen as the next // IME/target. For now only look for input windows on the main screen. - WindowState w = null; - int i; - for (i = mWindows.size() - 1; i >= 0; --i) { - final WindowState win = mWindows.get(i); - - if (DEBUG_INPUT_METHOD && willMove) Slog.i(TAG_WM, "Checking window @" + i - + " " + win + " fl=0x" + Integer.toHexString(win.mAttrs.flags)); - if (canBeImeTarget(win)) { - w = win; - //Slog.i(TAG_WM, "Putting input method here!"); - - // Yet more tricksyness! If this window is a "starting" window, we do actually want - // to be on top of it, but it is not -really- where input will go. So if the caller - // is not actually looking to move the IME, look down below for a real window to - // target... - if (!willMove && w.mAttrs.type == TYPE_APPLICATION_STARTING && i > 0) { - final WindowState wb = mWindows.get(i-1); - if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) { - i--; - w = wb; - } + WindowState target = getWindow(w -> { + if (DEBUG_INPUT_METHOD && updateImeTarget) Slog.i(TAG_WM, "Checking window @" + + w + " fl=0x" + Integer.toHexString(w.mAttrs.flags)); + return w.canBeImeTarget(); + }); + + + // Yet more tricksyness! If this window is a "starting" window, we do actually want + // to be on top of it, but it is not -really- where input will go. So look down below + // for a real window to target... + if (target != null && target.mAttrs.type == TYPE_APPLICATION_STARTING) { + final AppWindowToken token = target.mAppToken; + if (token != null) { + final WindowState betterTarget = token.getImeTargetBelowWindow(target); + if (betterTarget != null) { + target = betterTarget; } - break; } } - // Now w is either mWindows[0] or an IME (or null if mWindows is empty). - - if (DEBUG_INPUT_METHOD && willMove) Slog.v(TAG_WM, "Proposed new IME target: " + w); + if (DEBUG_INPUT_METHOD && updateImeTarget) Slog.v(TAG_WM, + "Proposed new IME target: " + target); // Now, a special case -- if the last target's window is in the process of exiting, and is // above the new target, keep on the last target to avoid flicker. Consider for example a @@ -1872,18 +1220,28 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo // until it is completely gone so it doesn't drop behind the dialog or its full-screen // scrim. final WindowState curTarget = mService.mInputMethodTarget; - if (curTarget != null - && curTarget.isDisplayedLw() - && curTarget.isClosing() - && (w == null || curTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer)) { + if (curTarget != null && curTarget.isDisplayedLw() && curTarget.isClosing() + && (target == null + || curTarget.mWinAnimator.mAnimLayer > target.mWinAnimator.mAnimLayer)) { if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Current target higher, not changing"); - return mWindows.indexOf(curTarget) + 1; + return curTarget; } - if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Desired input method target=" - + w + " willMove=" + willMove); + if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Desired input method target=" + target + + " updateImeTarget=" + updateImeTarget); + + if (target == null) { + if (updateImeTarget) { + if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget + + " to null." + (SHOW_STACK_CRAWLS ? " Callers=" + + Debug.getCallers(4) : "")); + setInputMethodTarget(null, mService.mInputMethodTargetWaitingAnim, 0); + } + + return null; + } - if (willMove && w != null) { + if (updateImeTarget) { AppWindowToken token = curTarget == null ? null : curTarget.mAppToken; if (token != null) { @@ -1891,24 +1249,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo // to look at all windows below the current target that are in this app, finding the // highest visible one in layering. WindowState highestTarget = null; - int highestPos = 0; if (token.mAppAnimator.animating || token.mAppAnimator.animation != null) { - WindowList curWindows = token.getDisplayContent().mWindows; - int pos = curWindows.indexOf(curTarget); - while (pos >= 0) { - WindowState win = curWindows.get(pos); - if (win.mAppToken != token) { - break; - } - if (!win.mRemoved) { - if (highestTarget == null || win.mWinAnimator.mAnimLayer > - highestTarget.mWinAnimator.mAnimLayer) { - highestTarget = win; - highestPos = pos; - } - } - pos--; - } + highestTarget = token.getHighestAnimLayerWindow(curTarget); } if (highestTarget != null) { @@ -1916,121 +1258,76 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, appTransition + " " + highestTarget + " animating=" + highestTarget.mWinAnimator.isAnimationSet() + " layer=" + highestTarget.mWinAnimator.mAnimLayer - + " new layer=" + w.mWinAnimator.mAnimLayer); + + " new layer=" + target.mWinAnimator.mAnimLayer); if (appTransition.isTransitionSet()) { // If we are currently setting up for an animation, hold everything until we // can find out what will happen. - mService.mInputMethodTargetWaitingAnim = true; - mService.mInputMethodTarget = highestTarget; - return highestPos + 1; + setInputMethodTarget(highestTarget, true, mInputMethodAnimLayerAdjustment); + return highestTarget; } else if (highestTarget.mWinAnimator.isAnimationSet() && - highestTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer) { + highestTarget.mWinAnimator.mAnimLayer > target.mWinAnimator.mAnimLayer) { // If the window we are currently targeting is involved with an animation, // and it is on top of the next target we will be over, then hold off on // moving until that is done. - mService.mInputMethodTargetWaitingAnim = true; - mService.mInputMethodTarget = highestTarget; - return highestPos + 1; + setInputMethodTarget(highestTarget, true, mInputMethodAnimLayerAdjustment); + return highestTarget; } } } - } - //Slog.i(TAG_WM, "Placing input method @" + (i+1)); - if (w != null) { - if (willMove) { - if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget + " to " - + w + (SHOW_STACK_CRAWLS ? " Callers=" + Debug.getCallers(4) : "")); - mService.mInputMethodTarget = w; - mService.mInputMethodTargetWaitingAnim = false; - if (w.mAppToken != null) { - setInputMethodAnimLayerAdjustment( - w.mAppToken.mAppAnimator.animLayerAdjustment); - } else { - setInputMethodAnimLayerAdjustment(0); - } - } - - // If the docked divider is visible, we still need to go through this whole excercise to - // find the appropriate input method target (used for animations and dialog - // adjustments), but for purposes of Z ordering we simply wish to place it above the - // docked divider. Unless it is already above the divider. - final WindowState dockedDivider = mDividerControllerLocked.getWindow(); - if (dockedDivider != null && dockedDivider.isVisibleLw()) { - int dividerIndex = mWindows.indexOf(dockedDivider); - if (dividerIndex > 0 && dividerIndex > i) { - return dividerIndex + 1; - } - } - return i+1; + if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget + " to " + + target + (SHOW_STACK_CRAWLS ? " Callers=" + Debug.getCallers(4) : "")); + setInputMethodTarget(target, false, target.mAppToken != null + ? target.mAppToken.mAppAnimator.animLayerAdjustment : 0); } - if (willMove) { - if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget - + " to null." + (SHOW_STACK_CRAWLS ? " Callers=" + Debug.getCallers(4) : "")); - mService.mInputMethodTarget = null; - setInputMethodAnimLayerAdjustment(0); - } - return -1; - } - private static boolean canBeImeTarget(WindowState w) { - final int fl = w.mAttrs.flags & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM); - final int type = w.mAttrs.type; + return target; + } - if (fl != 0 && fl != (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM) - && type != TYPE_APPLICATION_STARTING) { - return false; + private void setInputMethodTarget(WindowState target, boolean targetWaitingAnim, int layerAdj) { + if (target == mService.mInputMethodTarget + && mService.mInputMethodTargetWaitingAnim == targetWaitingAnim + && mInputMethodAnimLayerAdjustment == layerAdj) { + return; } - if (DEBUG_INPUT_METHOD) { - Slog.i(TAG_WM, "isVisibleOrAdding " + w + ": " + w.isVisibleOrAdding()); - if (!w.isVisibleOrAdding()) { - Slog.i(TAG_WM, " mSurfaceController=" + w.mWinAnimator.mSurfaceController - + " relayoutCalled=" + w.mRelayoutCalled - + " viewVis=" + w.mViewVisibility - + " policyVis=" + w.mPolicyVisibility - + " policyVisAfterAnim=" + w.mPolicyVisibilityAfterAnim - + " parentHidden=" + w.isParentWindowHidden() - + " exiting=" + w.mAnimatingExit + " destroying=" + w.mDestroying); - if (w.mAppToken != null) { - Slog.i(TAG_WM, " mAppToken.hiddenRequested=" + w.mAppToken.hiddenRequested); - } - } - } - return w.isVisibleOrAdding(); + mService.mInputMethodTarget = target; + mService.mInputMethodTargetWaitingAnim = targetWaitingAnim; + setInputMethodAnimLayerAdjustment(layerAdj); + assignWindowLayers(false /* setLayoutNeeded */); } - private void logWindowList(final WindowList windows, String prefix) { - int N = windows.size(); - while (N > 0) { - N--; - Slog.v(TAG_WM, prefix + "#" + N + ": " + windows.get(N)); + boolean getNeedsMenu(WindowState top, WindowManagerPolicy.WindowState bottom) { + if (top.mAttrs.needsMenuKey != NEEDS_MENU_UNSET) { + return top.mAttrs.needsMenuKey == NEEDS_MENU_SET_TRUE; } - } - boolean getNeedsMenu(WindowState win, WindowManagerPolicy.WindowState bottom) { - int index = -1; - while (true) { - if (win.mAttrs.needsMenuKey != NEEDS_MENU_UNSET) { - return win.mAttrs.needsMenuKey == NEEDS_MENU_SET_TRUE; + // Used to indicate we have reached the first window in the range we are interested in. + mTmpWindow = null; + + // TODO: Figure-out a more efficient way to do this. + final WindowState candidate = getWindow(w -> { + if (w == top) { + // Reached the first window in the range we are interested in. + mTmpWindow = w; } - // If we reached the bottom of the range of windows we are considering, - // assume no menu is needed. - if (win == bottom) { + if (mTmpWindow == null) { return false; } - // The current window hasn't specified whether menu key is needed; look behind it. - // First, we may need to determine the starting position. - if (index < 0) { - index = mWindows.indexOf(win); + + if (w.mAttrs.needsMenuKey != NEEDS_MENU_UNSET) { + return true; } - index--; - if (index < 0) { - return false; + // If we reached the bottom of the range of windows we are considering, + // assume no menu is needed. + if (w == bottom) { + return true; } - win = mWindows.get(index); - } + return false; + }); + + return candidate != null && candidate.mAttrs.needsMenuKey == NEEDS_MENU_SET_TRUE; } void setLayoutNeeded() { @@ -2047,85 +1344,6 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo return mLayoutNeeded; } - private void addAppWindowExisting(WindowState win, WindowList tokenWindowList) { - - // If this application has existing windows, we simply place the new window on top of - // them... but keep the starting window on top. - if (win.mAttrs.type == TYPE_BASE_APPLICATION) { - // Base windows go behind everything else. - final WindowState lowestWindow = tokenWindowList.get(0); - addWindowToListBefore(win, lowestWindow); - } else { - final AppWindowToken atoken = win.mAppToken; - final int windowListPos = tokenWindowList.size(); - final WindowState lastWindow = tokenWindowList.get(windowListPos - 1); - if (atoken != null && lastWindow == atoken.startingWindow) { - addWindowToListBefore(win, lastWindow); - } else { - int newIdx = findIdxBasedOnAppTokens(win); - // There is a window above this one associated with the same apptoken note that the - // window could be a floating window that was created later or a window at the top - // of the list of windows associated with this token. - if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM, - "not Base app: Adding window " + win + " at " + (newIdx + 1) + " of " - + mWindows.size()); - mWindows.add(newIdx + 1, win); - mService.mWindowsChanged = true; - } - } - } - - /** Places the first input window after the second input window in the window list. */ - private void addWindowToListAfter(WindowState first, WindowState second) { - final int i = mWindows.indexOf(second); - if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM, - "Adding window " + this + " at " + (i + 1) + " of " + mWindows.size() - + " (after " + second + ")"); - mWindows.add(i + 1, first); - mService.mWindowsChanged = true; - } - - /** Places the first input window before the second input window in the window list. */ - private void addWindowToListBefore(WindowState first, WindowState second) { - int i = mWindows.indexOf(second); - if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM, - "Adding window " + this + " at " + i + " of " + mWindows.size() - + " (before " + second + ")"); - if (i < 0) { - Slog.w(TAG_WM, "addWindowToListBefore: Unable to find " + second + " in " + mWindows); - i = 0; - } - mWindows.add(i, first); - mService.mWindowsChanged = true; - } - - /** - * This method finds out the index of a window that has the same app token as win. used for z - * ordering the windows in mWindows - */ - private int findIdxBasedOnAppTokens(WindowState win) { - for(int j = mWindows.size() - 1; j >= 0; j--) { - final WindowState wentry = mWindows.get(j); - if(wentry.mAppToken == win.mAppToken) { - return j; - } - } - return -1; - } - - private void dumpChildrenNames() { - StringBuilder output = new StringBuilder(); - dumpChildrenNames(output, " "); - Slog.v(TAG_WM, output.toString()); - } - - private void dumpWindows() { - Slog.v(TAG_WM, " Display #" + mDisplayId); - for (int winNdx = mWindows.size() - 1; winNdx >= 0; --winNdx) { - Slog.v(TAG_WM, " #" + winNdx + ": " + mWindows.get(winNdx)); - } - } - void dumpTokens(PrintWriter pw, boolean dumpAll) { if (mTokenMap.isEmpty()) { return; @@ -2146,25 +1364,24 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } void dumpWindowAnimators(PrintWriter pw, String subPrefix) { - final int count = mWindows.size(); - for (int j = 0; j < count; j++) { - final WindowStateAnimator wAnim = mWindows.get(j).mWinAnimator; - pw.println(subPrefix + "Window #" + j + ": " + wAnim); - } + final int[] index = new int[1]; + forAllWindows(w -> { + final WindowStateAnimator wAnim = w.mWinAnimator; + pw.println(subPrefix + "Window #" + index[0] + ": " + wAnim); + index[0] = index[0] + 1; + }, false /* traverseTopToBottom */); } void enableSurfaceTrace(FileDescriptor fd) { - for (int i = mWindows.size() - 1; i >= 0; i--) { - final WindowState win = mWindows.get(i); - win.mWinAnimator.enableSurfaceTrace(fd); - } + forAllWindows(w -> { + w.mWinAnimator.enableSurfaceTrace(fd); + }, true /* traverseTopToBottom */); } void disableSurfaceTrace() { - for (int i = mWindows.size() - 1; i >= 0; i--) { - final WindowState win = mWindows.get(i); - win.mWinAnimator.disableSurfaceTrace(); - } + forAllWindows(w -> { + w.mWinAnimator.disableSurfaceTrace(); + }, true /* traverseTopToBottom */); } /** @@ -2172,63 +1389,68 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo */ void startKeyguardExitOnNonAppWindows(boolean onWallpaper, boolean goingToShade) { final WindowManagerPolicy policy = mService.mPolicy; - for (int i = mWindows.size() - 1; i >= 0; i--) { - final WindowState window = mWindows.get(i); - if (window.mAppToken == null && policy.canBeHiddenByKeyguardLw(window)) { - window.mWinAnimator.setAnimation( + forAllWindows(w -> { + if (w.mAppToken == null && policy.canBeHiddenByKeyguardLw(w)) { + w.mWinAnimator.setAnimation( policy.createHiddenByKeyguardExit(onWallpaper, goingToShade)); } - } + }, true /* traverseTopToBottom */); } boolean checkWaitingForWindows() { - boolean haveBootMsg = false; - boolean haveApp = false; - // if the wallpaper service is disabled on the device, we're never going to have - // wallpaper, don't bother waiting for it - boolean haveWallpaper = false; - boolean wallpaperEnabled = mService.mContext.getResources().getBoolean( - com.android.internal.R.bool.config_enableWallpaperService) - && !mService.mOnlyCore; - boolean haveKeyguard = true; - final int count = mWindows.size(); - for (int i = 0; i < count; i++) { - final WindowState w = mWindows.get(i); + mHaveBootMsg = false; + mHaveApp = false; + mHaveWallpaper = false; + mHaveKeyguard = true; + + final WindowState visibleWindow = getWindow(w -> { if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) { return true; } if (w.isDrawnLw()) { if (w.mAttrs.type == TYPE_BOOT_PROGRESS) { - haveBootMsg = true; + mHaveBootMsg = true; } else if (w.mAttrs.type == TYPE_APPLICATION || w.mAttrs.type == TYPE_DRAWN_APPLICATION) { - haveApp = true; + mHaveApp = true; } else if (w.mAttrs.type == TYPE_WALLPAPER) { - haveWallpaper = true; + mHaveWallpaper = true; } else if (w.mAttrs.type == TYPE_STATUS_BAR) { - haveKeyguard = mService.mPolicy.isKeyguardDrawnLw(); + mHaveKeyguard = mService.mPolicy.isKeyguardDrawnLw(); } } + return false; + }); + + if (visibleWindow != null) { + // We have a visible window. + return true; } + // if the wallpaper service is disabled on the device, we're never going to have + // wallpaper, don't bother waiting for it + boolean wallpaperEnabled = mService.mContext.getResources().getBoolean( + com.android.internal.R.bool.config_enableWallpaperService) + && !mService.mOnlyCore; + if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG_WM, "******** booted=" + mService.mSystemBooted + " msg=" + mService.mShowingBootMessages - + " haveBoot=" + haveBootMsg + " haveApp=" + haveApp - + " haveWall=" + haveWallpaper + " wallEnabled=" + wallpaperEnabled - + " haveKeyguard=" + haveKeyguard); + + " haveBoot=" + mHaveBootMsg + " haveApp=" + mHaveApp + + " haveWall=" + mHaveWallpaper + " wallEnabled=" + wallpaperEnabled + + " haveKeyguard=" + mHaveKeyguard); // If we are turning on the screen to show the boot message, don't do it until the boot // message is actually displayed. - if (!mService.mSystemBooted && !haveBootMsg) { + if (!mService.mSystemBooted && !mHaveBootMsg) { return true; } // If we are turning on the screen after the boot is completed normally, don't do so until // we have the application and wallpaper. - if (mService.mSystemBooted && ((!haveApp && !haveKeyguard) || - (wallpaperEnabled && !haveWallpaper))) { + if (mService.mSystemBooted + && ((!mHaveApp && !mHaveKeyguard) || (wallpaperEnabled && !mHaveWallpaper))) { return true; } @@ -2236,10 +1458,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } void updateWindowsForAnimator(WindowAnimator animator) { - final WallpaperController wallpaperController = mWallpaperController; - for (int i = mWindows.size() - 1; i >= 0; i--) { - WindowState win = mWindows.get(i); - WindowStateAnimator winAnimator = win.mWinAnimator; + forAllWindows(w -> { + WindowStateAnimator winAnimator = w.mWinAnimator; if (winAnimator.hasSurface()) { final boolean wasAnimating = winAnimator.mWasAnimating; final boolean nowAnimating = winAnimator.stepAnimationLocked(animator.mCurrentTime); @@ -2247,10 +1467,10 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo animator.orAnimating(nowAnimating); if (DEBUG_WALLPAPER) Slog.v(TAG, - win + ": wasAnimating=" + wasAnimating + ", nowAnimating=" + nowAnimating); + w + ": wasAnimating=" + wasAnimating + ", nowAnimating=" + nowAnimating); if (wasAnimating && !winAnimator.mAnimating - && wallpaperController.isWallpaperTarget(win)) { + && mWallpaperController.isWallpaperTarget(w)) { animator.mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE; pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; if (DEBUG_LAYOUT_REPEATS) { @@ -2260,10 +1480,10 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } } - final AppWindowToken atoken = win.mAppToken; + final AppWindowToken atoken = w.mAppToken; if (winAnimator.mDrawState == READY_TO_SHOW) { if (atoken == null || atoken.allDrawn) { - if (win.performShowLocked()) { + if (w.performShowLocked()) { pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM; if (DEBUG_LAYOUT_REPEATS) { mService.mWindowPlacerLocked.debugLayoutRepeats( @@ -2282,23 +1502,22 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo appAnimator.thumbnailLayer = winAnimator.mAnimLayer; } } - } // end forall windows + }, true /* traverseTopToBottom */); } void updateWallpaperForAnimator(WindowAnimator animator) { resetAnimationBackgroundAnimator(); - final WindowList windows = mWindows; - WindowState detachedWallpaper = null; + // Used to indicate a detached wallpaper. + mTmpWindow = null; - for (int i = windows.size() - 1; i >= 0; i--) { - final WindowState win = windows.get(i); - final WindowStateAnimator winAnimator = win.mWinAnimator; + forAllWindows(w -> { + final WindowStateAnimator winAnimator = w.mWinAnimator; if (winAnimator.mSurfaceController == null || !winAnimator.hasSurface()) { - continue; + return; } - final int flags = win.mAttrs.flags; + final int flags = w.mAttrs.flags; // If this window is animating, make a note that we have an animating window and take // care of a request to run a detached wallpaper animation. @@ -2306,11 +1525,11 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo if (winAnimator.mAnimation != null) { if ((flags & FLAG_SHOW_WALLPAPER) != 0 && winAnimator.mAnimation.getDetachWallpaper()) { - detachedWallpaper = win; + mTmpWindow = w; } final int color = winAnimator.mAnimation.getBackgroundColor(); if (color != 0) { - final TaskStack stack = win.getStack(); + final TaskStack stack = w.getStack(); if (stack != null) { stack.setAnimationBackground(winAnimator, color); } @@ -2326,64 +1545,45 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo && appAnimator.animating) { if ((flags & FLAG_SHOW_WALLPAPER) != 0 && appAnimator.animation.getDetachWallpaper()) { - detachedWallpaper = win; + mTmpWindow = w; } final int color = appAnimator.animation.getBackgroundColor(); if (color != 0) { - final TaskStack stack = win.getStack(); + final TaskStack stack = w.getStack(); if (stack != null) { stack.setAnimationBackground(winAnimator, color); } } } - } // end forall windows + }, true /* traverseTopToBottom */); - if (animator.mWindowDetachedWallpaper != detachedWallpaper) { + if (animator.mWindowDetachedWallpaper != mTmpWindow) { if (DEBUG_WALLPAPER) Slog.v(TAG, "Detached wallpaper changed from " - + animator.mWindowDetachedWallpaper + " to " + detachedWallpaper); - animator.mWindowDetachedWallpaper = detachedWallpaper; + + animator.mWindowDetachedWallpaper + " to " + mTmpWindow); + animator.mWindowDetachedWallpaper = mTmpWindow; animator.mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE; } } void prepareWindowSurfaces() { - final int count = mWindows.size(); - for (int j = 0; j < count; j++) { - mWindows.get(j).mWinAnimator.prepareSurfaceLocked(true); - } + forAllWindows(w -> { + w.mWinAnimator.prepareSurfaceLocked(true); + }, false /* traverseTopToBottom */); } boolean inputMethodClientHasFocus(IInputMethodClient client) { - // The focus for the client is the window immediately below where we would place the input - // method window. - int idx = findDesiredInputMethodWindowIndex(false); - if (idx <= 0) { + final WindowState imFocus = computeImeTarget(false /* updateImeTarget */); + if (imFocus == null) { return false; } - WindowState imFocus = mWindows.get(idx - 1); if (DEBUG_INPUT_METHOD) { Slog.i(TAG_WM, "Desired input method target: " + imFocus); Slog.i(TAG_WM, "Current focus: " + mService.mCurrentFocus); Slog.i(TAG_WM, "Last focus: " + mService.mLastFocus); } - if (imFocus == null) { - return false; - } - - // This may be a starting window, in which case we still want to count it as okay. - if (imFocus.mAttrs.type == TYPE_APPLICATION_STARTING && imFocus.mAppToken != null) { - // The client has definitely started, so it really should have a window in this app - // token. Let's look for it. - final WindowState w = imFocus.mAppToken.getFirstNonStartingWindow(); - if (w != null) { - if (DEBUG_INPUT_METHOD) Slog.i(TAG_WM, "Switching to real app window: " + w); - imFocus = w; - } - } - final IInputMethodClient imeClient = imFocus.mSession.mClient; if (DEBUG_INPUT_METHOD) { @@ -2398,75 +1598,63 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } boolean hasSecureWindowOnScreen() { - for (int i = mWindows.size() - 1; i >= 0; --i) { - final WindowState ws = mWindows.get(i); - if (ws.isOnScreen() && (ws.mAttrs.flags & FLAG_SECURE) != 0) { - return true; - } - } - return false; + final WindowState win = getWindow( + w -> w.isOnScreen() && (w.mAttrs.flags & FLAG_SECURE) != 0); + return win != null; } void updateSystemUiVisibility(int visibility, int globalDiff) { - for (int i = mWindows.size() - 1; i >= 0; --i) { - final WindowState ws = mWindows.get(i); + forAllWindows(w -> { try { - int curValue = ws.mSystemUiVisibility; - int diff = (curValue ^ visibility) & globalDiff; - int newValue = (curValue & ~diff) | (visibility & diff); + final int curValue = w.mSystemUiVisibility; + final int diff = (curValue ^ visibility) & globalDiff; + final int newValue = (curValue & ~diff) | (visibility & diff); if (newValue != curValue) { - ws.mSeq++; - ws.mSystemUiVisibility = newValue; + w.mSeq++; + w.mSystemUiVisibility = newValue; } - if (newValue != curValue || ws.mAttrs.hasSystemUiListeners) { - ws.mClient.dispatchSystemUiVisibilityChanged(ws.mSeq, + if (newValue != curValue || w.mAttrs.hasSystemUiListeners) { + w.mClient.dispatchSystemUiVisibilityChanged(w.mSeq, visibility, newValue, diff); } } catch (RemoteException e) { // so sorry } - } + }, true /* traverseTopToBottom */); } void onWindowFreezeTimeout() { Slog.w(TAG_WM, "Window freeze timeout expired."); mService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_TIMEOUT; - for (int i = mWindows.size() - 1; i >= 0; --i) { - final WindowState w = mWindows.get(i); + + forAllWindows(w -> { if (!w.mOrientationChanging) { - continue; + return; } w.mOrientationChanging = false; w.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime() - mService.mDisplayFreezeTime); Slog.w(TAG_WM, "Force clearing orientation change: " + w); - } + }, true /* traverseTopToBottom */); mService.mWindowPlacerLocked.performSurfacePlacement(); } void waitForAllWindowsDrawn() { final WindowManagerPolicy policy = mService.mPolicy; - for (int winNdx = mWindows.size() - 1; winNdx >= 0; --winNdx) { - final WindowState win = mWindows.get(winNdx); - final boolean keyguard = policy.isKeyguardHostWindow(win.mAttrs); - if (win.isVisibleLw() && (win.mAppToken != null || keyguard)) { - win.mWinAnimator.mDrawState = DRAW_PENDING; + forAllWindows(w -> { + final boolean keyguard = policy.isKeyguardHostWindow(w.mAttrs); + if (w.isVisibleLw() && (w.mAppToken != null || keyguard)) { + w.mWinAnimator.mDrawState = DRAW_PENDING; // Force add to mResizingWindows. - win.mLastContentInsets.set(-1, -1, -1, -1); - mService.mWaitingForDrawn.add(win); + w.mLastContentInsets.set(-1, -1, -1, -1); + mService.mWaitingForDrawn.add(w); } - } + }, true /* traverseTopToBottom */); } // TODO: Super crazy long method that should be broken down... boolean applySurfaceChangesTransaction(boolean recoveringMemory) { - boolean focusDisplayed = false; - boolean displayHasContent = false; - float preferredRefreshRate = 0; - int preferredModeId = 0; - - final int dw = mDisplayInfo.logicalWidth; final int dh = mDisplayInfo.logicalHeight; final WindowSurfacePlacer surfacePlacer = mService.mWindowPlacerLocked; @@ -2490,7 +1678,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo // Remove check for default display when there will be support for multiple wallpaper // targets (on different displays). if (isDefaultDisplay && (pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0) { - adjustWallpaperWindows(); + mWallpaperController.adjustWallpaperWindows(this); } if (isDefaultDisplay && (pendingLayoutChanges & FINISH_LAYOUT_REDO_CONFIG) != 0) { @@ -2517,55 +1705,59 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo if (isDefaultDisplay) { mService.mPolicy.beginPostLayoutPolicyLw(dw, dh); - for (int i = mWindows.size() - 1; i >= 0; i--) { - final WindowState w = mWindows.get(i); + forAllWindows(w -> { mService.mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs, w.getParentWindow(), mService.mInputMethodTarget); - } + }, true /* traverseTopToBottom */); pendingLayoutChanges |= mService.mPolicy.finishPostLayoutPolicyLw(); if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats( "after finishPostLayoutPolicyLw", pendingLayoutChanges); } } while (pendingLayoutChanges != 0); - RootWindowContainer root = mService.mRoot; - boolean obscured = false; - boolean syswin = false; + final RootWindowContainer root = mService.mRoot; + mTmpApplySurfaceChangesTransactionState.reset(); resetDimming(); // Only used if default window final boolean someoneLosingFocus = !mService.mLosingFocus.isEmpty(); - for (int i = mWindows.size() - 1; i >= 0; i--) { - final WindowState w = mWindows.get(i); - final Task task = w.getTask(); - final boolean obscuredChanged = w.mObscured != obscured; + forAllWindows(w -> { + final boolean obscuredChanged = w.mObscured != + mTmpApplySurfaceChangesTransactionState.obscured; // Update effect. - w.mObscured = obscured; - if (!obscured) { + w.mObscured = mTmpApplySurfaceChangesTransactionState.obscured; + if (!mTmpApplySurfaceChangesTransactionState.obscured) { final boolean isDisplayed = w.isDisplayedLw(); if (isDisplayed && w.isObscuringFullscreen(mDisplayInfo)) { // This window completely covers everything behind it, so we want to leave all // of them as undimmed (for performance reasons). root.mObscuringWindow = w; - obscured = true; + mTmpApplySurfaceChangesTransactionState.obscured = true; } - displayHasContent |= root.handleNotObscuredLocked(w, obscured, syswin); + mTmpApplySurfaceChangesTransactionState.displayHasContent |= + root.handleNotObscuredLocked(w, + mTmpApplySurfaceChangesTransactionState.obscured, + mTmpApplySurfaceChangesTransactionState.syswin); if (w.mHasSurface && isDisplayed) { final int type = w.mAttrs.type; if (type == TYPE_SYSTEM_DIALOG || type == TYPE_SYSTEM_ERROR || (w.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) { - syswin = true; + mTmpApplySurfaceChangesTransactionState.syswin = true; } - if (preferredRefreshRate == 0 && w.mAttrs.preferredRefreshRate != 0) { - preferredRefreshRate = w.mAttrs.preferredRefreshRate; + if (mTmpApplySurfaceChangesTransactionState.preferredRefreshRate == 0 + && w.mAttrs.preferredRefreshRate != 0) { + mTmpApplySurfaceChangesTransactionState.preferredRefreshRate + = w.mAttrs.preferredRefreshRate; } - if (preferredModeId == 0 && w.mAttrs.preferredDisplayModeId != 0) { - preferredModeId = w.mAttrs.preferredDisplayModeId; + if (mTmpApplySurfaceChangesTransactionState.preferredModeId == 0 + && w.mAttrs.preferredDisplayModeId != 0) { + mTmpApplySurfaceChangesTransactionState.preferredModeId + = w.mAttrs.preferredDisplayModeId; } } } @@ -2638,16 +1830,16 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo if (isDefaultDisplay && someoneLosingFocus && w == mService.mCurrentFocus && w.isDisplayedLw()) { - focusDisplayed = true; + mTmpApplySurfaceChangesTransactionState.focusDisplayed = true; } w.updateResizingWindowIfNeeded(); - } + }, true /* traverseTopToBottom */); mService.mDisplayManagerInternal.setDisplayProperties(mDisplayId, - displayHasContent, - preferredRefreshRate, - preferredModeId, + mTmpApplySurfaceChangesTransactionState.displayHasContent, + mTmpApplySurfaceChangesTransactionState.preferredRefreshRate, + mTmpApplySurfaceChangesTransactionState.preferredModeId, true /* inTraversal, must call performTraversalInTrans... below */); stopDimmingIfNeeded(); @@ -2659,7 +1851,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo atoken.updateAllDrawn(this); } - return focusDisplayed; + return mTmpApplySurfaceChangesTransactionState.focusDisplayed; } void performLayout(boolean initial, boolean updateInputWindows) { @@ -2692,110 +1884,110 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo if (seq < 0) seq = 0; mService.mLayoutSeq = seq; - boolean behindDream = false; + // Used to indicate that we have processed the dream window and all additional windows are + // behind it. + mTmpWindow = null; // First perform layout of any root windows (not attached to another window). - int topAttached = -1; - for (i = mWindows.size() - 1; i >= 0; i--) { - final WindowState win = mWindows.get(i); - + forAllWindows(w -> { // Don't do layout of a window if it is not visible, or soon won't be visible, to avoid // wasting time and funky changes while a window is animating away. - final boolean gone = (behindDream && mService.mPolicy.canBeHiddenByKeyguardLw(win)) - || win.isGoneForLayoutLw(); - - if (DEBUG_LAYOUT && !win.mLayoutAttached) { - Slog.v(TAG, "1ST PASS " + win + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame - + " mLayoutAttached=" + win.mLayoutAttached - + " screen changed=" + win.isConfigChanged()); - final AppWindowToken atoken = win.mAppToken; - if (gone) Slog.v(TAG, " GONE: mViewVisibility=" + win.mViewVisibility - + " mRelayoutCalled=" + win.mRelayoutCalled + " hidden=" + win.mToken.hidden + final boolean gone = (mTmpWindow != null && mService.mPolicy.canBeHiddenByKeyguardLw(w)) + || w.isGoneForLayoutLw(); + + if (DEBUG_LAYOUT && !w.mLayoutAttached) { + Slog.v(TAG, "1ST PASS " + w + ": gone=" + gone + " mHaveFrame=" + w.mHaveFrame + + " mLayoutAttached=" + w.mLayoutAttached + + " screen changed=" + w.isConfigChanged()); + final AppWindowToken atoken = w.mAppToken; + if (gone) Slog.v(TAG, " GONE: mViewVisibility=" + w.mViewVisibility + + " mRelayoutCalled=" + w.mRelayoutCalled + " hidden=" + w.mToken.hidden + " hiddenRequested=" + (atoken != null && atoken.hiddenRequested) - + " parentHidden=" + win.isParentWindowHidden()); - else Slog.v(TAG, " VIS: mViewVisibility=" + win.mViewVisibility - + " mRelayoutCalled=" + win.mRelayoutCalled + " hidden=" + win.mToken.hidden + + " parentHidden=" + w.isParentWindowHidden()); + else Slog.v(TAG, " VIS: mViewVisibility=" + w.mViewVisibility + + " mRelayoutCalled=" + w.mRelayoutCalled + " hidden=" + w.mToken.hidden + " hiddenRequested=" + (atoken != null && atoken.hiddenRequested) - + " parentHidden=" + win.isParentWindowHidden()); + + " parentHidden=" + w.isParentWindowHidden()); } // If this view is GONE, then skip it -- keep the current frame, and let the caller know // so they can ignore it if they want. (We do the normal layout for INVISIBLE windows, // since that means "perform layout as normal, just don't display"). - if (!gone || !win.mHaveFrame || win.mLayoutNeeded - || ((win.isConfigChanged() || win.setReportResizeHints()) - && !win.isGoneForLayoutLw() && - ((win.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 || - (win.mHasSurface && win.mAppToken != null && - win.mAppToken.layoutConfigChanges)))) { - if (!win.mLayoutAttached) { + if (!gone || !w.mHaveFrame || w.mLayoutNeeded + || ((w.isConfigChanged() || w.setReportResizeHints()) + && !w.isGoneForLayoutLw() && + ((w.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 || + (w.mHasSurface && w.mAppToken != null && + w.mAppToken.layoutConfigChanges)))) { + if (!w.mLayoutAttached) { if (initial) { //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial"); - win.mContentChanged = false; + w.mContentChanged = false; } - if (win.mAttrs.type == TYPE_DREAM) { + if (w.mAttrs.type == TYPE_DREAM) { // Don't layout windows behind a dream, so that if it does stuff like hide // the status bar we won't get a bad transition when it goes away. - behindDream = true; + mTmpWindow = w; } - win.mLayoutNeeded = false; - win.prelayout(); - mService.mPolicy.layoutWindowLw(win, null); - win.mLayoutSeq = seq; + w.mLayoutNeeded = false; + w.prelayout(); + mService.mPolicy.layoutWindowLw(w, null); + w.mLayoutSeq = mService.mLayoutSeq; // Window frames may have changed. Update dim layer with the new bounds. - final Task task = win.getTask(); + final Task task = w.getTask(); if (task != null) { mDimLayerController.updateDimLayer(task); } - if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame=" + win.mFrame - + " mContainingFrame=" + win.mContainingFrame - + " mDisplayFrame=" + win.mDisplayFrame); - } else { - if (topAttached < 0) topAttached = i; + if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame=" + w.mFrame + + " mContainingFrame=" + w.mContainingFrame + + " mDisplayFrame=" + w.mDisplayFrame); } } - } + }, true /* traverseTopToBottom */); - boolean attachedBehindDream = false; + // Used to indicate that we have processed the dream window and all additional attached + // windows are behind it. + final WindowState dreamWin = mTmpWindow; + mTmpWindow = null; // Now perform layout of attached windows, which usually depend on the position of the // window they are attached to. XXX does not deal with windows that are attached to windows // that are themselves attached. - for (i = topAttached; i >= 0; i--) { - final WindowState win = mWindows.get(i); - - if (win.mLayoutAttached) { - if (DEBUG_LAYOUT) Slog.v(TAG, "2ND PASS " + win + " mHaveFrame=" + win.mHaveFrame - + " mViewVisibility=" + win.mViewVisibility - + " mRelayoutCalled=" + win.mRelayoutCalled); - // If this view is GONE, then skip it -- keep the current frame, and let the caller - // know so they can ignore it if they want. (We do the normal layout for INVISIBLE - // windows, since that means "perform layout as normal, just don't display"). - if (attachedBehindDream && mService.mPolicy.canBeHiddenByKeyguardLw(win)) { - continue; - } - if ((win.mViewVisibility != GONE && win.mRelayoutCalled) || !win.mHaveFrame - || win.mLayoutNeeded) { + forAllWindows(w -> { + if (w.mLayoutAttached) { + if (DEBUG_LAYOUT) Slog.v(TAG, "2ND PASS " + w + " mHaveFrame=" + w.mHaveFrame + + " mViewVisibility=" + w.mViewVisibility + + " mRelayoutCalled=" + w.mRelayoutCalled); + // If this view is GONE, then skip it -- keep the current frame, and let the + // caller know so they can ignore it if they want. (We do the normal layout for + // INVISIBLE windows, since that means "perform layout as normal, just don't + // display"). + if (mTmpWindow != null && mService.mPolicy.canBeHiddenByKeyguardLw(w)) { + return; + } + if ((w.mViewVisibility != GONE && w.mRelayoutCalled) || !w.mHaveFrame + || w.mLayoutNeeded) { if (initial) { //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial"); - win.mContentChanged = false; + w.mContentChanged = false; } - win.mLayoutNeeded = false; - win.prelayout(); - mService.mPolicy.layoutWindowLw(win, win.getParentWindow()); - win.mLayoutSeq = seq; - if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame=" + win.mFrame - + " mContainingFrame=" + win.mContainingFrame - + " mDisplayFrame=" + win.mDisplayFrame); - } - } else if (win.mAttrs.type == TYPE_DREAM) { + w.mLayoutNeeded = false; + w.prelayout(); + mService.mPolicy.layoutWindowLw(w, w.getParentWindow()); + w.mLayoutSeq = mService.mLayoutSeq; + if (DEBUG_LAYOUT) + Slog.v(TAG, " LAYOUT: mFrame=" + w.mFrame + + " mContainingFrame=" + w.mContainingFrame + + " mDisplayFrame=" + w.mDisplayFrame); + } + } else if (w.mAttrs.type == TYPE_DREAM) { // Don't layout windows behind a dream, so that if it does stuff like hide the // status bar we won't get a bad transition when it goes away. - attachedBehindDream = behindDream; + mTmpWindow = dreamWin; } - } + }, true /* traverseTopToBottom */); // Window frames may have changed. Tell the input dispatcher about it. mService.mInputMonitor.layoutInputConsumers(dw, dh); @@ -2819,7 +2011,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo * @param config of the output bitmap * @param wallpaperOnly true if only the wallpaper layer should be included in the screenshot */ - Bitmap screenshotApplications(IBinder appToken, int displayId, int width, int height, + Bitmap screenshotApplications(IBinder appToken, int width, int height, boolean includeFullDisplay, float frameScale, Bitmap.Config config, boolean wallpaperOnly) { int dw = mDisplayInfo.logicalWidth; @@ -2832,22 +2024,10 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo Bitmap bm = null; - int maxLayer = 0; + mScreenshotApplicationState.reset(appToken == null && !wallpaperOnly); final Rect frame = new Rect(); final Rect stackBounds = new Rect(); - boolean screenshotReady; - int minLayer; - if (appToken == null && !wallpaperOnly) { - screenshotReady = true; - minLayer = 0; - } else { - screenshotReady = false; - minLayer = Integer.MAX_VALUE; - } - - WindowState appWin = null; - boolean includeImeInScreenshot; synchronized(mService.mWindowMap) { final AppWindowToken imeTargetAppToken = mService.mInputMethodTarget != null @@ -2868,70 +2048,69 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo synchronized(mService.mWindowMap) { // Figure out the part of the screen that is actually the app. - appWin = null; - for (int i = mWindows.size() - 1; i >= 0; i--) { - final WindowState ws = mWindows.get(i); - if (!ws.mHasSurface) { - continue; + mScreenshotApplicationState.appWin = null; + forAllWindows(w -> { + if (!w.mHasSurface) { + return false; } - if (ws.mLayer >= aboveAppLayer) { - continue; + if (w.mLayer >= aboveAppLayer) { + return false; } - if (wallpaperOnly && !ws.mIsWallpaper) { - continue; + if (wallpaperOnly && !w.mIsWallpaper) { + return false; } - if (ws.mIsImWindow) { + if (w.mIsImWindow) { if (!includeImeInScreenshot) { - continue; + return false; } - } else if (ws.mIsWallpaper) { + } else if (w.mIsWallpaper) { // If this is the wallpaper layer and we're only looking for the wallpaper layer // then the target window state is this one. if (wallpaperOnly) { - appWin = ws; + mScreenshotApplicationState.appWin = w; } - if (appWin == null) { + if (mScreenshotApplicationState.appWin == null) { // We have not ran across the target window yet, so it is probably behind // the wallpaper. This can happen when the keyguard is up and all windows // are moved behind the wallpaper. We don't want to include the wallpaper // layer in the screenshot as it will cover-up the layer of the target // window. - continue; + return false; } // Fall through. The target window is in front of the wallpaper. For this // case we want to include the wallpaper layer in the screenshot because // the target window might have some transparent areas. } else if (appToken != null) { - if (ws.mAppToken == null || ws.mAppToken.token != appToken) { + if (w.mAppToken == null || w.mAppToken.token != appToken) { // This app window is of no interest if it is not associated with the // screenshot app. - continue; + return false; } - appWin = ws; + mScreenshotApplicationState.appWin = w; } // Include this window. - final WindowStateAnimator winAnim = ws.mWinAnimator; + final WindowStateAnimator winAnim = w.mWinAnimator; int layer = winAnim.mSurfaceController.getLayer(); - if (maxLayer < layer) { - maxLayer = layer; + if (mScreenshotApplicationState.maxLayer < layer) { + mScreenshotApplicationState.maxLayer = layer; } - if (minLayer > layer) { - minLayer = layer; + if (mScreenshotApplicationState.minLayer > layer) { + mScreenshotApplicationState.minLayer = layer; } // Don't include wallpaper in bounds calculation - if (!includeFullDisplay && !ws.mIsWallpaper) { - final Rect wf = ws.mFrame; - final Rect cr = ws.mContentInsets; + if (!includeFullDisplay && !w.mIsWallpaper) { + final Rect wf = w.mFrame; + final Rect cr = w.mContentInsets; int left = wf.left + cr.left; int top = wf.top + cr.top; int right = wf.right - cr.right; int bottom = wf.bottom - cr.bottom; frame.union(left, top, right, bottom); - ws.getVisibleBounds(stackBounds); + w.getVisibleBounds(stackBounds); if (!Rect.intersects(frame, stackBounds)) { // Set frame empty if there's no intersection. frame.setEmpty(); @@ -2939,16 +2118,22 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } final boolean foundTargetWs = - (ws.mAppToken != null && ws.mAppToken.token == appToken) - || (appWin != null && wallpaperOnly); - if (foundTargetWs && ws.isDisplayedLw() && winAnim.getShown()) { - screenshotReady = true; + (w.mAppToken != null && w.mAppToken.token == appToken) + || (mScreenshotApplicationState.appWin != null && wallpaperOnly); + if (foundTargetWs && w.isDisplayedLw() && winAnim.getShown()) { + mScreenshotApplicationState.screenshotReady = true; } - if (ws.isObscuringFullscreen(mDisplayInfo)){ - break; + if (w.isObscuringFullscreen(mDisplayInfo)){ + return true; } - } + return false; + }, true /* traverseTopToBottom */); + + final WindowState appWin = mScreenshotApplicationState.appWin; + final boolean screenshotReady = mScreenshotApplicationState.screenshotReady; + final int maxLayer = mScreenshotApplicationState.maxLayer; + final int minLayer = mScreenshotApplicationState.minLayer; if (appToken != null && appWin == null) { // Can't find a window to snapshot. @@ -3020,14 +2205,13 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo if (DEBUG_SCREENSHOT) { Slog.i(TAG_WM, "Screenshot: " + dw + "x" + dh + " from " + minLayer + " to " + maxLayer + " appToken=" + appToken); - for (int i = 0; i < mWindows.size(); i++) { - final WindowState win = mWindows.get(i); - final WindowSurfaceController controller = win.mWinAnimator.mSurfaceController; - Slog.i(TAG_WM, win + ": " + win.mLayer - + " animLayer=" + win.mWinAnimator.mAnimLayer + forAllWindows(w -> { + final WindowSurfaceController controller = w.mWinAnimator.mSurfaceController; + Slog.i(TAG_WM, w + ": " + w.mLayer + + " animLayer=" + w.mWinAnimator.mAnimLayer + " surfaceLayer=" + ((controller == null) ? "null" : controller.getLayer())); - } + }, false /* traverseTopToBottom */); } final ScreenRotationAnimation screenRotationAnimation = @@ -3064,6 +2248,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } } if (allBlack) { + final WindowState appWin = mScreenshotApplicationState.appWin; + final int maxLayer = mScreenshotApplicationState.maxLayer; + final int minLayer = mScreenshotApplicationState.minLayer; Slog.i(TAG_WM, "Screenshot " + appWin + " was monochrome(" + Integer.toHexString(firstColor) + ")! mSurfaceLayer=" + (appWin != null ? @@ -3104,32 +2291,23 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } void onSeamlessRotationTimeout() { - boolean layoutNeeded = false; - for (int i = mWindows.size() - 1; i >= 0; i--) { - final WindowState w = mWindows.get(i); + // Used to indicate the layout is needed. + mTmpWindow = null; + + forAllWindows(w -> { if (!w.mSeamlesslyRotated) { - continue; + return; } - layoutNeeded = true; + mTmpWindow = w; w.setDisplayLayoutNeeded(); mService.markForSeamlessRotation(w, false); - } + }, true /* traverseTopToBottom */); - if (layoutNeeded) { + if (mTmpWindow != null) { mService.mWindowPlacerLocked.performSurfacePlacement(); } } - static final class GetWindowOnDisplaySearchResult { - boolean reachedToken; - WindowState foundWindow; - - void reset() { - reachedToken = false; - foundWindow = null; - } - } - static final class TaskForResizePointSearchResult { boolean searchDone; Task taskForResize; @@ -3140,6 +2318,39 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } } + private static final class ApplySurfaceChangesTransactionState { + boolean displayHasContent; + boolean obscured; + boolean syswin; + boolean focusDisplayed; + float preferredRefreshRate; + int preferredModeId; + + void reset() { + displayHasContent = false; + obscured = false; + syswin = false; + focusDisplayed = false; + preferredRefreshRate = 0; + preferredModeId = 0; + } + } + + private static final class ScreenshotApplicationState { + WindowState appWin; + int maxLayer; + int minLayer; + boolean screenshotReady; + + void reset(boolean screenshotReady) { + appWin = null; + maxLayer = 0; + minLayer = 0; + this.screenshotReady = screenshotReady; + minLayer = (screenshotReady) ? 0 : Integer.MAX_VALUE; + } + } + /** * Base class for any direct child window container of {@link #DisplayContent} need to inherit * from. This is mainly a pass through class that allows {@link #DisplayContent} to have @@ -3192,15 +2403,6 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo void removeStackFromDisplay(TaskStack stack) { removeChild(stack); stack.onRemovedFromDisplay(); - // TODO: remove when window list will be gone. - // Manually remove records from window list and tap excluded windows list. - for (int i = mWindows.size() - 1; i >= 0; --i) { - final WindowState windowState = mWindows.get(i); - if (stack == windowState.getStack()) { - mWindows.remove(i); - mTapExcludedWindows.remove(windowState); - } - } } void moveStack(TaskStack stack, boolean toTop) { @@ -3345,6 +2547,40 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo } @Override + int getOrientation() { + final WindowManagerPolicy policy = mService.mPolicy; + // Find a window requesting orientation. + final WindowState win = getWindow((w) -> { + if (!w.isVisibleLw() || !w.mPolicyVisibilityAfterAnim) { + return false; + } + final int req = w.mAttrs.screenOrientation; + if(req == SCREEN_ORIENTATION_UNSPECIFIED || req == SCREEN_ORIENTATION_BEHIND + || req == SCREEN_ORIENTATION_UNSET) { + return false; + } + return true; + }); + + if (win != null) { + final int req = win.mAttrs.screenOrientation; + if (DEBUG_ORIENTATION) Slog.v(TAG_WM, win + " forcing orientation to " + req); + if (policy.isKeyguardHostWindow(win.mAttrs)) { + mService.mLastKeyguardForcedOrientation = req; + } + return (mService.mLastWindowForcedOrientation = req); + } + + mService.mLastWindowForcedOrientation = SCREEN_ORIENTATION_UNSPECIFIED; + + if (policy.isKeyguardShowingAndNotOccluded()) { + return mService.mLastKeyguardForcedOrientation; + } + + return SCREEN_ORIENTATION_UNSET; + } + + @Override String getName() { return mName; } diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java index 12c72e9e0795..01d1c30ec0de 100644 --- a/services/core/java/com/android/server/wm/InputMonitor.java +++ b/services/core/java/com/android/server/wm/InputMonitor.java @@ -16,10 +16,15 @@ package com.android.server.wm; +import static android.app.ActivityManager.StackId.PINNED_STACK_ID; import static android.view.Display.DEFAULT_DISPLAY; +import static android.view.WindowManager.INPUT_CONSUMER_NAVIGATION; import static android.view.WindowManager.INPUT_CONSUMER_PIP; import static android.view.WindowManager.INPUT_CONSUMER_WALLPAPER; import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; +import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS; +import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD; +import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT; @@ -70,6 +75,10 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks { // Array of window handles to provide to the input dispatcher. private InputWindowHandle[] mInputWindowHandles; private int mInputWindowHandleCount; + private boolean mAddInputConsumerHandle; + private boolean mAddPipInputConsumerHandle; + private boolean mAddWallpaperInputConsumerHandle; + private boolean mDisableWallpaperTouchEvents; // Set to true when the first input device configuration change notification // is received to indicate that the input devices are ready. @@ -323,12 +332,12 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks { } } - public void setUpdateInputWindowsNeededLw() { + void setUpdateInputWindowsNeededLw() { mUpdateInputWindowsNeeded = true; } /* Updates the cached window information provided to the input dispatcher. */ - public void updateInputWindowsLw(boolean force) { + void updateInputWindowsLw(boolean force) { if (!force && !mUpdateInputWindowsNeeded) { return; } @@ -372,15 +381,92 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks { } // Add all windows on the default display. - mService.mRoot.updateInputWindows(this, mInputFocus, inDrag); + updateInputWindows(inDrag); - // Send windows to native code. - mService.mInputManager.setInputWindows(mInputWindowHandles); + if (false) Slog.d(TAG_WM, "<<<<<<< EXITED updateInputWindowsLw"); + } + + private void updateInputWindows(boolean inDrag) { - // Clear the list in preparation for the next round. clearInputWindowHandlesLw(); - if (false) Slog.d(TAG_WM, "<<<<<<< EXITED updateInputWindowsLw"); + // TODO: multi-display + final InputConsumerImpl navInputConsumer = + getInputConsumer(INPUT_CONSUMER_NAVIGATION, DEFAULT_DISPLAY); + final InputConsumerImpl pipInputConsumer = + getInputConsumer(INPUT_CONSUMER_PIP, DEFAULT_DISPLAY); + final InputConsumerImpl wallpaperInputConsumer = + getInputConsumer(INPUT_CONSUMER_WALLPAPER, DEFAULT_DISPLAY); + mAddInputConsumerHandle = navInputConsumer != null; + mAddPipInputConsumerHandle = pipInputConsumer != null; + mAddWallpaperInputConsumerHandle = wallpaperInputConsumer != null; + final Rect pipTouchableBounds = mAddPipInputConsumerHandle ? new Rect() : null; + mDisableWallpaperTouchEvents = false; + + final WallpaperController wallpaperController = mService.mRoot.mWallpaperController; + mService.mRoot.forAllWindows(w -> { + final InputChannel inputChannel = w.mInputChannel; + final InputWindowHandle inputWindowHandle = w.mInputWindowHandle; + if (inputChannel == null || inputWindowHandle == null || w.mRemoved + || w.isAdjustedForMinimizedDock()) { + // Skip this window because it cannot possibly receive input. + return; + } + + if (mAddPipInputConsumerHandle + && w.getStackId() == PINNED_STACK_ID + && inputWindowHandle.layer <= pipInputConsumer.mWindowHandle.layer) { + // Update the bounds of the Pip input consumer to match the Pinned stack + w.getStack().getBounds(pipTouchableBounds); + pipInputConsumer.mWindowHandle.touchableRegion.set(pipTouchableBounds); + addInputWindowHandle(pipInputConsumer.mWindowHandle); + mAddPipInputConsumerHandle = false; + } + + if (mAddInputConsumerHandle + && inputWindowHandle.layer <= navInputConsumer.mWindowHandle.layer) { + addInputWindowHandle(navInputConsumer.mWindowHandle); + mAddInputConsumerHandle = false; + } + + if (mAddWallpaperInputConsumerHandle) { + if (w.mAttrs.type == TYPE_WALLPAPER && w.isVisibleLw()) { + // Add the wallpaper input consumer above the first visible wallpaper. + addInputWindowHandle(wallpaperInputConsumer.mWindowHandle); + mAddWallpaperInputConsumerHandle = false; + } + } + + final int flags = w.mAttrs.flags; + final int privateFlags = w.mAttrs.privateFlags; + final int type = w.mAttrs.type; + + final boolean hasFocus = w == mInputFocus; + final boolean isVisible = w.isVisibleLw(); + if ((privateFlags & PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS) != 0) { + mDisableWallpaperTouchEvents = true; + } + final boolean hasWallpaper = wallpaperController.isWallpaperTarget(w) + && (privateFlags & PRIVATE_FLAG_KEYGUARD) == 0 + && !mDisableWallpaperTouchEvents; + + // If there's a drag in progress and 'child' is a potential drop target, + // make sure it's been told about the drag + if (inDrag && isVisible && w.getDisplayContent().isDefaultDisplay) { + mService.mDragState.sendDragStartedIfNeededLw(w); + } + + addInputWindowHandle( + inputWindowHandle, w, flags, type, isVisible, hasFocus, hasWallpaper); + }, true /* traverseTopToBottom */); + + if (mAddWallpaperInputConsumerHandle) { + // No visible wallpaper found, add the wallpaper input consumer at the end. + addInputWindowHandle(wallpaperInputConsumer.mWindowHandle); + } + + // Send windows to native code. + mService.mInputManager.setInputWindows(mInputWindowHandles); } /* Notifies that the input device configuration has changed. */ diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 88986e33894a..1962ca738892 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -219,7 +219,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> { return false; } - void getWindowsByName(WindowList output, String name) { + void getWindowsByName(ArrayList<WindowState> output, String name) { int objectId = 0; // See if this is an object ID. try { @@ -231,7 +231,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> { getWindowsByName(output, name, objectId); } - private void getWindowsByName(WindowList output, String name, int objectId) { + private void getWindowsByName(ArrayList<WindowState> output, String name, int objectId) { forAllWindows((w) -> { if (name != null) { if (w.mAttrs.getTitle().toString().contains(name)) { @@ -276,15 +276,6 @@ class RootWindowContainer extends WindowContainer<DisplayContent> { return null; } - // TODO: Users would have their own window containers under the display container? - void switchUser() { - final int count = mChildren.size(); - for (int i = 0; i < count; ++i) { - final DisplayContent dc = mChildren.get(i); - dc.switchUser(); - } - } - /** * Set new display override config and return array of ids of stacks that were changed during * update. If called for the default display, global configuration will also be updated. @@ -429,14 +420,6 @@ class RootWindowContainer extends WindowContainer<DisplayContent> { return hasChanges; } - void updateInputWindows(InputMonitor inputMonitor, WindowState inputFocus, boolean inDrag) { - final int count = mChildren.size(); - for (int i = 0; i < count; ++i) { - final DisplayContent dc = mChildren.get(i); - dc.updateInputWindows(inputMonitor, inputFocus, inDrag); - } - } - boolean reclaimSomeSurfaceMemory(WindowStateAnimator winAnimator, String operation, boolean secure) { final WindowSurfaceController surfaceController = winAnimator.mSurfaceController; diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index b889db230208..772833c8ff4f 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -589,46 +589,6 @@ class Task extends WindowContainer<AppWindowToken> implements DimLayer.DimLayerU } } - void getWindowOnDisplayBeforeToken(DisplayContent dc, WindowToken token, - DisplayContent.GetWindowOnDisplaySearchResult result) { - for (int i = mChildren.size() - 1; i >= 0; --i) { - final AppWindowToken current = mChildren.get(i); - if (current == token) { - // We have reach the token we are interested in. End search. - result.reachedToken = true; - return; - } - - // We haven't reached the token yet; if this token is not going to the bottom and - // has windows on this display, then it is a candidate for what we are looking for. - final WindowList tokenWindowList = dc.getTokenWindowsOnDisplay(current); - if (!current.sendingToBottom && tokenWindowList.size() > 0) { - result.foundWindow = tokenWindowList.get(0); - } - } - } - - void getWindowOnDisplayAfterToken(DisplayContent dc, WindowToken token, - DisplayContent.GetWindowOnDisplaySearchResult result) { - for (int i = mChildren.size() - 1; i >= 0; --i) { - final AppWindowToken current = mChildren.get(i); - if (!result.reachedToken) { - if (current == token) { - // We have reached the token we are interested in. Get whichever window occurs - // after it that is on the same display. - result.reachedToken = true; - } - continue; - } - - final WindowList tokenWindowList = dc.getTokenWindowsOnDisplay(current); - if (tokenWindowList.size() > 0) { - result.foundWindow = tokenWindowList.get(tokenWindowList.size() - 1); - return; - } - } - } - @Override boolean fillsParent() { return mFillsParent || !StackId.isTaskResizeAllowed(mStack.mStackId); diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java index 203ba72ca144..f2c74dffe423 100644 --- a/services/core/java/com/android/server/wm/TaskStack.java +++ b/services/core/java/com/android/server/wm/TaskStack.java @@ -859,7 +859,9 @@ public class TaskStack extends WindowContainer<Task> implements DimLayer.DimLaye } // TODO: Should each user have there own stacks? + @Override void switchUser() { + super.switchUser(); int top = mChildren.size(); for (int taskNdx = 0; taskNdx < top; ++taskNdx) { Task task = mChildren.get(taskNdx); @@ -1488,30 +1490,6 @@ public class TaskStack extends WindowContainer<Task> implements DimLayer.DimLaye } } - void getWindowOnDisplayBeforeToken(DisplayContent dc, WindowToken token, - DisplayContent.GetWindowOnDisplaySearchResult result) { - for (int i = mChildren.size() - 1; i >= 0; --i) { - final Task task = mChildren.get(i); - task.getWindowOnDisplayBeforeToken(dc, token, result); - if (result.reachedToken) { - // We have reach the token we are interested in. End search. - return; - } - } - } - - void getWindowOnDisplayAfterToken(DisplayContent dc, WindowToken token, - DisplayContent.GetWindowOnDisplaySearchResult result) { - for (int i = mChildren.size() - 1; i >= 0; --i) { - final Task task = mChildren.get(i); - task.getWindowOnDisplayAfterToken(dc, token, result); - if (result.foundWindow != null) { - // We have found a window after the token. End search. - return; - } - } - } - @Override int getOrientation() { return (StackId.canSpecifyOrientation(mStackId)) diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java index 8dbf2b3e019f..7fd8028a9c13 100644 --- a/services/core/java/com/android/server/wm/WallpaperController.java +++ b/services/core/java/com/android/server/wm/WallpaperController.java @@ -683,24 +683,6 @@ class WallpaperController { } } - void dumpTokens(PrintWriter pw, String prefix, boolean dumpAll) { - if (!mWallpaperTokens.isEmpty()) { - pw.println(); - pw.print(prefix); pw.println("Wallpaper tokens:"); - for (int i = mWallpaperTokens.size() - 1; i >= 0; i--) { - WindowToken token = mWallpaperTokens.get(i); - pw.print(prefix); pw.print("Wallpaper #"); pw.print(i); - pw.print(' '); pw.print(token); - if (dumpAll) { - pw.println(':'); - token.dump(pw, " "); - } else { - pw.println(); - } - } - } - } - /** Helper class for storing the results of a wallpaper target find operation. */ final private static class FindWallpaperTargetResult { WindowState topWallpaper = null; diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index a6a907cd50fb..f5db0b668c22 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -18,7 +18,6 @@ package com.android.server.wm; import android.annotation.CallSuper; import android.content.res.Configuration; -import android.view.animation.Animation; import com.android.internal.util.ToBooleanFunction; import java.util.Comparator; @@ -483,19 +482,11 @@ class WindowContainer<E extends WindowContainer> implements Comparable<WindowCon return false; } - /** - * Rebuilds the WindowList for the input display content. - * @param addIndex The index in the window list to add the next entry to. - * @return The next index in the window list to. - */ - // TODO: Hoping we can get rid of WindowList so this method wouldn't be needed. - int rebuildWindowList(int addIndex) { - final int count = mChildren.size(); - for (int i = 0; i < count; i++) { - final WindowContainer wc = mChildren.get(i); - addIndex = wc.rebuildWindowList(addIndex); + // TODO: Users would have their own window containers under the display container? + void switchUser() { + for (int i = mChildren.size() - 1; i >= 0; --i) { + mChildren.get(i).switchUser(); } - return addIndex; } /** diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 00d8fba09a58..507679bedd4c 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -606,17 +606,6 @@ public class WindowManagerService extends IWindowManager.Stub boolean mInputMethodTargetWaitingAnim; WindowState mInputMethodWindow = null; - // TODO: Remove with extreme prejudice! This list is maintained so that we can keep track of - // dialogs that should go on top of the IME so they can be re-arranged in the window list any - // time the IME changes position in the window list. Normally you would have a dialog be a child - // window of the IME, but they don't share the same token since they are added by different - // clients. This doesn't really affect what the user sees on screen since this dialogs have an - // higher base layer than the IME window, but it will affect users of the window list that - // expect the list to represent the order of things on-screen (e.g input service). This makes - // the code for managing the window list hard to follow (see all the places it is used). - // We can remove the use of this field when we automatically assign layers and z-order the - // window list before it is used whenever window container order changes. - final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<>(); boolean mHardKeyboardAvailable; WindowManagerInternal.OnHardKeyboardStatusChangeListener mHardKeyboardStatusChangeListener; @@ -1377,19 +1366,16 @@ public class WindowManagerService extends IWindowManager.Stub boolean imMayMove = true; + win.mToken.addWindow(win); if (type == TYPE_INPUT_METHOD) { win.mGivenInsetsPending = true; mInputMethodWindow = win; - win.mToken.addImeWindow(win); + displayContent.computeImeTarget(true /* updateImeTarget */); imMayMove = false; } else if (type == TYPE_INPUT_METHOD_DIALOG) { - mInputMethodDialogs.add(win); - win.mToken.addWindow(win); - displayContent.moveInputMethodDialogs( - displayContent.findDesiredInputMethodWindowIndex(true)); + displayContent.computeImeTarget(true /* updateImeTarget */); imMayMove = false; } else { - win.mToken.addWindow(win); if (type == TYPE_WALLPAPER) { displayContent.mWallpaperController.clearLastWallpaperTimeoutTime(); displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; @@ -1462,7 +1448,7 @@ public class WindowManagerService extends IWindowManager.Stub } if (imMayMove) { - displayContent.moveInputMethodWindowsIfNeeded(false); + displayContent.computeImeTarget(true /* updateImeTarget */); } // Don't do layout here, the window must call @@ -1646,8 +1632,6 @@ public class WindowManagerService extends IWindowManager.Stub if (mInputMethodWindow == win) { mInputMethodWindow = null; - } else if (win.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) { - mInputMethodDialogs.remove(win); } final WindowToken token = win.mToken; @@ -1677,13 +1661,11 @@ public class WindowManagerService extends IWindowManager.Stub dc.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; } - if (dc != null && dc.removeFromWindowList(win)) { - if (!mWindowPlacerLocked.isInLayout()) { - dc.assignWindowLayers(true /* setLayoutNeeded */); - mWindowPlacerLocked.performSurfacePlacement(); - if (win.mAppToken != null) { - win.mAppToken.updateReportedVisibilityLocked(); - } + if (dc != null && !mWindowPlacerLocked.isInLayout()) { + dc.assignWindowLayers(true /* setLayoutNeeded */); + mWindowPlacerLocked.performSurfacePlacement(); + if (win.mAppToken != null) { + win.mAppToken.updateReportedVisibilityLocked(); } } @@ -2064,14 +2046,15 @@ public class WindowManagerService extends IWindowManager.Stub // reassign them at this point if the IM window state gets shuffled boolean toBeDisplayed = (result & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0; final DisplayContent dc = win.getDisplayContent(); - if (imMayMove && (dc.moveInputMethodWindowsIfNeeded(false) || toBeDisplayed)) { - // Little hack here -- we -should- be able to rely on the function to return true if - // the IME has moved and needs its layer recomputed. However, if the IME was hidden - // and isn't actually moved in the list, its layer may be out of data so we make - // sure to recompute it. - // TODO: Probably not needed once the window list always has the right z-ordering - // when the window hierarchy is updated. - dc.assignWindowLayers(false /* setLayoutNeeded */); + if (imMayMove) { + dc.computeImeTarget(true /* updateImeTarget */); + if (toBeDisplayed) { + // Little hack here -- we -should- be able to rely on the function to return + // true if the IME has moved and needs its layer recomputed. However, if the IME + // was hidden and isn't actually moved in the list, its layer may be out of data + // so we make sure to recompute it. + dc.assignWindowLayers(false /* setLayoutNeeded */); + } } if (wallpaperMayMove) { @@ -3351,7 +3334,7 @@ public class WindowManagerService extends IWindowManager.Stub if (mAppTransition.isTransitionSet()) { task.setSendingToBottom(false); } - displayContent.rebuildAppWindowsAndLayoutIfNeeded(); + displayContent.layoutAndAssignWindowLayersIfNeeded(); } } finally { Binder.restoreCallingIdentity(origId); @@ -3373,7 +3356,7 @@ public class WindowManagerService extends IWindowManager.Stub if (mAppTransition.isTransitionSet()) { task.setSendingToBottom(true); } - stack.getDisplayContent().rebuildAppWindowsAndLayoutIfNeeded(); + stack.getDisplayContent().layoutAndAssignWindowLayersIfNeeded(); } } finally { Binder.restoreCallingIdentity(origId); @@ -4619,7 +4602,7 @@ public class WindowManagerService extends IWindowManager.Stub return null; } } - return displayContent.screenshotApplications(appToken, displayId, width, height, + return displayContent.screenshotApplications(appToken, width, height, includeFullDisplay, frameScale, config, wallpaperOnly); } @@ -5181,7 +5164,7 @@ public class WindowManagerService extends IWindowManager.Stub boolean result = true; - final WindowList windows = new WindowList(); + final ArrayList<WindowState> windows = new ArrayList(); synchronized (mWindowMap) { mRoot.forAllWindows(w -> { windows.add(w); @@ -7312,7 +7295,7 @@ public class WindowManagerService extends IWindowManager.Stub changes |= FINISH_LAYOUT_REDO_LAYOUT; if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG_WM, "Wallpaper layer changed: assigning layers + relayout"); - dc.moveInputMethodWindowsIfNeeded(true); + dc.computeImeTarget(true /* updateImeTarget */); mRoot.mWallpaperMayChange = true; // Since the window list has been rebuilt, focus might have to be recomputed since the // actual order of windows might have changed again. @@ -7405,10 +7388,25 @@ public class WindowManagerService extends IWindowManager.Stub mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE); // TODO(multidisplay): Focused windows on default display only. final DisplayContent displayContent = getDefaultDisplayContentLocked(); - final boolean imWindowChanged = displayContent.moveInputMethodWindowsIfNeeded( - mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS - && mode != UPDATE_FOCUS_WILL_PLACE_SURFACES); + boolean imWindowChanged = false; + if (mInputMethodWindow != null) { + final WindowState prevTarget = mInputMethodTarget; + final WindowState newTarget = + displayContent.computeImeTarget(true /* updateImeTarget*/); + + imWindowChanged = prevTarget != newTarget; + + if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS + && mode != UPDATE_FOCUS_WILL_PLACE_SURFACES) { + final int prevImeAnimLayer = mInputMethodWindow.mWinAnimator.mAnimLayer; + displayContent.assignWindowLayers(false /* setLayoutNeeded */); + imWindowChanged |= + prevImeAnimLayer != mInputMethodWindow.mWinAnimator.mAnimLayer; + } + } + if (imWindowChanged) { + mWindowsChanged = true; displayContent.setLayoutNeeded(); newFocus = mRoot.computeFocusedWindow(); } @@ -7883,7 +7881,6 @@ public class WindowManagerService extends IWindowManager.Stub private void dumpTokensLocked(PrintWriter pw, boolean dumpAll) { pw.println("WINDOW MANAGER TOKENS (dumpsys window tokens)"); mRoot.dumpTokens(pw, dumpAll); - mRoot.mWallpaperController.dumpTokens(pw, " ", dumpAll); if (!mFinishedStarting.isEmpty()) { pw.println(); pw.println(" Finishing start of application tokens:"); @@ -7929,16 +7926,6 @@ public class WindowManagerService extends IWindowManager.Stub ArrayList<WindowState> windows) { mRoot.dumpWindowsNoHeader(pw, dumpAll, windows); - if (mInputMethodDialogs.size() > 0) { - pw.println(); - pw.println(" Input method dialogs:"); - for (int i=mInputMethodDialogs.size()-1; i>=0; i--) { - WindowState w = mInputMethodDialogs.get(i); - if (windows == null || windows.contains(w)) { - pw.print(" IM Dialog #"); pw.print(i); pw.print(": "); pw.println(w); - } - } - } if (mPendingRemove.size() > 0) { pw.println(); pw.println(" Remove pending for:"); @@ -8097,7 +8084,7 @@ public class WindowManagerService extends IWindowManager.Stub private boolean dumpWindows(PrintWriter pw, String name, String[] args, int opti, boolean dumpAll) { - final WindowList windows = new WindowList(); + final ArrayList<WindowState> windows = new ArrayList(); if ("apps".equals(name) || "visible".equals(name) || "visible-apps".equals(name)) { final boolean appsOnly = name.contains("apps"); final boolean visibleOnly = name.contains("visible"); diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 661df9cd60ad..d959d8c715ca 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -76,6 +76,7 @@ import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_ import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW; import static android.view.WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW; import static android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON; +import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND; import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; @@ -115,6 +116,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIO import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_CONFIGURATION; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT; +import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT_METHOD; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION; @@ -140,9 +142,6 @@ import static com.android.server.wm.WindowStateAnimator.DRAW_PENDING; import static com.android.server.wm.WindowStateAnimator.HAS_DRAWN; import static com.android.server.wm.WindowStateAnimator.READY_TO_SHOW; -class WindowList extends ArrayList<WindowState> { -} - /** A window in the window manager. */ class WindowState extends WindowContainer<WindowState> implements WindowManagerPolicy.WindowState { static final String TAG = TAG_WITH_CLASS_NAME ? "WindowState" : TAG_WM; @@ -448,12 +447,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP */ boolean mWindowRemovalAllowed; - /** - * Temp for keeping track of windows that have been removed when - * rebuilding window list. - */ - boolean mRebuilding; - // Input channel and input window handle used by the input dispatcher. final InputWindowHandle mInputWindowHandle; InputChannel mInputChannel; @@ -1721,7 +1714,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP final DisplayContent dc = getDisplayContent(); if (mService.mInputMethodTarget == this) { - dc.moveInputMethodWindowsIfNeeded(false); + dc.computeImeTarget(true /* updateImeTarget */); } final int type = mAttrs.type; @@ -1931,6 +1924,33 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP return mLayer + specialAdjustment; } + boolean canBeImeTarget() { + final int fl = mAttrs.flags & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM); + final int type = mAttrs.type; + + if (fl != 0 && fl != (FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM) + && type != TYPE_APPLICATION_STARTING) { + return false; + } + + if (DEBUG_INPUT_METHOD) { + Slog.i(TAG_WM, "isVisibleOrAdding " + this + ": " + isVisibleOrAdding()); + if (!isVisibleOrAdding()) { + Slog.i(TAG_WM, " mSurfaceController=" + mWinAnimator.mSurfaceController + + " relayoutCalled=" + mRelayoutCalled + + " viewVis=" + mViewVisibility + + " policyVis=" + mPolicyVisibility + + " policyVisAfterAnim=" + mPolicyVisibilityAfterAnim + + " parentHidden=" + isParentWindowHidden() + + " exiting=" + mAnimatingExit + " destroying=" + mDestroying); + if (mAppToken != null) { + Slog.i(TAG_WM, " mAppToken.hiddenRequested=" + mAppToken.hiddenRequested); + } + } + } + return isVisibleOrAdding(); + } + void scheduleAnimationIfDimming() { final DisplayContent dc = getDisplayContent(); if (dc == null) { @@ -2085,7 +2105,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP return false; } - void removeReplacedWindow() { + private void removeReplacedWindow() { if (DEBUG_ADD_REMOVE) Slog.d(TAG, "Removing replaced window: " + this); if (isDimming()) { transferDimToReplacement(); @@ -2138,6 +2158,16 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } } + @Override + void switchUser() { + super.switchUser(); + if (isHiddenFromUserLocked()) { + if (DEBUG_VISIBILITY) Slog.w(TAG_WM, "user changing, hiding " + this + + ", attrs=" + mAttrs.type + ", belonging to " + mOwnerUid); + hideLw(false); + } + } + int getTouchableRegion(Region region, int flags) { final boolean modal = (flags & (FLAG_NOT_TOUCH_MODAL | FLAG_NOT_FOCUSABLE)) == 0; if (modal && mAppToken != null) { @@ -3499,16 +3529,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP return mIsChildWindow; } - /** - * Returns the bottom child window in regards to z-order of this window or null if no children. - */ - WindowState getBottomChild() { - // Child windows are z-ordered based on sub-layer using {@link #sWindowSubLayerComparator} - // and the child with the lowest z-order will be at the head of the list. - WindowState c = mChildren.peekFirst(); - return c == null ? null : c; - } - boolean layoutInParentFrame() { return mIsChildWindow && (mAttrs.privateFlags & PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME) != 0; @@ -3795,44 +3815,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } @Override - int rebuildWindowList(int addIndex) { - return reAddWindow(addIndex); - } - - // TODO: come-up with a better name for this method that represents what it does. - // Or, it is probably not going to matter anyways if we are successful in getting rid of - // the WindowList concept. - int reAddWindow(int index) { - final DisplayContent dc = getDisplayContent(); - // Adding child windows relies on child windows being ordered by mSubLayer using - // {@link #sWindowSubLayerComparator}. - final int childCount = mChildren.size(); - boolean winAdded = false; - for (int j = 0; j < childCount; j++) { - final WindowState child = mChildren.get(j); - if (!winAdded && child.mSubLayer >= 0) { - if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, - "Re-adding child window at " + index + ": " + child); - mRebuilding = false; - dc.addToWindowList(this, index); - index++; - winAdded = true; - } - if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Re-adding window at " + index + ": " + child); - child.mRebuilding = false; - dc.addToWindowList(child, index); - index++; - } - if (!winAdded) { - if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Re-adding window at " + index + ": " + this); - mRebuilding = false; - dc.addToWindowList(this, index); - index++; - } - return index; - } - - @Override boolean forAllWindows(ToBooleanFunction<WindowState> callback, boolean traverseTopToBottom) { if (mChildren.isEmpty()) { // The window has no children so we just return it. diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java index 7e1880fb65d6..de808377e880 100644 --- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java +++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java @@ -239,7 +239,8 @@ class WindowSurfacePlacer { mService.mH.removeMessages(H.APP_TRANSITION_TIMEOUT); final DisplayContent displayContent = mService.getDefaultDisplayContentLocked(); - displayContent.rebuildAppWindowList(); + // TODO: Don't believe this is really needed... + //mService.mWindowsChanged = true; mService.mRoot.mWallpaperMayChange = false; @@ -356,12 +357,8 @@ class WindowSurfacePlacer { displayContent.setLayoutNeeded(); // TODO(multidisplay): IMEs are only supported on the default display. - // TODO: Probably not needed once the window list always has the right z-ordering - // when the window hierarchy is updated. final DisplayContent dc = mService.getDefaultDisplayContentLocked(); - if (!dc.moveInputMethodWindowsIfNeeded(true)) { - dc.assignWindowLayers(false /*setLayoutNeeded*/); - } + dc.computeImeTarget(true /* updateImeTarget */); mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES, true /*updateInputWindows*/); mService.mFocusMayChange = false; diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java index a2eebc336970..40bd3fb41b2f 100644 --- a/services/core/java/com/android/server/wm/WindowToken.java +++ b/services/core/java/com/android/server/wm/WindowToken.java @@ -168,13 +168,6 @@ class WindowToken extends WindowContainer<WindowState> { return highestAnimLayer; } - WindowState getTopWindow() { - if (mChildren.isEmpty()) { - return null; - } - return (WindowState) mChildren.get(mChildren.size() - 1).getTop(); - } - /** * Returns true if the new window is considered greater than the existing window in terms of * z-order. @@ -189,51 +182,16 @@ class WindowToken extends WindowContainer<WindowState> { if (DEBUG_FOCUS) Slog.d(TAG_WM, "addWindow: win=" + win + " Callers=" + Debug.getCallers(5)); - if (!win.isChildWindow()) { - if (asAppWindowToken() != null) { - mDisplayContent.addAppWindowToWindowList(win); - } else { - mDisplayContent.addNonAppWindowToWindowList(win); - } - - if (!mChildren.contains(win)) { - if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Adding " + win + " to " + this); - addChild(win, mWindowComparator); - } - } else { - mDisplayContent.addChildWindowToWindowList(win); - } - } - - void addImeWindow(WindowState win) { - int pos = mDisplayContent.findDesiredInputMethodWindowIndex(true); - - if (pos < 0) { - addWindow(win); - mDisplayContent.moveInputMethodDialogs(pos); + if (win.isChildWindow()) { + // Child windows are added to their parent windows. return; } - - if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM, - "Adding input method window " + win + " at " + pos); - mDisplayContent.addToWindowList(win, pos); if (!mChildren.contains(win)) { - addChild(win, null); + if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Adding " + win + " to " + this); + addChild(win, mWindowComparator); + mService.mWindowsChanged = true; + // TODO: Should we also be setting layout needed here and other places? } - mDisplayContent.moveInputMethodDialogs(pos + 1); - } - - /** Return the first window in the token window list that isn't a starting window or null. */ - WindowState getFirstNonStartingWindow() { - final int count = mChildren.size(); - // We only care about parent windows so no need to loop through child windows. - for (int i = 0; i < count; i++) { - final WindowState w = mChildren.get(i); - if (w.mAttrs.type != TYPE_APPLICATION_STARTING) { - return w; - } - } - return null; } /** Returns true if the token windows list is empty. */ diff --git a/services/core/jni/com_android_server_lights_LightsService.cpp b/services/core/jni/com_android_server_lights_LightsService.cpp index e6072bb03ccc..a3ab8f67d2fa 100644 --- a/services/core/jni/com_android_server_lights_LightsService.cpp +++ b/services/core/jni/com_android_server_lights_LightsService.cpp @@ -34,6 +34,9 @@ using Brightness = ::android::hardware::light::V2_0::Brightness; using Flash = ::android::hardware::light::V2_0::Flash; using Type = ::android::hardware::light::V2_0::Type; using LightState = ::android::hardware::light::V2_0::LightState; +using Status = ::android::hardware::light::V2_0::Status; +template<typename T> +using Return = ::android::hardware::Return<T>; static sp<ILight> gLight; @@ -108,9 +111,33 @@ static void setLight_native( state.brightnessMode = brightness; + Status status; + { ALOGD_IF_SLOW(50, "Excessive delay setting light"); - gLight->setLight(type, state); + Return<Status> ret = gLight->setLight(type, state); + + // TODO(b/31348667): this is transport specific status + if (!ret.getStatus().isOk()) { + ALOGE("Failed to issue set light command."); + return; + } + + status = static_cast<Status>(ret); // hal status + } + + switch (status) { + case Status::SUCCESS: + break; + case Status::LIGHT_NOT_SUPPORTED: + ALOGE("Light requested not availale on this device."); + break; + case Status::BRIGHTNESS_NOT_SUPPORTED: + ALOGE("Brightness parameter not supported on this device."); + break; + case Status::UNKNOWN: + default: + ALOGE("Unknown error setting light."); } } diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index ba23f219c106..1fc4378de277 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -41,12 +41,10 @@ import android.os.SystemClock; import android.os.SystemProperties; import android.os.Trace; import android.os.UserHandle; -import android.os.UserManager; import android.os.storage.IStorageManager; -import android.provider.Settings; +import android.util.BootTimingsTraceLog; import android.util.DisplayMetrics; import android.util.EventLog; -import android.util.Pair; import android.util.Slog; import android.view.WindowManager; @@ -55,7 +53,6 @@ import com.android.internal.app.NightDisplayController; import com.android.internal.logging.MetricsLogger; import com.android.internal.os.BinderInternal; import com.android.internal.os.SamplingProfilerIntegration; -import com.android.internal.os.ZygoteInit; import com.android.internal.policy.EmergencyAffordanceManager; import com.android.internal.widget.ILockSettings; import com.android.server.accessibility.AccessibilityManagerService; @@ -102,8 +99,8 @@ import com.android.server.statusbar.StatusBarManagerService; import com.android.server.storage.DeviceStorageMonitorService; import com.android.server.telecom.TelecomLoaderService; import com.android.server.trust.TrustManagerService; -import com.android.server.tv.TvRemoteService; import com.android.server.tv.TvInputManagerService; +import com.android.server.tv.TvRemoteService; import com.android.server.twilight.TwilightService; import com.android.server.usage.UsageStatsService; import com.android.server.vr.VrManagerService; @@ -112,8 +109,6 @@ import com.android.server.wm.WindowManagerService; import dalvik.system.VMRuntime; -import java.util.ArrayDeque; -import java.util.Deque; import java.io.File; import java.io.IOException; import java.util.Locale; @@ -125,11 +120,8 @@ import static android.view.Display.DEFAULT_DISPLAY; public final class SystemServer { private static final String TAG = "SystemServer"; - private static final boolean LOG_BOOT_TIME = true; - // Debug boot time for every step if it's non-user build. - private static final boolean DEBUG_BOOT_TIME = LOG_BOOT_TIME && !"user".equals(Build.TYPE); - private static final String TAG_BOOT_TIME = "SystemServerTiming"; - private static final Deque<Pair<String, Long>> START_TIMES = new ArrayDeque<>(); + private static final BootTimingsTraceLog BOOT_TIMINGS_TRACE_LOG + = new BootTimingsTraceLog("SystemServerTiming", Trace.TRACE_TAG_SYSTEM_SERVER); private static final String ENCRYPTING_STATE = "trigger_restart_min_framework"; private static final String ENCRYPTED_STATE = "1"; @@ -279,6 +271,11 @@ public final class SystemServer { int uptimeMillis = (int) SystemClock.uptimeMillis(); EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, uptimeMillis); MetricsLogger.histogram(null, "boot_system_server_init", uptimeMillis); + // Also report when first stage of init has started + long initStartNs = SystemProperties.getLong("init.start", -1); + if (initStartNs >= 0) { + MetricsLogger.histogram(null, "boot_android_init", (int)(initStartNs / 1000000)); + } // In case the runtime switched since last boot (such as when // the old runtime was removed in an OTA), set the system @@ -1643,24 +1640,11 @@ public final class SystemServer { } private static void traceBeginAndSlog(String name) { - Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, name); Slog.i(TAG, name); - if (DEBUG_BOOT_TIME) { - START_TIMES.push(Pair.create(name, Long.valueOf(SystemClock.elapsedRealtime()))); - } + BOOT_TIMINGS_TRACE_LOG.traceBegin(name); } private static void traceEnd() { - Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); - if (!DEBUG_BOOT_TIME) { - return; - } - Pair<String, Long> event = START_TIMES.pollFirst(); - if (event == null) { - Slog.w(TAG, "traceEnd called more times than traceBeginAndSlog"); - return; - } - Slog.d(TAG_BOOT_TIME, event.first + " took to complete: " - + (SystemClock.elapsedRealtime() - event.second) + "ms"); + BOOT_TIMINGS_TRACE_LOG.traceEnd(); } } diff --git a/services/print/java/com/android/server/print/RemotePrintSpooler.java b/services/print/java/com/android/server/print/RemotePrintSpooler.java index 6b919df290bb..f4c9c86fda2a 100644 --- a/services/print/java/com/android/server/print/RemotePrintSpooler.java +++ b/services/print/java/com/android/server/print/RemotePrintSpooler.java @@ -43,6 +43,7 @@ import android.printservice.PrintService; import android.util.Slog; import android.util.TimedRemoteCaller; +import com.android.internal.annotations.GuardedBy; import com.android.internal.os.TransferPipe; import libcore.io.IoUtils; @@ -112,6 +113,10 @@ final class RemotePrintSpooler { private boolean mCanUnbind; + /** Whether a thread is currently trying to {@link #bindLocked() bind to the print service} */ + @GuardedBy("mLock") + private boolean mIsBinding; + public static interface PrintSpoolerCallbacks { public void onPrintJobQueued(PrintJobInfo printJob); public void onAllPrintJobsForServiceHandled(ComponentName printService); @@ -164,10 +169,8 @@ final class RemotePrintSpooler { try { return mGetPrintJobInfosCaller.getPrintJobInfos(getRemoteInstanceLazy(), componentName, state, appId); - } catch (RemoteException re) { - Slog.e(LOG_TAG, "Error getting print jobs.", re); - } catch (TimeoutException te) { - Slog.e(LOG_TAG, "Error getting print jobs.", te); + } catch (RemoteException | TimeoutException | InterruptedException e) { + Slog.e(LOG_TAG, "Error getting print jobs.", e); } finally { if (DEBUG) { Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] getPrintJobInfos()"); @@ -188,10 +191,8 @@ final class RemotePrintSpooler { } try { getRemoteInstanceLazy().createPrintJob(printJob); - } catch (RemoteException re) { - Slog.e(LOG_TAG, "Error creating print job.", re); - } catch (TimeoutException te) { - Slog.e(LOG_TAG, "Error creating print job.", te); + } catch (RemoteException | TimeoutException | InterruptedException e) { + Slog.e(LOG_TAG, "Error creating print job.", e); } finally { if (DEBUG) { Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] createPrintJob()"); @@ -211,10 +212,8 @@ final class RemotePrintSpooler { } try { getRemoteInstanceLazy().writePrintJobData(fd, printJobId); - } catch (RemoteException re) { - Slog.e(LOG_TAG, "Error writing print job data.", re); - } catch (TimeoutException te) { - Slog.e(LOG_TAG, "Error writing print job data.", te); + } catch (RemoteException | TimeoutException | InterruptedException e) { + Slog.e(LOG_TAG, "Error writing print job data.", e); } finally { if (DEBUG) { Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] writePrintJobData()"); @@ -238,10 +237,8 @@ final class RemotePrintSpooler { try { return mGetPrintJobInfoCaller.getPrintJobInfo(getRemoteInstanceLazy(), printJobId, appId); - } catch (RemoteException re) { - Slog.e(LOG_TAG, "Error getting print job info.", re); - } catch (TimeoutException te) { - Slog.e(LOG_TAG, "Error getting print job info.", te); + } catch (RemoteException | TimeoutException | InterruptedException e) { + Slog.e(LOG_TAG, "Error getting print job info.", e); } finally { if (DEBUG) { Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] getPrintJobInfo()"); @@ -263,10 +260,8 @@ final class RemotePrintSpooler { try { return mSetPrintJobStatusCaller.setPrintJobState(getRemoteInstanceLazy(), printJobId, state, error); - } catch (RemoteException re) { - Slog.e(LOG_TAG, "Error setting print job state.", re); - } catch (TimeoutException te) { - Slog.e(LOG_TAG, "Error setting print job state.", te); + } catch (RemoteException | TimeoutException | InterruptedException e) { + Slog.e(LOG_TAG, "Error setting print job state.", e); } finally { if (DEBUG) { Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setPrintJobState()"); @@ -294,7 +289,7 @@ final class RemotePrintSpooler { } try { getRemoteInstanceLazy().setProgress(printJobId, progress); - } catch (RemoteException|TimeoutException re) { + } catch (RemoteException | TimeoutException | InterruptedException re) { Slog.e(LOG_TAG, "Error setting progress.", re); } finally { if (DEBUG) { @@ -321,8 +316,8 @@ final class RemotePrintSpooler { } try { getRemoteInstanceLazy().setStatus(printJobId, status); - } catch (RemoteException|TimeoutException re) { - Slog.e(LOG_TAG, "Error setting status.", re); + } catch (RemoteException | TimeoutException | InterruptedException e) { + Slog.e(LOG_TAG, "Error setting status.", e); } finally { if (DEBUG) { Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setStatus()"); @@ -350,8 +345,8 @@ final class RemotePrintSpooler { } try { getRemoteInstanceLazy().setStatusRes(printJobId, status, appPackageName); - } catch (RemoteException|TimeoutException re) { - Slog.e(LOG_TAG, "Error setting status.", re); + } catch (RemoteException | TimeoutException | InterruptedException e) { + Slog.e(LOG_TAG, "Error setting status.", e); } finally { if (DEBUG) { Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setStatus()"); @@ -380,7 +375,7 @@ final class RemotePrintSpooler { try { mCustomPrinterIconLoadedCaller.onCustomPrinterIconLoaded(getRemoteInstanceLazy(), printerId, icon); - } catch (RemoteException|TimeoutException re) { + } catch (RemoteException | TimeoutException | InterruptedException re) { Slog.e(LOG_TAG, "Error loading new custom printer icon.", re); } finally { if (DEBUG) { @@ -412,8 +407,8 @@ final class RemotePrintSpooler { try { return mGetCustomPrinterIconCaller.getCustomPrinterIcon(getRemoteInstanceLazy(), printerId); - } catch (RemoteException|TimeoutException re) { - Slog.e(LOG_TAG, "Error getting custom printer icon.", re); + } catch (RemoteException | TimeoutException | InterruptedException e) { + Slog.e(LOG_TAG, "Error getting custom printer icon.", e); return null; } finally { if (DEBUG) { @@ -438,8 +433,8 @@ final class RemotePrintSpooler { } try { mClearCustomPrinterIconCache.clearCustomPrinterIconCache(getRemoteInstanceLazy()); - } catch (RemoteException|TimeoutException re) { - Slog.e(LOG_TAG, "Error clearing custom printer icon cache.", re); + } catch (RemoteException | TimeoutException | InterruptedException e) { + Slog.e(LOG_TAG, "Error clearing custom printer icon cache.", e); } finally { if (DEBUG) { Slog.i(LOG_TAG, @@ -462,10 +457,8 @@ final class RemotePrintSpooler { try { return mSetPrintJobTagCaller.setPrintJobTag(getRemoteInstanceLazy(), printJobId, tag); - } catch (RemoteException re) { - Slog.e(LOG_TAG, "Error setting print job tag.", re); - } catch (TimeoutException te) { - Slog.e(LOG_TAG, "Error setting print job tag.", te); + } catch (RemoteException | TimeoutException | InterruptedException e) { + Slog.e(LOG_TAG, "Error setting print job tag.", e); } finally { if (DEBUG) { Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] setPrintJobTag()"); @@ -487,10 +480,8 @@ final class RemotePrintSpooler { try { getRemoteInstanceLazy().setPrintJobCancelling(printJobId, cancelling); - } catch (RemoteException re) { - Slog.e(LOG_TAG, "Error setting print job cancelling.", re); - } catch (TimeoutException te) { - Slog.e(LOG_TAG, "Error setting print job cancelling.", te); + } catch (RemoteException | TimeoutException | InterruptedException e) { + Slog.e(LOG_TAG, "Error setting print job cancelling.", e); } finally { if (DEBUG) { Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() @@ -516,8 +507,8 @@ final class RemotePrintSpooler { } try { getRemoteInstanceLazy().pruneApprovedPrintServices(servicesToKeep); - } catch (RemoteException|TimeoutException re) { - Slog.e(LOG_TAG, "Error pruning approved print services.", re); + } catch (RemoteException | TimeoutException | InterruptedException e) { + Slog.e(LOG_TAG, "Error pruning approved print services.", e); } finally { if (DEBUG) { Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() @@ -538,9 +529,7 @@ final class RemotePrintSpooler { } try { getRemoteInstanceLazy().removeObsoletePrintJobs(); - } catch (RemoteException re) { - Slog.e(LOG_TAG, "Error removing obsolete print jobs .", re); - } catch (TimeoutException te) { + } catch (RemoteException | TimeoutException | InterruptedException te) { Slog.e(LOG_TAG, "Error removing obsolete print jobs .", te); } finally { if (DEBUG) { @@ -578,7 +567,7 @@ final class RemotePrintSpooler { try { TransferPipe.dumpAsync(getRemoteInstanceLazy().asBinder(), fd, new String[] { prefix }); - } catch (IOException | TimeoutException | RemoteException e) { + } catch (IOException | TimeoutException | RemoteException | InterruptedException e) { pw.println("Failed to dump remote instance: " + e); } } @@ -595,7 +584,7 @@ final class RemotePrintSpooler { mCallbacks.onPrintJobStateChanged(printJob); } - private IPrintSpooler getRemoteInstanceLazy() throws TimeoutException { + private IPrintSpooler getRemoteInstanceLazy() throws TimeoutException, InterruptedException { synchronized (mLock) { if (mRemoteInstance != null) { return mRemoteInstance; @@ -605,43 +594,50 @@ final class RemotePrintSpooler { } } - private void bindLocked() throws TimeoutException { + private void bindLocked() throws TimeoutException, InterruptedException { + while (mIsBinding) { + mLock.wait(); + } + if (mRemoteInstance != null) { return; } + + mIsBinding = true; + if (DEBUG) { Slog.i(LOG_TAG, "[user: " + mUserHandle.getIdentifier() + "] bindLocked() " + (mIsLowPriority ? "low priority" : "")); } - int flags; - if (mIsLowPriority) { - flags = Context.BIND_AUTO_CREATE; - } else { - flags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE; - } + try { + int flags; + if (mIsLowPriority) { + flags = Context.BIND_AUTO_CREATE; + } else { + flags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE; + } - mContext.bindServiceAsUser(mIntent, mServiceConnection, flags, mUserHandle); + mContext.bindServiceAsUser(mIntent, mServiceConnection, flags, mUserHandle); - final long startMillis = SystemClock.uptimeMillis(); - while (true) { - if (mRemoteInstance != null) { - break; - } - final long elapsedMillis = SystemClock.uptimeMillis() - startMillis; - final long remainingMillis = BIND_SPOOLER_SERVICE_TIMEOUT - elapsedMillis; - if (remainingMillis <= 0) { - throw new TimeoutException("Cannot get spooler!"); - } - try { + final long startMillis = SystemClock.uptimeMillis(); + while (true) { + if (mRemoteInstance != null) { + break; + } + final long elapsedMillis = SystemClock.uptimeMillis() - startMillis; + final long remainingMillis = BIND_SPOOLER_SERVICE_TIMEOUT - elapsedMillis; + if (remainingMillis <= 0) { + throw new TimeoutException("Cannot get spooler!"); + } mLock.wait(remainingMillis); - } catch (InterruptedException ie) { - /* ignore */ } - } - mCanUnbind = true; - mLock.notifyAll(); + mCanUnbind = true; + } finally { + mIsBinding = false; + mLock.notifyAll(); + } } private void unbindLocked() { diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerPresubmitTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerPresubmitTest.java new file mode 100644 index 000000000000..379d4fe00afb --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerPresubmitTest.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.server.pm; + +import android.content.Context; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.PermissionInfo; +import android.platform.test.annotations.Presubmit; +import android.support.test.InstrumentationRegistry; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; +import android.util.ArraySet; + +import com.android.internal.os.RoSystemProperties; +import com.android.server.SystemConfig; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static junit.framework.Assert.assertTrue; + + +/** + * Presubmit tests for {@link PackageManager}. + */ +@RunWith(AndroidJUnit4.class) +public class PackageManagerPresubmitTest { + + private Context mContext; + + private PackageManager mPackageManager; + + @Before + public void setUp() { + mContext = InstrumentationRegistry.getContext(); + mPackageManager = mContext.getPackageManager(); + } + + /** + * <p>This test ensures that all signature|privileged permissions are granted to core apps like + * systemui/settings. If CONTROL_PRIVAPP_PERMISSIONS is set, the test also verifies that + * granted permissions are whitelisted in {@link SystemConfig} + */ + @Test + @SmallTest + @Presubmit + public void testPrivAppPermissions() throws PackageManager.NameNotFoundException { + String[] testPackages = {"com.android.settings", "com.android.shell", + "com.android.systemui"}; + for (String testPackage : testPackages) { + testPackagePrivAppPermission(testPackage); + } + } + + private void testPackagePrivAppPermission(String testPackage) + throws PackageManager.NameNotFoundException { + PackageInfo packageInfo = mPackageManager.getPackageInfo(testPackage, + PackageManager.GET_PERMISSIONS); + ArraySet<String> privAppPermissions = SystemConfig.getInstance() + .getPrivAppPermissions(testPackage); + for (int i = 0; i < packageInfo.requestedPermissions.length; i++) { + String pName = packageInfo.requestedPermissions[i]; + int protectionLevel; + boolean platformPermission; + try { + PermissionInfo permissionInfo = mPackageManager.getPermissionInfo(pName, 0); + platformPermission = PackageManagerService.PLATFORM_PACKAGE_NAME.equals( + permissionInfo.packageName); + protectionLevel = permissionInfo.protectionLevel; + } catch (PackageManager.NameNotFoundException e) { + continue; + } + if ((protectionLevel & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) { + boolean granted = (packageInfo.requestedPermissionsFlags[i] + & PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0; + assertTrue("Permission " + pName + " should be granted to " + testPackage, granted); + // if CONTROL_PRIVAPP_PERMISSIONS enabled, platform permissions must be whitelisted + // in SystemConfig + if (platformPermission && RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS) { + assertTrue("Permission " + pName + + " should be declared in the xml file for package " + + testPackage, + privAppPermissions.contains(pName)); + } + } + } + } +} diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java index 50e5a2220ee3..3f47d5cfc2d3 100644 --- a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java @@ -117,35 +117,6 @@ public class WindowStateTests extends WindowTestsBase { } @Test - public void testGetBottomChild() throws Exception { - final WindowState parentWindow = - createWindow(null, TYPE_APPLICATION, mWindowToken, "parentWindow"); - assertNull(parentWindow.getBottomChild()); - - final WindowState child1 = - createWindow(parentWindow, TYPE_APPLICATION_PANEL, mWindowToken, "child1"); - assertEquals(child1, parentWindow.getBottomChild()); - - final WindowState child2 = - createWindow(parentWindow, TYPE_APPLICATION_PANEL, mWindowToken, "child2"); - // Since child1 and child2 are at the same layer, then child2 is expect to be added on top - // on child1 - assertEquals(child1, parentWindow.getBottomChild()); - - final WindowState child3 = - createWindow(parentWindow, TYPE_APPLICATION_MEDIA_OVERLAY, mWindowToken, "child3"); - // Since child3 is a negative layer, we would expect it to be added below current children - // with positive layers. - assertEquals(child3, parentWindow.getBottomChild()); - - final WindowState child4 = - createWindow(parentWindow, TYPE_APPLICATION_MEDIA_OVERLAY, mWindowToken, "child4"); - // We would also expect additional negative layers to be added below existing negative - // layers. - assertEquals(child4, parentWindow.getBottomChild()); - } - - @Test public void testGetParentWindow() throws Exception { final WindowState parentWindow = createWindow(null, TYPE_APPLICATION, mWindowToken, "parentWindow"); diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 20dd012b07e1..ad97a8ff2a88 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -686,42 +686,49 @@ public class TelephonyManager { public static final String EXTRA_DATA_FAILURE_CAUSE = PhoneConstants.DATA_FAILURE_CAUSE_KEY; /** - * Broadcast intent action for letting custom component know to show voicemail notification. - * @hide + * Broadcast intent action for letting the default dialer to know to show voicemail + * notification. + * + * <p> + * The {@link #EXTRA_NOTIFICATION_COUNT} extra indicates the total numbers of unheard + * voicemails. + * The {@link #EXTRA_VOICEMAIL_NUMBER} extra indicates the voicemail number if available. + * The {@link #EXTRA_CALL_VOICEMAIL_INTENT} extra is a {@link android.app.PendingIntent} that + * will call the voicemail number when sent. This extra will be empty if the voicemail number + * is not set, and {@link #EXTRA_LAUNCH_VOICEMAIL_SETTINGS_INTENT} will be set instead. + * The {@link #EXTRA_LAUNCH_VOICEMAIL_SETTINGS_INTENT} extra is a + * {@link android.app.PendingIntent} that will launch the voicemail settings. This extra is only + * available when the voicemail number is not set. + * + * @see #EXTRA_NOTIFICATION_COUNT + * @see #EXTRA_VOICEMAIL_NUMBER + * @see #EXTRA_CALL_VOICEMAIL_INTENT + * @see #EXTRA_LAUNCH_VOICEMAIL_SETTINGS_INTENT */ - @SystemApi public static final String ACTION_SHOW_VOICEMAIL_NOTIFICATION = "android.telephony.action.SHOW_VOICEMAIL_NOTIFICATION"; /** * The number of voice messages associated with the notification. - * @hide */ - @SystemApi public static final String EXTRA_NOTIFICATION_COUNT = "android.telephony.extra.NOTIFICATION_COUNT"; /** * The voicemail number. - * @hide */ - @SystemApi public static final String EXTRA_VOICEMAIL_NUMBER = "android.telephony.extra.VOICEMAIL_NUMBER"; /** * The intent to call voicemail. - * @hide */ - @SystemApi public static final String EXTRA_CALL_VOICEMAIL_INTENT = "android.telephony.extra.CALL_VOICEMAIL_INTENT"; /** * The intent to launch voicemail settings. - * @hide */ - @SystemApi public static final String EXTRA_LAUNCH_VOICEMAIL_SETTINGS_INTENT = "android.telephony.extra.LAUNCH_VOICEMAIL_SETTINGS_INTENT"; diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index 4a6fb13d2073..34acebfef52b 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -728,10 +728,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { static private void waitFor(Criteria criteria) { int delays = 0; while (!criteria.get()) { - try { - Thread.sleep(50); - } catch (InterruptedException e) { - } + sleepFor(50); if (++delays == 10) fail(); } } @@ -2313,10 +2310,30 @@ public class ConnectivityServiceTest extends AndroidTestCase { networkCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent); // pass timeout and validate that UNAVAILABLE is not called - try { - Thread.sleep(15); - } catch (InterruptedException e) { - } + sleepFor(15); + networkCallback.assertNoCallback(); + } + + /** + * Validate that a satisfied network request followed by a disconnected (lost) network does + * not trigger onUnavailable() once the time-out period expires. + */ + @SmallTest + public void testSatisfiedThenLostNetworkRequestDoesNotTriggerOnUnavailable() { + NetworkRequest nr = new NetworkRequest.Builder().addTransportType( + NetworkCapabilities.TRANSPORT_WIFI).build(); + final TestNetworkCallback networkCallback = new TestNetworkCallback(); + mCm.requestNetwork(nr, networkCallback, 500); + + mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); + mWiFiNetworkAgent.connect(false); + networkCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent); + sleepFor(20); + mWiFiNetworkAgent.disconnect(); + networkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent); + + // pass timeout and validate that UNAVAILABLE is not called + sleepFor(600); networkCallback.assertNoCallback(); } @@ -2358,10 +2375,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { // pass timeout and validate that no callbacks // Note: doesn't validate that nothing called from CS since even if called the CM already // unregisters the callback and won't pass it through! - try { - Thread.sleep(15); - } catch (InterruptedException e) { - } + sleepFor(15); networkCallback.assertNoCallback(); // create a network satisfying request - validate that request not triggered @@ -2775,4 +2789,13 @@ public class ConnectivityServiceTest extends AndroidTestCase { mCm.unregisterNetworkCallback(pendingIntent); } } + + /* test utilities */ + static private void sleepFor(int ms) { + try { + Thread.sleep(ms); + } catch (InterruptedException e) { + } + + } } diff --git a/wifi/java/android/net/wifi/aware/PublishConfig.java b/wifi/java/android/net/wifi/aware/PublishConfig.java index 5d3ad0582f9c..ba493a024a13 100644 --- a/wifi/java/android/net/wifi/aware/PublishConfig.java +++ b/wifi/java/android/net/wifi/aware/PublishConfig.java @@ -32,9 +32,8 @@ import java.util.Arrays; /** * Defines the configuration of a Aware publish session. Built using * {@link PublishConfig.Builder}. A publish session is created using - * {@link WifiAwareSession#publish(android.os.Handler, PublishConfig, - * WifiAwareDiscoverySessionCallback)} - * or updated using + * {@link WifiAwareSession#publish(PublishConfig, WifiAwareDiscoverySessionCallback, + * android.os.Handler)} or updated using * {@link WifiAwarePublishDiscoverySession#updatePublish(PublishConfig)}. * * @hide PROPOSED_AWARE_API diff --git a/wifi/java/android/net/wifi/aware/SubscribeConfig.java b/wifi/java/android/net/wifi/aware/SubscribeConfig.java index 2a6cc93146b4..5e14f8f761e0 100644 --- a/wifi/java/android/net/wifi/aware/SubscribeConfig.java +++ b/wifi/java/android/net/wifi/aware/SubscribeConfig.java @@ -32,9 +32,8 @@ import java.util.Arrays; /** * Defines the configuration of a Aware subscribe session. Built using * {@link SubscribeConfig.Builder}. Subscribe is done using - * {@link WifiAwareSession#subscribe(android.os.Handler, SubscribeConfig, - * WifiAwareDiscoverySessionCallback)} - * or + * {@link WifiAwareSession#subscribe(SubscribeConfig, WifiAwareDiscoverySessionCallback, + * android.os.Handler)} or * {@link WifiAwareSubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}. * * @hide PROPOSED_AWARE_API @@ -403,8 +402,8 @@ public final class SubscribeConfig implements Parcelable { * Sets the match style of the subscription - how are matches from a * single match session (corresponding to the same publish action on the * peer) reported to the host (using the - * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(Object, byte[], byte[])} - * ). The options are: only report the first match and ignore the rest + * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle, + * byte[], byte[])}). The options are: only report the first match and ignore the rest * {@link SubscribeConfig#MATCH_STYLE_FIRST_ONLY} or report every single * match {@link SubscribeConfig#MATCH_STYLE_ALL} (the default). * diff --git a/wifi/java/android/net/wifi/aware/WifiAwareAttachCallback.java b/wifi/java/android/net/wifi/aware/WifiAwareAttachCallback.java index 2cace6143f4f..1e8dbd945b6e 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareAttachCallback.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareAttachCallback.java @@ -18,7 +18,7 @@ package android.net.wifi.aware; /** * Base class for Aware attach callbacks. Should be extended by applications and set when calling - * {@link WifiAwareManager#attach(android.os.Handler, WifiAwareAttachCallback)}. These are callbacks + * {@link WifiAwareManager#attach(WifiAwareAttachCallback, android.os.Handler)}. These are callbacks * applying to the Aware connection as a whole - not to specific publish or subscribe sessions - * for that see {@link WifiAwareDiscoverySessionCallback}. * @@ -27,7 +27,7 @@ package android.net.wifi.aware; public class WifiAwareAttachCallback { /** * Called when Aware attach operation - * {@link WifiAwareManager#attach(android.os.Handler, WifiAwareAttachCallback)} + * {@link WifiAwareManager#attach(WifiAwareAttachCallback, android.os.Handler)} * is completed and that we can now start discovery sessions or connections. * * @param session The Aware object on which we can execute further Aware operations - e.g. @@ -39,7 +39,7 @@ public class WifiAwareAttachCallback { /** * Called when Aware attach operation - * {@link WifiAwareManager#attach(android.os.Handler, WifiAwareAttachCallback)} failed. + * {@link WifiAwareManager#attach(WifiAwareAttachCallback, android.os.Handler)} failed. */ public void onAttachFailed() { /* empty */ diff --git a/wifi/java/android/net/wifi/aware/WifiAwareCharacteristics.java b/wifi/java/android/net/wifi/aware/WifiAwareCharacteristics.java index 6232c14e0f18..072ccab1eb96 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareCharacteristics.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareCharacteristics.java @@ -58,7 +58,8 @@ public class WifiAwareCharacteristics implements Parcelable { * message exchange. Restricts the parameters of the * {@link PublishConfig.Builder#setServiceSpecificInfo(byte[])}, * {@link SubscribeConfig.Builder#setServiceSpecificInfo(byte[])}, and - * {@link WifiAwareDiscoveryBaseSession#sendMessage(Object, int, byte[])} variants. + * {@link WifiAwareDiscoveryBaseSession#sendMessage(WifiAwareManager.PeerHandle, int, byte[])} + * variants. * * @return A positive integer, maximum length of byte array for Aware messaging. */ diff --git a/wifi/java/android/net/wifi/aware/WifiAwareDiscoveryBaseSession.java b/wifi/java/android/net/wifi/aware/WifiAwareDiscoveryBaseSession.java index 07f752396d3d..e8335d11407a 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareDiscoveryBaseSession.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareDiscoveryBaseSession.java @@ -32,10 +32,10 @@ import java.lang.ref.WeakReference; * {@link WifiAwarePublishDiscoverySession} and {@link WifiAwareSubscribeDiscoverySession}. This * class provides functionality common to both publish and subscribe discovery sessions: * <ul> - * <li>Sending messages: {@link #sendMessage(Object, int, byte[])} or - * {@link #sendMessage(Object, int, byte[], int)} methods. + * <li>Sending messages: {@link #sendMessage(WifiAwareManager.PeerHandle, int, byte[])} or + * {@link #sendMessage(WifiAwareManager.PeerHandle, int, byte[], int)} methods. * <li>Creating a network-specifier when requesting a Aware connection: - * {@link #createNetworkSpecifier(int, Object, byte[])}. + * {@link #createNetworkSpecifier(int, WifiAwareManager.PeerHandle, byte[])}. * </ul> * The {@link #destroy()} method must be called to destroy discovery sessions once they are * no longer needed. @@ -62,7 +62,7 @@ public class WifiAwareDiscoveryBaseSession { /** * Return the maximum permitted retry count when sending messages using - * {@link #sendMessage(Object, int, byte[], int)}. + * {@link #sendMessage(WifiAwareManager.PeerHandle, int, byte[], int)}. * * @return Maximum retry count when sending messages. */ @@ -139,21 +139,24 @@ public class WifiAwareDiscoveryBaseSession { /** * Sends a message to the specified destination. Aware messages are transmitted in the context * of a discovery session - executed subsequent to a publish/subscribe - * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(Object, byte[], byte[])} event. + * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle, + * byte[], byte[])} event. * <p> * Aware messages are not guaranteed delivery. Callbacks on * {@link WifiAwareDiscoverySessionCallback} indicate message was transmitted successfully, - * {@link WifiAwareDiscoverySessionCallback#onMessageSent(int)}, or transmission failed - * (possibly after several retries) - + * {@link WifiAwareDiscoverySessionCallback#onMessageSendSucceeded(int)}, or transmission + * failed (possibly after several retries) - * {@link WifiAwareDiscoverySessionCallback#onMessageSendFailed(int)}. * <p> * The peer will get a callback indicating a message was received using - * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(Object, byte[])}. + * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(WifiAwareManager.PeerHandle, + * byte[])}. * * @param peerHandle The peer's handle for the message. Must be a result of an - * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(Object, byte[], byte[])} - * or - * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(Object, byte[])} events. + * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle, + * byte[], byte[])} or + * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(WifiAwareManager.PeerHandle, + * byte[])} events. * @param messageId An arbitrary integer used by the caller to identify the message. The same * integer ID will be returned in the callbacks indicating message send success or * failure. The {@code messageId} is not used internally by the Aware service - it @@ -164,8 +167,8 @@ public class WifiAwareDiscoveryBaseSession { * (note: no retransmissions are attempted in other failure cases). A value of 0 * indicates no retries. Max permitted value is {@link #getMaxSendRetryCount()}. */ - public void sendMessage(@NonNull Object peerHandle, int messageId, @Nullable byte[] message, - int retryCount) { + public void sendMessage(@NonNull WifiAwareManager.PeerHandle peerHandle, int messageId, + @Nullable byte[] message, int retryCount) { if (mTerminated) { Log.w(TAG, "sendMessage: called on terminated session"); return; @@ -183,37 +186,43 @@ public class WifiAwareDiscoveryBaseSession { /** * Sends a message to the specified destination. Aware messages are transmitted in the context * of a discovery session - executed subsequent to a publish/subscribe - * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(Object, byte[], byte[])} event. + * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle, + * byte[], byte[])} event. * <p> * Aware messages are not guaranteed delivery. Callbacks on * {@link WifiAwareDiscoverySessionCallback} indicate message was transmitted successfully, - * {@link WifiAwareDiscoverySessionCallback#onMessageSent(int)}, or transmission failed - * (possibly after several retries) - + * {@link WifiAwareDiscoverySessionCallback#onMessageSendSucceeded(int)}, or transmission + * failed (possibly after several retries) - * {@link WifiAwareDiscoverySessionCallback#onMessageSendFailed(int)}. * <p> - * The peer will get a callback indicating a message was received using - * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(Object, byte[])}. - * Equivalent to {@link #sendMessage(Object, int, byte[], int)} with a {@code retryCount} of - * 0. + * The peer will get a callback indicating a message was received using + * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(WifiAwareManager.PeerHandle, + * byte[])}. + * Equivalent to {@link #sendMessage(WifiAwareManager.PeerHandle, int, byte[], int)} + * with a {@code retryCount} of 0. * * @param peerHandle The peer's handle for the message. Must be a result of an - * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(Object, byte[], byte[])} - * or - * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(Object, byte[])} events. + * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle, + * byte[], byte[])} or + * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(WifiAwareManager.PeerHandle, + * byte[])} events. * @param messageId An arbitrary integer used by the caller to identify the message. The same * integer ID will be returned in the callbacks indicating message send success or * failure. The {@code messageId} is not used internally by the Aware service - it * can be arbitrary and non-unique. * @param message The message to be transmitted. */ - public void sendMessage(@NonNull Object peerHandle, int messageId, @Nullable byte[] message) { + public void sendMessage(@NonNull WifiAwareManager.PeerHandle peerHandle, int messageId, + @Nullable byte[] message) { sendMessage(peerHandle, messageId, message, 0); } /** * Start a ranging operation with the specified peers. The peer IDs are obtained from an - * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(Object, byte[], byte[])} or - * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(Object, byte[])} operation - can + * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle, + * byte[], byte[])} or + * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(WifiAwareManager.PeerHandle, + * byte[])} operation - can * only range devices which are part of an ongoing discovery session. * * @param params RTT parameters - each corresponding to a specific peer ID (the array sizes @@ -256,11 +265,12 @@ public class WifiAwareDiscoveryBaseSession { * {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_INITIATOR} or * {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_RESPONDER} * @param peerHandle The peer's handle obtained through - * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(Object, byte[], byte[])} or - * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(Object, byte[])}. On a RESPONDER - * this value is used to gate the acceptance of a connection request from only - * that peer. A RESPONDER may specified a null - indicating that it will accept - * connection requests from any device. + * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle, + * byte[], byte[])} or + * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(WifiAwareManager.PeerHandle, + * byte[])}. On a RESPONDER this value is used to gate the acceptance of a connection request + * from only that peer. A RESPONDER may specified a null - indicating that + * it will accept connection requests from any device. * @param token An arbitrary token (message) to be used to match connection initiation request * to a responder setup. A RESPONDER is set up with a {@code token} which must * be matched by the token provided by the INITIATOR. A null token is permitted @@ -274,7 +284,7 @@ public class WifiAwareDiscoveryBaseSession { * [or other varieties of that API]. */ public String createNetworkSpecifier(@WifiAwareManager.DataPathRole int role, - @Nullable Object peerHandle, @Nullable byte[] token) { + @Nullable WifiAwareManager.PeerHandle peerHandle, @Nullable byte[] token) { if (mTerminated) { Log.w(TAG, "createNetworkSpecifier: called on terminated session"); return null; diff --git a/wifi/java/android/net/wifi/aware/WifiAwareDiscoverySessionCallback.java b/wifi/java/android/net/wifi/aware/WifiAwareDiscoverySessionCallback.java index 9dfa24fd7232..6331c9c726c9 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareDiscoverySessionCallback.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareDiscoverySessionCallback.java @@ -26,11 +26,10 @@ import java.lang.annotation.RetentionPolicy; * Base class for Aware session events callbacks. Should be extended by * applications wanting notifications. The callbacks are set when a * publish or subscribe session is created using - * {@link WifiAwareSession#publish(android.os.Handler, PublishConfig, - * WifiAwareDiscoverySessionCallback)} - * or - * {@link WifiAwareSession#subscribe(android.os.Handler, SubscribeConfig, - * WifiAwareDiscoverySessionCallback)} . + * {@link WifiAwareSession#publish(PublishConfig, WifiAwareDiscoverySessionCallback, + * android.os.Handler)} or + * {@link WifiAwareSession#subscribe(SubscribeConfig, WifiAwareDiscoverySessionCallback, + * android.os.Handler)}. * <p> * A single callback is set at session creation - it cannot be replaced. * @@ -62,9 +61,8 @@ public class WifiAwareDiscoverySessionCallback { /** * Called when a publish operation is started successfully in response to a - * {@link WifiAwareSession#publish(android.os.Handler, PublishConfig, - * WifiAwareDiscoverySessionCallback)} - * operation. + * {@link WifiAwareSession#publish(PublishConfig, WifiAwareDiscoverySessionCallback, + * android.os.Handler)} operation. * * @param session The {@link WifiAwarePublishDiscoverySession} used to control the * discovery session. @@ -75,9 +73,8 @@ public class WifiAwareDiscoverySessionCallback { /** * Called when a subscribe operation is started successfully in response to a - * {@link WifiAwareSession#subscribe(android.os.Handler, SubscribeConfig, - * WifiAwareDiscoverySessionCallback)} - * operation. + * {@link WifiAwareSession#subscribe(SubscribeConfig, WifiAwareDiscoverySessionCallback, + * android.os.Handler)} operation. * * @param session The {@link WifiAwareSubscribeDiscoverySession} used to control the * discovery session. @@ -98,12 +95,10 @@ public class WifiAwareDiscoverySessionCallback { /** * Called when a publish or subscribe discovery session cannot be created: - * {@link WifiAwareSession#publish(android.os.Handler, PublishConfig, - * WifiAwareDiscoverySessionCallback)} - * or - * {@link WifiAwareSession#subscribe(android.os.Handler, SubscribeConfig, - * WifiAwareDiscoverySessionCallback)}, - * or when a configuration update fails: + * {@link WifiAwareSession#publish(PublishConfig, WifiAwareDiscoverySessionCallback, + * android.os.Handler)} or + * {@link WifiAwareSession#subscribe(SubscribeConfig, WifiAwareDiscoverySessionCallback, + * android.os.Handler)}, or when a configuration update fails: * {@link WifiAwarePublishDiscoverySession#updatePublish(PublishConfig)} or * {@link WifiAwareSubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}. * <p> @@ -138,13 +133,14 @@ public class WifiAwareDiscoverySessionCallback { * @param matchFilter The filter (Tx on advertiser and Rx on listener) which * resulted in this service discovery. */ - public void onServiceDiscovered(Object peerHandle, byte[] serviceSpecificInfo, - byte[] matchFilter) { + public void onServiceDiscovered(WifiAwareManager.PeerHandle peerHandle, + byte[] serviceSpecificInfo, byte[] matchFilter) { /* empty */ } /** - * Called in response to {@link WifiAwareDiscoveryBaseSession#sendMessage(Object, int, byte[])} + * Called in response to + * {@link WifiAwareDiscoveryBaseSession#sendMessage(WifiAwareManager.PeerHandle, int, byte[])} * when a message is transmitted successfully - i.e. when it was received successfully by the * peer (corresponds to an ACK being received). * <p> @@ -154,18 +150,18 @@ public class WifiAwareDiscoverySessionCallback { * * @param messageId The arbitrary message ID specified when sending the message. */ - public void onMessageSent(@SuppressWarnings("unused") int messageId) { + public void onMessageSendSucceeded(@SuppressWarnings("unused") int messageId) { /* empty */ } /** * Called when message transmission fails - when no ACK is received from the peer. * Retries when ACKs are not received are done by hardware, MAC, and in the Aware stack (using - * the {@link WifiAwareDiscoveryBaseSession#sendMessage(Object, int, byte[], int)} method) - - * this event is received after all retries are exhausted. + * the {@link WifiAwareDiscoveryBaseSession#sendMessage(WifiAwareManager.PeerHandle, int, + * byte[], int)} method) - this event is received after all retries are exhausted. * <p> * Note that either this callback or - * {@link WifiAwareDiscoverySessionCallback#onMessageSent(int)} will be received + * {@link WifiAwareDiscoverySessionCallback#onMessageSendSucceeded(int)} will be received * - never both. * * @param messageId The arbitrary message ID specified when sending the message. @@ -176,13 +172,14 @@ public class WifiAwareDiscoverySessionCallback { /** * Called when a message is received from a discovery session peer - in response to the - * peer's {@link WifiAwareDiscoveryBaseSession#sendMessage(Object, int, byte[])} or - * {@link WifiAwareDiscoveryBaseSession#sendMessage(Object, int, byte[], int)}. + * peer's {@link WifiAwareDiscoveryBaseSession#sendMessage(WifiAwareManager.PeerHandle, int, + * byte[])} or {@link WifiAwareDiscoveryBaseSession#sendMessage(WifiAwareManager.PeerHandle, + * int, byte[], int)}. * * @param peerHandle An opaque handle to the peer matching our discovery operation. * @param message A byte array containing the message. */ - public void onMessageReceived(Object peerHandle, byte[] message) { + public void onMessageReceived(WifiAwareManager.PeerHandle peerHandle, byte[] message) { /* empty */ } } diff --git a/wifi/java/android/net/wifi/aware/WifiAwareManager.java b/wifi/java/android/net/wifi/aware/WifiAwareManager.java index 10b70abad9df..a34ef4777d65 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareManager.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareManager.java @@ -56,14 +56,14 @@ import java.util.Arrays; * The class provides access to: * <ul> * <li>Initialize a Aware cluster (peer-to-peer synchronization). Refer to - * {@link #attach(Handler, WifiAwareAttachCallback)}. + * {@link #attach(WifiAwareAttachCallback, Handler)}. * <li>Create discovery sessions (publish or subscribe sessions). Refer to - * {@link WifiAwareSession#publish(Handler, PublishConfig, WifiAwareDiscoverySessionCallback)} and - * {@link WifiAwareSession#subscribe(Handler, SubscribeConfig, WifiAwareDiscoverySessionCallback)}. + * {@link WifiAwareSession#publish(PublishConfig, WifiAwareDiscoverySessionCallback, Handler)} and + * {@link WifiAwareSession#subscribe(SubscribeConfig, WifiAwareDiscoverySessionCallback, Handler)}. * <li>Create a Aware network specifier to be used with * {@link ConnectivityManager#requestNetwork(NetworkRequest, ConnectivityManager.NetworkCallback)} * to set-up a Aware connection with a peer. Refer to - * {@link WifiAwareDiscoveryBaseSession#createNetworkSpecifier(int, Object, byte[])} and + * {@link WifiAwareDiscoveryBaseSession#createNetworkSpecifier(int, PeerHandle, byte[])} and * {@link WifiAwareSession#createNetworkSpecifier(int, byte[], byte[])}. * </ul> * <p> @@ -73,7 +73,7 @@ import java.util.Arrays; * broadcast. Note that this broadcast is not sticky - you should register for it and then * check the above API to avoid a race condition. * <p> - * An application must use {@link #attach(Handler, WifiAwareAttachCallback)} to initialize a + * An application must use {@link #attach(WifiAwareAttachCallback, Handler)} to initialize a * Aware cluster - before making any other Aware operation. Aware cluster membership is a * device-wide operation - the API guarantees that the device is in a cluster or joins a * Aware cluster (or starts one if none can be found). Information about attach success (or @@ -86,12 +86,11 @@ import java.util.Arrays; * application detaches. * <p> * Once a Aware attach is confirmed use the - * {@link WifiAwareSession#publish(Handler, PublishConfig, WifiAwareDiscoverySessionCallback)} + * {@link WifiAwareSession#publish(PublishConfig, WifiAwareDiscoverySessionCallback, Handler)} * or - * {@link WifiAwareSession#subscribe(Handler, SubscribeConfig, - * WifiAwareDiscoverySessionCallback)} - * to create publish or subscribe Aware discovery sessions. Events are called on the provided - * callback object {@link WifiAwareDiscoverySessionCallback}. Specifically, the + * {@link WifiAwareSession#subscribe(SubscribeConfig, WifiAwareDiscoverySessionCallback, + * Handler)} to create publish or subscribe Aware discovery sessions. Events are called on the + * provided callback object {@link WifiAwareDiscoverySessionCallback}. Specifically, the * {@link WifiAwareDiscoverySessionCallback#onPublishStarted(WifiAwarePublishDiscoverySession)} * and * {@link WifiAwareDiscoverySessionCallback#onSubscribeStarted( @@ -102,7 +101,7 @@ import java.util.Arrays; * the session {@link WifiAwarePublishDiscoverySession#updatePublish(PublishConfig)} and * {@link WifiAwareSubscribeDiscoverySession#updateSubscribe(SubscribeConfig)}. Sessions can * also be used to send messages using the - * {@link WifiAwareDiscoveryBaseSession#sendMessage(Object, int, byte[])} APIs. When an + * {@link WifiAwareDiscoveryBaseSession#sendMessage(PeerHandle, int, byte[])} APIs. When an * application is finished with a discovery session it <b>must</b> terminate it using the * {@link WifiAwareDiscoveryBaseSession#destroy()} API. * <p> @@ -115,7 +114,7 @@ import java.util.Arrays; * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}. * <li>{@link NetworkRequest.Builder#setNetworkSpecifier(String)} using * {@link WifiAwareSession#createNetworkSpecifier(int, byte[], byte[])} or - * {@link WifiAwareDiscoveryBaseSession#createNetworkSpecifier(int, Object, byte[])}. + * {@link WifiAwareDiscoveryBaseSession#createNetworkSpecifier(int, PeerHandle, byte[])}. * </ul> * * @hide PROPOSED_AWARE_API @@ -225,7 +224,7 @@ public class WifiAwareManager { * Connection creation role is that of INITIATOR. Used to create a network specifier string * when requesting a Aware network. * - * @see WifiAwareDiscoveryBaseSession#createNetworkSpecifier(int, Object, byte[]) + * @see WifiAwareDiscoveryBaseSession#createNetworkSpecifier(int, PeerHandle, byte[]) * @see WifiAwareSession#createNetworkSpecifier(int, byte[], byte[]) */ public static final int WIFI_AWARE_DATA_PATH_ROLE_INITIATOR = 0; @@ -234,7 +233,7 @@ public class WifiAwareManager { * Connection creation role is that of RESPONDER. Used to create a network specifier string * when requesting a Aware network. * - * @see WifiAwareDiscoveryBaseSession#createNetworkSpecifier(int, Object, byte[]) + * @see WifiAwareDiscoveryBaseSession#createNetworkSpecifier(int, PeerHandle, byte[]) * @see WifiAwareSession#createNetworkSpecifier(int, byte[], byte[]) */ public static final int WIFI_AWARE_DATA_PATH_ROLE_RESPONDER = 1; @@ -326,13 +325,13 @@ public class WifiAwareManager { * then this function will simply indicate success immediately using the same {@code * attachCallback}. * + * @param attachCallback A callback for attach events, extended from + * {@link WifiAwareAttachCallback}. * @param handler The Handler on whose thread to execute the callbacks of the {@code * attachCallback} object. If a null is provided then the application's main thread will be * used. - * @param attachCallback A callback for attach events, extended from - * {@link WifiAwareAttachCallback}. */ - public void attach(@Nullable Handler handler, @NonNull WifiAwareAttachCallback attachCallback) { + public void attach(@NonNull WifiAwareAttachCallback attachCallback, @Nullable Handler handler) { attach(handler, null, attachCallback, null); } @@ -352,20 +351,21 @@ public class WifiAwareManager { * on startup and whenever it is updated (it is randomized at regular intervals for privacy). * The application must have the {@link android.Manifest.permission#ACCESS_COARSE_LOCATION} * permission to execute this attach request. Otherwise, use the - * {@link #attach(Handler, WifiAwareAttachCallback)} version. Note that aside from permission + * {@link #attach(WifiAwareAttachCallback, Handler)} version. Note that aside from permission * requirements this listener will wake up the host at regular intervals causing higher power * consumption, do not use it unless the information is necessary (e.g. for OOB discovery). * - * @param handler The Handler on whose thread to execute the callbacks of the {@code - * attachCallback} and {@code identityChangedListener} objects. If a null is provided then the - * application's main thread will be used. * @param attachCallback A callback for attach events, extended from * {@link WifiAwareAttachCallback}. * @param identityChangedListener A listener for changed identity, extended from * {@link WifiAwareIdentityChangedListener}. + * @param handler The Handler on whose thread to execute the callbacks of the {@code + * attachCallback} and {@code identityChangedListener} objects. If a null is provided then the + * application's main thread will be used. */ - public void attach(@Nullable Handler handler, @NonNull WifiAwareAttachCallback attachCallback, - @NonNull WifiAwareIdentityChangedListener identityChangedListener) { + public void attach(@NonNull WifiAwareAttachCallback attachCallback, + @NonNull WifiAwareIdentityChangedListener identityChangedListener, + @Nullable Handler handler) { attach(handler, null, attachCallback, identityChangedListener); } @@ -481,7 +481,7 @@ public class WifiAwareManager { } /** @hide */ - public void sendMessage(int clientId, int sessionId, Object peerHandle, byte[] message, + public void sendMessage(int clientId, int sessionId, PeerHandle peerHandle, byte[] message, int messageId, int retryCount) { if (peerHandle == null) { throw new IllegalArgumentException( @@ -490,13 +490,13 @@ public class WifiAwareManager { if (VDBG) { Log.v(TAG, "sendMessage(): clientId=" + clientId + ", sessionId=" + sessionId - + ", peerHandle=" + ((OpaquePeerHandle) peerHandle).peerId + ", messageId=" + + ", peerHandle=" + peerHandle.peerId + ", messageId=" + messageId + ", retryCount=" + retryCount); } try { - mService.sendMessage(clientId, sessionId, ((OpaquePeerHandle) peerHandle).peerId, - message, messageId, retryCount); + mService.sendMessage(clientId, sessionId, peerHandle.peerId, message, messageId, + retryCount); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -524,12 +524,12 @@ public class WifiAwareManager { } /** @hide */ - public String createNetworkSpecifier(int clientId, int role, int sessionId, Object peerHandle, - byte[] token) { + public String createNetworkSpecifier(int clientId, int role, int sessionId, + PeerHandle peerHandle, byte[] token) { if (VDBG) { Log.v(TAG, "createNetworkSpecifier: role=" + role + ", sessionId=" + sessionId - + ", peerHandle=" + ((peerHandle == null) ? peerHandle - : ((OpaquePeerHandle) peerHandle).peerId) + ", token=" + token); + + ", peerHandle=" + ((peerHandle == null) ? peerHandle : peerHandle.peerId) + + ", token=" + token); } int type; @@ -569,7 +569,7 @@ public class WifiAwareManager { json.put(NETWORK_SPECIFIER_KEY_CLIENT_ID, clientId); json.put(NETWORK_SPECIFIER_KEY_SESSION_ID, sessionId); if (peerHandle != null) { - json.put(NETWORK_SPECIFIER_KEY_PEER_ID, ((OpaquePeerHandle) peerHandle).peerId); + json.put(NETWORK_SPECIFIER_KEY_PEER_ID, peerHandle.peerId); } if (token != null) { json.put(NETWORK_SPECIFIER_KEY_TOKEN, @@ -876,18 +876,18 @@ public class WifiAwareManager { break; case CALLBACK_MATCH: mOriginalCallback.onServiceDiscovered( - new OpaquePeerHandle(msg.arg1), + new PeerHandle(msg.arg1), msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE), msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE2)); break; case CALLBACK_MESSAGE_SEND_SUCCESS: - mOriginalCallback.onMessageSent(msg.arg1); + mOriginalCallback.onMessageSendSucceeded(msg.arg1); break; case CALLBACK_MESSAGE_SEND_FAIL: mOriginalCallback.onMessageSendFailed(msg.arg1); break; case CALLBACK_MESSAGE_RECEIVED: - mOriginalCallback.onMessageReceived(new OpaquePeerHandle(msg.arg1), + mOriginalCallback.onMessageReceived(new PeerHandle(msg.arg1), (byte[]) msg.obj); break; } @@ -1019,12 +1019,14 @@ public class WifiAwareManager { } } - /** @hide */ - public static class OpaquePeerHandle { - public OpaquePeerHandle(int peerId) { + /** @hide PROPOSED_AWARE_API */ + public static class PeerHandle { + /** @hide */ + public PeerHandle(int peerId) { this.peerId = peerId; } + /** @hide */ public int peerId; } } diff --git a/wifi/java/android/net/wifi/aware/WifiAwarePublishDiscoverySession.java b/wifi/java/android/net/wifi/aware/WifiAwarePublishDiscoverySession.java index 610a92ce28b5..68786d17d38d 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwarePublishDiscoverySession.java +++ b/wifi/java/android/net/wifi/aware/WifiAwarePublishDiscoverySession.java @@ -21,9 +21,8 @@ import android.util.Log; /** * A class representing a Aware publish session. Created when - * {@link WifiAwareSession#publish(android.os.Handler, PublishConfig, - * WifiAwareDiscoverySessionCallback)} - * is called and a discovery session is created and returned in + * {@link WifiAwareSession#publish(PublishConfig, WifiAwareDiscoverySessionCallback, + * android.os.Handler)} is called and a discovery session is created and returned in * {@link WifiAwareDiscoverySessionCallback#onPublishStarted(WifiAwarePublishDiscoverySession)}. See * baseline functionality of all discovery sessions in {@link WifiAwareDiscoveryBaseSession}. This * object allows updating an existing/running publish discovery session using diff --git a/wifi/java/android/net/wifi/aware/WifiAwareSession.java b/wifi/java/android/net/wifi/aware/WifiAwareSession.java index 357bd43f12db..acb60a4480d4 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareSession.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareSession.java @@ -65,7 +65,7 @@ public class WifiAwareSession { * session-wide destroy. * <p> * An application may re-attach after a destroy using - * {@link WifiAwareManager#attach(Handler, WifiAwareAttachCallback)} . + * {@link WifiAwareManager#attach(WifiAwareAttachCallback, Handler)} . */ public void destroy() { WifiAwareManager mgr = mMgr.get(); @@ -116,15 +116,15 @@ public class WifiAwareSession { * <p>The application must have the {@link android.Manifest.permission#ACCESS_COARSE_LOCATION} * permission to start a publish discovery session. * - * @param handler The Handler on whose thread to execute the callbacks of the {@code - * callback} object. If a null is provided then the application's main thread will be used. * @param publishConfig The {@link PublishConfig} specifying the * configuration of the requested publish session. * @param callback A {@link WifiAwareDiscoverySessionCallback} derived object to be used for * session event callbacks. + * @param handler The Handler on whose thread to execute the callbacks of the {@code + * callback} object. If a null is provided then the application's main thread will be used. */ - public void publish(@Nullable Handler handler, @NonNull PublishConfig publishConfig, - @NonNull WifiAwareDiscoverySessionCallback callback) { + public void publish(@NonNull PublishConfig publishConfig, + @NonNull WifiAwareDiscoverySessionCallback callback, @Nullable Handler handler) { WifiAwareManager mgr = mMgr.get(); if (mgr == null) { Log.e(TAG, "publish: called post GC on WifiAwareManager"); @@ -162,15 +162,15 @@ public class WifiAwareSession { * <p>The application must have the {@link android.Manifest.permission#ACCESS_COARSE_LOCATION} * permission to start a subscribe discovery session. * - * @param handler The Handler on whose thread to execute the callbacks of the {@code - * callback} object. If a null is provided then the application's main thread will be used. * @param subscribeConfig The {@link SubscribeConfig} specifying the * configuration of the requested subscribe session. * @param callback A {@link WifiAwareDiscoverySessionCallback} derived object to be used for * session event callbacks. + * @param handler The Handler on whose thread to execute the callbacks of the {@code + * callback} object. If a null is provided then the application's main thread will be used. */ - public void subscribe(@Nullable Handler handler, @NonNull SubscribeConfig subscribeConfig, - @NonNull WifiAwareDiscoverySessionCallback callback) { + public void subscribe(@NonNull SubscribeConfig subscribeConfig, + @NonNull WifiAwareDiscoverySessionCallback callback, @Nullable Handler handler) { WifiAwareManager mgr = mMgr.get(); if (mgr == null) { Log.e(TAG, "publish: called post GC on WifiAwareManager"); @@ -193,7 +193,8 @@ public class WifiAwareSession { * This API is targeted for applications which can obtain the peer MAC address using OOB * (out-of-band) discovery. Aware discovery does not provide the MAC address of the peer - * when using Aware discovery use the alternative network specifier method - - * {@link WifiAwareDiscoveryBaseSession#createNetworkSpecifier(int, Object, byte[])}. + * {@link WifiAwareDiscoveryBaseSession#createNetworkSpecifier(int, + * WifiAwareManager.PeerHandle, byte[])}. * * @param role The role of this device: * {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_INITIATOR} or diff --git a/wifi/java/android/net/wifi/aware/WifiAwareSubscribeDiscoverySession.java b/wifi/java/android/net/wifi/aware/WifiAwareSubscribeDiscoverySession.java index 7c48f549eaf4..a0ec8093a3ab 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareSubscribeDiscoverySession.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareSubscribeDiscoverySession.java @@ -21,8 +21,8 @@ import android.util.Log; /** * A class representing a Aware subscribe session. Created when - * {@link WifiAwareSession#subscribe(android.os.Handler, SubscribeConfig, - * WifiAwareDiscoverySessionCallback)} + * {@link WifiAwareSession#subscribe(SubscribeConfig, + * WifiAwareDiscoverySessionCallback, android.os.Handler)} * is called and a discovery session is created and returned in * {@link WifiAwareDiscoverySessionCallback#onSubscribeStarted(WifiAwareSubscribeDiscoverySession)}. * See baseline functionality of all discovery sessions in {@link WifiAwareDiscoveryBaseSession}. diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java index a62a0fb582f1..643753abf5dc 100644 --- a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java +++ b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java @@ -36,6 +36,27 @@ public final class PasspointConfiguration implements Parcelable { public HomeSP homeSp = null; public Credential credential = null; + /** + * Constructor for creating PasspointConfiguration with default values. + */ + public PasspointConfiguration() {} + + /** + * Copy constructor. + * + * @param source The source to copy from + */ + public PasspointConfiguration(PasspointConfiguration source) { + if (source != null) { + if (source.homeSp != null) { + homeSp = new HomeSP(source.homeSp); + } + if (source.credential != null) { + credential = new Credential(source.credential); + } + } + } + @Override public int describeContents() { return 0; diff --git a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java index 57e65eb7a190..790dfaf643ca 100644 --- a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java +++ b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java @@ -109,6 +109,25 @@ public final class Credential implements Parcelable { */ public String nonEapInnerMethod = null; + /** + * Constructor for creating UserCredential with default values. + */ + public UserCredential() {} + + /** + * Copy constructor. + * + * @param source The source to copy from + */ + public UserCredential(UserCredential source) { + if (source != null) { + username = source.username; + password = source.password; + eapType = source.eapType; + nonEapInnerMethod = source.nonEapInnerMethod; + } + } + @Override public int describeContents() { return 0; @@ -221,6 +240,26 @@ public final class Credential implements Parcelable { */ public byte[] certSha256FingerPrint = null; + /** + * Constructor for creating CertificateCredential with default values. + */ + public CertificateCredential() {} + + /** + * Copy constructor. + * + * @param source The source to copy from + */ + public CertificateCredential(CertificateCredential source) { + if (source != null) { + certType = source.certType; + if (source.certSha256FingerPrint != null) { + certSha256FingerPrint = Arrays.copyOf(source.certSha256FingerPrint, + source.certSha256FingerPrint.length); + } + } + } + @Override public int describeContents() { return 0; @@ -307,6 +346,23 @@ public final class Credential implements Parcelable { */ public int eapType = Integer.MIN_VALUE; + /** + * Constructor for creating SimCredential with default values. + */ + public SimCredential() {} + + /** + * Copy constructor + * + * @param source The source to copy from + */ + public SimCredential(SimCredential source) { + if (source != null) { + imsi = source.imsi; + eapType = source.eapType; + } + } + @Override public int describeContents() { return 0; @@ -422,6 +478,37 @@ public final class Credential implements Parcelable { */ public PrivateKey clientPrivateKey = null; + /** + * Constructor for creating Credential with default values. + */ + public Credential() {} + + /** + * Copy constructor. + * + * @param source The source to copy from + */ + public Credential(Credential source) { + if (source != null) { + realm = source.realm; + if (source.userCredential != null) { + userCredential = new UserCredential(source.userCredential); + } + if (source.certCredential != null) { + certCredential = new CertificateCredential(source.certCredential); + } + if (source.simCredential != null) { + simCredential = new SimCredential(source.simCredential); + } + if (source.clientCertificateChain != null) { + clientCertificateChain = Arrays.copyOf(source.clientCertificateChain, + source.clientCertificateChain.length); + } + caCertificate = source.caCertificate; + clientPrivateKey = source.clientPrivateKey; + } + } + @Override public int describeContents() { return 0; diff --git a/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.java b/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.java index 5837c06499e3..d4a5792d93fc 100644 --- a/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.java +++ b/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.java @@ -53,6 +53,27 @@ public final class HomeSP implements Parcelable { */ public long[] roamingConsortiumOIs = null; + /** + * Constructor for creating HomeSP with default values. + */ + public HomeSP() {} + + /** + * Copy constructor. + * + * @param source The source to copy from + */ + public HomeSP(HomeSP source) { + if (source != null) { + fqdn = source.fqdn; + friendlyName = source.friendlyName; + if (source.roamingConsortiumOIs != null) { + roamingConsortiumOIs = Arrays.copyOf(source.roamingConsortiumOIs, + source.roamingConsortiumOIs.length); + } + } + } + @Override public int describeContents() { return 0; diff --git a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java index b4a3acf08975..2350d3201171 100644 --- a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java +++ b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java @@ -33,6 +33,11 @@ import org.junit.Test; @SmallTest public class PasspointConfigurationTest { + /** + * Utility function for creating a {@link android.net.wifi.hotspot2.pps.HomeSP}. + * + * @return {@link android.net.wifi.hotspot2.pps.HomeSP} + */ private static HomeSP createHomeSp() { HomeSP homeSp = new HomeSP(); homeSp.fqdn = "fqdn"; @@ -41,6 +46,11 @@ public class PasspointConfigurationTest { return homeSp; } + /** + * Utility function for creating a {@link android.net.wifi.hotspot2.pps.Credential}. + * + * @return {@link android.net.wifi.hotspot2.pps.Credential} + */ private static Credential createCredential() { Credential cred = new Credential(); cred.realm = "realm"; @@ -55,6 +65,12 @@ public class PasspointConfigurationTest { return cred; } + /** + * Verify parcel write and read consistency for the given configuration. + * + * @param writeConfig The configuration to verify + * @throws Exception + */ private static void verifyParcel(PasspointConfiguration writeConfig) throws Exception { Parcel parcel = Parcel.obtain(); writeConfig.writeToParcel(parcel, 0); @@ -77,6 +93,7 @@ public class PasspointConfigurationTest { /** * Verify parcel read/write for a configuration that contained both HomeSP and Credential. + * * @throws Exception */ @Test @@ -158,4 +175,30 @@ public class PasspointConfigurationTest { config.credential = createCredential(); assertTrue(config.validate()); } -}
\ No newline at end of file + + /** + * Verify that copy constructor works when pass in a null source. + * + * @throws Exception + */ + @Test + public void validateCopyConstructorWithNullSource() throws Exception { + PasspointConfiguration copyConfig = new PasspointConfiguration(null); + PasspointConfiguration defaultConfig = new PasspointConfiguration(); + assertTrue(copyConfig.equals(defaultConfig)); + } + + /** + * Verify that copy constructor works when pass in a valid source. + * + * @throws Exception + */ + @Test + public void validateCopyConstructorWithValidSource() throws Exception { + PasspointConfiguration sourceConfig = new PasspointConfiguration(); + sourceConfig.homeSp = createHomeSp(); + sourceConfig.credential = createCredential(); + PasspointConfiguration copyConfig = new PasspointConfiguration(sourceConfig); + assertTrue(copyConfig.equals(sourceConfig)); + } +} diff --git a/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java b/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java index 223aa5231b36..9c8b749e1c93 100644 --- a/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java +++ b/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java @@ -470,4 +470,52 @@ public class CredentialTest { cred.simCredential.eapType = EAPConstants.EAP_SIM; assertFalse(cred.validate()); } + + /** + * Verify that copy constructor works when pass in a null source. + * + * @throws Exception + */ + @Test + public void validateCopyConstructorWithNullSource() throws Exception { + Credential copyCred = new Credential(null); + Credential defaultCred = new Credential(); + assertTrue(copyCred.equals(defaultCred)); + } + + /** + * Verify that copy constructor works when pass in a source with user credential. + * + * @throws Exception + */ + @Test + public void validateCopyConstructorWithSourceWithUserCred() throws Exception { + Credential sourceCred = createCredentialWithUserCredential(); + Credential copyCred = new Credential(sourceCred); + assertTrue(copyCred.equals(sourceCred)); + } + + /** + * Verify that copy constructor works when pass in a source with certificate credential. + * + * @throws Exception + */ + @Test + public void validateCopyConstructorWithSourceWithCertCred() throws Exception { + Credential sourceCred = createCredentialWithCertificateCredential(); + Credential copyCred = new Credential(sourceCred); + assertTrue(copyCred.equals(sourceCred)); + } + + /** + * Verify that copy constructor works when pass in a source with SIM credential. + * + * @throws Exception + */ + @Test + public void validateCopyConstructorWithSourceWithSimCred() throws Exception { + Credential sourceCred = createCredentialWithSimCredential(); + Credential copyCred = new Credential(sourceCred); + assertTrue(copyCred.equals(sourceCred)); + } }
\ No newline at end of file diff --git a/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSPTest.java b/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSPTest.java index fff1477e833b..c70799332b02 100644 --- a/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSPTest.java +++ b/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSPTest.java @@ -118,4 +118,31 @@ public class HomeSPTest { homeSp.roamingConsortiumOIs = new long[] {0x55, 0x66}; assertTrue(homeSp.validate()); } + + /** + * Verify that copy constructor works when pass in a null source. + * + * @throws Exception + */ + @Test + public void validateCopyConstructorFromNullSource() throws Exception { + HomeSP copySp = new HomeSP(null); + HomeSP defaultSp = new HomeSP(); + assertTrue(copySp.equals(defaultSp)); + } + + /** + * Verify that copy constructor works when pass in a valid source. + * + * @throws Exception + */ + @Test + public void validateCopyConstructorFromValidSource() throws Exception { + HomeSP sourceSp = new HomeSP(); + sourceSp.fqdn = "fqdn"; + sourceSp.friendlyName = "friendlyName"; + sourceSp.roamingConsortiumOIs = new long[] {0x55, 0x66}; + HomeSP copySp = new HomeSP(sourceSp); + assertTrue(copySp.equals(sourceSp)); + } } |