diff options
48 files changed, 682 insertions, 211 deletions
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java index fde756c13234..a81546dc1d47 100644 --- a/core/java/android/app/WallpaperManager.java +++ b/core/java/android/app/WallpaperManager.java @@ -1874,23 +1874,33 @@ public class WallpaperManager { * @hide */ public static ComponentName getDefaultWallpaperComponent(Context context) { + ComponentName cn = null; + String flat = SystemProperties.get(PROP_WALLPAPER_COMPONENT); if (!TextUtils.isEmpty(flat)) { - final ComponentName cn = ComponentName.unflattenFromString(flat); - if (cn != null) { - return cn; + cn = ComponentName.unflattenFromString(flat); + } + + if (cn == null) { + flat = context.getString(com.android.internal.R.string.default_wallpaper_component); + if (!TextUtils.isEmpty(flat)) { + cn = ComponentName.unflattenFromString(flat); } } - flat = context.getString(com.android.internal.R.string.default_wallpaper_component); - if (!TextUtils.isEmpty(flat)) { - final ComponentName cn = ComponentName.unflattenFromString(flat); - if (cn != null) { - return cn; + // Check if the package exists + if (cn != null) { + try { + final PackageManager packageManager = context.getPackageManager(); + packageManager.getPackageInfo(cn.getPackageName(), + PackageManager.MATCH_DIRECT_BOOT_AWARE + | PackageManager.MATCH_DIRECT_BOOT_UNAWARE); + } catch (PackageManager.NameNotFoundException e) { + cn = null; } } - return null; + return cn; } /** diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java index c109ed2dcfe3..a061e610fd40 100644 --- a/core/java/android/content/ContentResolver.java +++ b/core/java/android/content/ContentResolver.java @@ -77,6 +77,7 @@ import java.util.concurrent.atomic.AtomicBoolean; * <p>For more information about using a ContentResolver with content providers, read the * <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a> * developer guide.</p> + * </div> */ public abstract class ContentResolver { /** diff --git a/core/java/android/text/util/Linkify.java b/core/java/android/text/util/Linkify.java index c905f49569d7..dc68da0310b6 100644 --- a/core/java/android/text/util/Linkify.java +++ b/core/java/android/text/util/Linkify.java @@ -29,6 +29,7 @@ import android.text.Spanned; import android.text.method.LinkMovementMethod; import android.text.method.MovementMethod; import android.text.style.URLSpan; +import android.util.Log; import android.util.Patterns; import android.view.textclassifier.TextClassifier; import android.view.textclassifier.TextLinks; @@ -77,6 +78,9 @@ import java.util.regex.Pattern; */ public class Linkify { + + private static final String LOG_TAG = "Linkify"; + /** * Bit field indicating that web URLs should be matched in methods that * take an options mask @@ -246,6 +250,11 @@ public class Linkify { private static boolean addLinks(@NonNull Spannable text, @LinkifyMask int mask, @Nullable Context context) { + if (text != null && containsUnsupportedCharacters(text.toString())) { + android.util.EventLog.writeEvent(0x534e4554, "116321860", -1, ""); + return false; + } + if (mask == 0) { return false; } @@ -292,6 +301,29 @@ public class Linkify { } /** + * Returns true if the specified text contains at least one unsupported character for applying + * links. Also logs the error. + * + * @param text the text to apply links to + * @hide + */ + public static boolean containsUnsupportedCharacters(String text) { + if (text.contains("\u202C")) { + Log.e(LOG_TAG, "Unsupported character for applying links: u202C"); + return true; + } + if (text.contains("\u202D")) { + Log.e(LOG_TAG, "Unsupported character for applying links: u202D"); + return true; + } + if (text.contains("\u202E")) { + Log.e(LOG_TAG, "Unsupported character for applying links: u202E"); + return true; + } + return false; + } + + /** * Scans the text of the provided TextView and turns all occurrences of * the link types indicated in the mask into clickable links. If matches * are found the movement method for the TextView is set to @@ -461,6 +493,11 @@ public class Linkify { public static final boolean addLinks(@NonNull Spannable spannable, @NonNull Pattern pattern, @Nullable String defaultScheme, @Nullable String[] schemes, @Nullable MatchFilter matchFilter, @Nullable TransformFilter transformFilter) { + if (spannable != null && containsUnsupportedCharacters(spannable.toString())) { + android.util.EventLog.writeEvent(0x534e4554, "116321860", -1, ""); + return false; + } + final String[] schemesCopy; if (defaultScheme == null) defaultScheme = ""; if (schemes == null || schemes.length < 1) { diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 6df0173d9684..a1c0967f0ab1 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -1354,6 +1354,9 @@ public final class ViewRootImpl implements ViewParent, } if (mStopped) { + if (mSurfaceHolder != null) { + notifySurfaceDestroyed(); + } mSurface.release(); } } @@ -2227,13 +2230,7 @@ public final class ViewRootImpl implements ViewParent, } mIsCreating = false; } else if (hadSurface) { - mSurfaceHolder.ungetCallbacks(); - SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks(); - if (callbacks != null) { - for (SurfaceHolder.Callback c : callbacks) { - c.surfaceDestroyed(mSurfaceHolder); - } - } + notifySurfaceDestroyed(); mSurfaceHolder.mSurfaceLock.lock(); try { mSurfaceHolder.mSurface = new Surface(); @@ -2497,6 +2494,16 @@ public final class ViewRootImpl implements ViewParent, mIsInTraversal = false; } + private void notifySurfaceDestroyed() { + mSurfaceHolder.ungetCallbacks(); + SurfaceHolder.Callback[] callbacks = mSurfaceHolder.getCallbacks(); + if (callbacks != null) { + for (SurfaceHolder.Callback c : callbacks) { + c.surfaceDestroyed(mSurfaceHolder); + } + } + } + private void maybeHandleWindowMove(Rect frame) { // TODO: Well, we are checking whether the frame has changed similarly diff --git a/core/java/android/view/textclassifier/TextClassification.java b/core/java/android/view/textclassifier/TextClassification.java index 9511a9efb3d5..49ca969fa7af 100644 --- a/core/java/android/view/textclassifier/TextClassification.java +++ b/core/java/android/view/textclassifier/TextClassification.java @@ -104,7 +104,7 @@ public final class TextClassification implements Parcelable { /** * @hide */ - static final TextClassification EMPTY = new TextClassification.Builder().build(); + public static final TextClassification EMPTY = new TextClassification.Builder().build(); private static final String LOG_TAG = "TextClassification"; // TODO(toki): investigate a way to derive this based on device properties. diff --git a/core/java/android/view/textclassifier/TextLinksParams.java b/core/java/android/view/textclassifier/TextLinksParams.java index be4c3bcdff67..c21206ca0258 100644 --- a/core/java/android/view/textclassifier/TextLinksParams.java +++ b/core/java/android/view/textclassifier/TextLinksParams.java @@ -107,6 +107,13 @@ public final class TextLinksParams { Preconditions.checkNotNull(textLinks); final String textString = text.toString(); + + if (Linkify.containsUnsupportedCharacters(textString)) { + // Do not apply links to text containing unsupported characters. + android.util.EventLog.writeEvent(0x534e4554, "116321860", -1, ""); + return TextLinks.STATUS_NO_LINKS_APPLIED; + } + if (!textString.startsWith(textLinks.getText())) { return TextLinks.STATUS_DIFFERENT_TEXT; } diff --git a/core/java/android/webkit/WebViewClient.java b/core/java/android/webkit/WebViewClient.java index bdd7a0900213..a29d44966540 100644 --- a/core/java/android/webkit/WebViewClient.java +++ b/core/java/android/webkit/WebViewClient.java @@ -370,11 +370,16 @@ public class WebViewClient { /** * Notify the host application that an SSL error occurred while loading a - * resource. The host application must call either handler.cancel() or - * handler.proceed(). Note that the decision may be retained for use in + * resource. The host application must call either {@link SslErrorHandler#cancel} or + * {@link SslErrorHandler#proceed}. Note that the decision may be retained for use in * response to future SSL errors. The default behavior is to cancel the * load. * <p> + * This API is only called for recoverable SSL certificate errors. In the case of + * non-recoverable errors (such as when the server fails the client), WebView will call {@link + * #onReceivedError(WebView, WebResourceRequest, WebResourceError)} with {@link + * #ERROR_FAILED_SSL_HANDSHAKE}. + * <p> * Applications are advised not to prompt the user about SSL errors, as * the user is unlikely to be able to make an informed security decision * and WebView does not provide any UI for showing the details of the @@ -382,10 +387,10 @@ public class WebViewClient { * <p> * Application overrides of this method may display custom error pages or * silently log issues, but it is strongly recommended to always call - * handler.cancel() and never allow proceeding past errors. + * {@link SslErrorHandler#cancel} and never allow proceeding past errors. * * @param view The WebView that is initiating the callback. - * @param handler An SslErrorHandler object that will handle the user's + * @param handler An {@link SslErrorHandler} that will handle the user's * response. * @param error The SSL error object. */ diff --git a/core/java/android/widget/SelectionActionModeHelper.java b/core/java/android/widget/SelectionActionModeHelper.java index 6cb0eaa7f47d..0d88e6986f11 100644 --- a/core/java/android/widget/SelectionActionModeHelper.java +++ b/core/java/android/widget/SelectionActionModeHelper.java @@ -31,6 +31,7 @@ import android.text.Layout; import android.text.Selection; import android.text.Spannable; import android.text.TextUtils; +import android.text.util.Linkify; import android.util.Log; import android.view.ActionMode; import android.view.textclassifier.SelectionEvent; @@ -1045,7 +1046,12 @@ public final class SelectionActionModeHelper { trimText(); final TextClassification classification; - if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.P) { + if (Linkify.containsUnsupportedCharacters(mText)) { + // Do not show smart actions for text containing unsupported characters. + android.util.EventLog.writeEvent(0x534e4554, "116321860", -1, ""); + classification = TextClassification.EMPTY; + } else if (mContext.getApplicationInfo().targetSdkVersion + >= Build.VERSION_CODES.P) { final TextClassification.Request request = new TextClassification.Request.Builder( mTrimmedText, mRelativeStart, mRelativeEnd) diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index e7a777e8c97b..ea25bfe0643e 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -1455,7 +1455,7 @@ <string name="vpn_lockdown_config" msgid="8151951501116759194">"تغيير إعدادات الشبكة أو الشبكة الافتراضية الخاصة (VPN)"</string> <string name="upload_file" msgid="2897957172366730416">"اختيار ملف"</string> <string name="no_file_chosen" msgid="6363648562170759465">"لم يتم اختيار أي ملف"</string> - <string name="reset" msgid="2448168080964209908">"إعادة تعيين"</string> + <string name="reset" msgid="2448168080964209908">"إعادة الضبط"</string> <string name="submit" msgid="1602335572089911941">"إرسال"</string> <string name="car_mode_disable_notification_title" msgid="5704265646471239078">"تطبيق القيادة قيد التشغيل"</string> <string name="car_mode_disable_notification_message" msgid="7647248420931129377">"انقر للخروج من تطبيق القيادة."</string> diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml index 6aae0979e49b..80d17c4d86ec 100644 --- a/core/res/res/values-as/strings.xml +++ b/core/res/res/values-as/strings.xml @@ -1173,7 +1173,7 @@ <string name="network_available_sign_in" msgid="1848877297365446605">"নেটৱৰ্কত ছাইন ইন কৰক"</string> <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) --> <skip /> - <string name="wifi_no_internet" msgid="8938267198124654938">"ৱাই-ফাইত ইন্টাৰনেট নাই"</string> + <string name="wifi_no_internet" msgid="8938267198124654938">"ৱাই-ফাইত ইণ্টাৰনেট নাই"</string> <string name="wifi_no_internet_detailed" msgid="8083079241212301741">"অধিক বিকল্পৰ বাবে টিপক"</string> <string name="wifi_softap_config_change" msgid="8475911871165857607">"আপোনাৰ হটস্পট ছেটিংসমূহত কৰা সালসলনি"</string> <string name="wifi_softap_config_change_summary" msgid="7601233252456548891">"আপোনাৰ হটস্পটৰ বেণ্ড সলনি কৰা হ’ল।"</string> diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index 937120ed2793..139563afce63 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -79,7 +79,7 @@ <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"Налады ідэнтыфікатару АВН па змаўчанні: не абмяжавана. Наступны выклік: не абмежавана"</string> <string name="serviceNotProvisioned" msgid="8614830180508686666">"Служба не прадастаўляецца."</string> <string name="CLIRPermanent" msgid="3377371145926835671">"Вы не можаце змяніць налады ідэнтыфікатара абанента, якi тэлефануе."</string> - <string name="RestrictedOnDataTitle" msgid="5221736429761078014">"Мабільны інтэрнэт недаступны"</string> + <string name="RestrictedOnDataTitle" msgid="5221736429761078014">"Мабільная перадача даных недаступная"</string> <string name="RestrictedOnEmergencyTitle" msgid="6855466023161191166">"Экстранныя выклікі недаступныя"</string> <string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Няма сэрвісу галасавых выклікаў"</string> <string name="RestrictedOnAllVoiceTitle" msgid="8037246983606545202">"Галасавыя або экстранныя выклікі недаступныя"</string> @@ -416,7 +416,7 @@ <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Гэта праграма можа атрымліваць звесткі пра ваша месцазнаходжанне на падставе даных сеткавых крыніц, такіх як вышкі сотавай сувязі і сеткі Wi-Fi. Гэтыя сэрвісы вызначэння месцазнаходжання павінны быць уключаны i даступныя на вашым тэлефоне, каб праграма магла іх выкарыстоўваць."</string> <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"змяняць налады аудыё"</string> <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Дазваляе прыкладанням змяняць глабальныя налады гуку, такія як моц і тое, што дынамік выкарыстоўваецца для выхаду."</string> - <string name="permlab_recordAudio" msgid="3876049771427466323">"запісваць аўдыё"</string> + <string name="permlab_recordAudio" msgid="3876049771427466323">"запіс аўдыя"</string> <string name="permdesc_recordAudio" msgid="4245930455135321433">"Гэта праграма можа у любы час запісваць аўдыя, выкарыстоўваючы мікрафон."</string> <string name="permlab_sim_communication" msgid="2935852302216852065">"адпраўляць каманды на SIM-карту"</string> <string name="permdesc_sim_communication" msgid="5725159654279639498">"Дазваляе праграме адпраўляць каманды SIM-карце. Гэта вельмі небяспечна."</string> diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml index cff2c0610823..fd944c3ded07 100644 --- a/core/res/res/values-bs/strings.xml +++ b/core/res/res/values-bs/strings.xml @@ -147,9 +147,9 @@ <string name="httpErrorOk" msgid="1191919378083472204">"Uredu"</string> <string name="httpError" msgid="7956392511146698522">"Došlo je do greške na mreži."</string> <string name="httpErrorLookup" msgid="4711687456111963163">"Pronalaženje URL-a nije uspjelo."</string> - <string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"Shema za provjeru vjerodostojnosti stranice nije podržana."</string> - <string name="httpErrorAuth" msgid="1435065629438044534">"Došlo je do greške prilikom provjere vjerodostojnosti."</string> - <string name="httpErrorProxyAuth" msgid="1788207010559081331">"Došlo je do greške prilikom provjere vjerodostojnosti preko proksi servera."</string> + <string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"Shema za autentifikaciju stranice nije podržana."</string> + <string name="httpErrorAuth" msgid="1435065629438044534">"Došlo je do greške prilikom autentifikacije."</string> + <string name="httpErrorProxyAuth" msgid="1788207010559081331">"Došlo je do greške prilikom autentifikacije preko proksi servera."</string> <string name="httpErrorConnect" msgid="8714273236364640549">"Povezivanje sa serverom nije uspjelo."</string> <string name="httpErrorIO" msgid="2340558197489302188">"Veza sa serverom nije uspostavljena. Pokušajte ponovo kasnije."</string> <string name="httpErrorTimeout" msgid="4743403703762883954">"Vrijeme za uspostavljanje veze sa serverom je isteklo."</string> @@ -494,7 +494,7 @@ <string name="permlab_manageFingerprint" msgid="5640858826254575638">"upravljanje hardverom za otiske prstiju"</string> <string name="permdesc_manageFingerprint" msgid="178208705828055464">"Omogućava aplikaciji da koristi metode za dodavanje i brisanje šablona otisaka prstiju za upotrebu."</string> <string name="permlab_useFingerprint" msgid="3150478619915124905">"korištenje hardvera za otiske prstiju"</string> - <string name="permdesc_useFingerprint" msgid="9165097460730684114">"Omogućava aplikaciji da za provjeru vjerodostojnosti koristi hardver za otiske prstiju"</string> + <string name="permdesc_useFingerprint" msgid="9165097460730684114">"Omogućava aplikaciji da za autentifikaciju koristi hardver za otiske prstiju"</string> <string name="fingerprint_acquired_partial" msgid="735082772341716043">"Otkriven je djelomičan otisak prsta. Pokušajte ponovo."</string> <string name="fingerprint_acquired_insufficient" msgid="4596546021310923214">"Nije uspjela obrada otiska prsta. Pokušajte ponovo."</string> <string name="fingerprint_acquired_imager_dirty" msgid="1087209702421076105">"Senzor za otisak prsta je prljav. Očistite ga i pokušajte ponovo."</string> @@ -1558,7 +1558,7 @@ <string name="kg_invalid_puk" msgid="3638289409676051243">"Ponovo unesite ispravan PUK kôd. Ponovljeni pokušaji će trajno onemogućiti SIM."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN-ovi se ne poklapaju"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Previše pokušaja otključavanja pomoću uzorka"</string> - <string name="kg_login_instructions" msgid="1100551261265506448">"Da otključate, prijavite se sa svojim Google računom."</string> + <string name="kg_login_instructions" msgid="1100551261265506448">"Da otključate, prijavite se pomoću svog Google računa."</string> <string name="kg_login_username_hint" msgid="5718534272070920364">"Korisničko ime (adresa e-pošte)"</string> <string name="kg_login_password_hint" msgid="9057289103827298549">"Lozinka"</string> <string name="kg_login_submit_button" msgid="5355904582674054702">"Prijava"</string> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index 47f26a560ad0..6d5fb581c518 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -87,7 +87,7 @@ <string name="NetworkPreferenceSwitchSummary" msgid="509327194863482733">"Prøv at skifte dit foretrukne netværk. Tryk for skifte."</string> <string name="EmergencyCallWarningTitle" msgid="813380189532491336">"Det er ikke muligt at foretage nødopkald"</string> <string name="EmergencyCallWarningSummary" msgid="1899692069750260619">"Det er ikke muligt at foretage nødopkald via Wi‑Fi"</string> - <string name="notification_channel_network_alert" msgid="4427736684338074967">"Underretninger"</string> + <string name="notification_channel_network_alert" msgid="4427736684338074967">"Notifikationer"</string> <string name="notification_channel_call_forward" msgid="2419697808481833249">"Viderestilling af opkald"</string> <string name="notification_channel_emergency_callback" msgid="6686166232265733921">"Nødtilbagekaldstilstand"</string> <string name="notification_channel_mobile_data_status" msgid="4575131690860945836">"Status for mobildata"</string> @@ -179,7 +179,7 @@ <string name="work_profile_deleted_description_dpm_wipe" msgid="8823792115612348820">"Din arbejdsprofil er ikke længere tilgængelig på denne enhed"</string> <string name="work_profile_deleted_reason_maximum_password_failure" msgid="8986903510053359694">"For mange mislykkede adgangskodeforsøg"</string> <string name="network_logging_notification_title" msgid="6399790108123704477">"Dette er en administreret enhed"</string> - <string name="network_logging_notification_text" msgid="7930089249949354026">"Din organisation administrerer denne enhed og kan overvåge netværkstrafik. Tryk for at se oplysninger."</string> + <string name="network_logging_notification_text" msgid="7930089249949354026">"Din organisation administrerer denne enhed og kan overvåge netværkstrafik. Tryk for at se info."</string> <string name="factory_reset_warning" msgid="5423253125642394387">"Enheden slettes"</string> <string name="factory_reset_message" msgid="9024647691106150160">"Administrationsappen kan ikke bruges. Enheden vil nu blive ryddet. \n\nKontakt din organisations administrator, hvis du har spørgsmål."</string> <string name="printing_disabled_by" msgid="8936832919072486965">"Udskrivning er deaktiveret af <xliff:g id="OWNER_APP">%s</xliff:g>."</string> @@ -244,7 +244,7 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Taleassistent"</string> <string name="global_action_lockdown" msgid="1099326950891078929">"Lukning"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_hidden_text" msgid="6351207030447943784">"Ny underretning"</string> + <string name="notification_hidden_text" msgid="6351207030447943784">"Ny notifikation"</string> <string name="notification_channel_virtual_keyboard" msgid="6969925135507955575">"Virtuelt tastatur"</string> <string name="notification_channel_physical_keyboard" msgid="7297661826966861459">"Fysisk tastatur"</string> <string name="notification_channel_security" msgid="7345516133431326347">"Sikkerhed"</string> @@ -257,22 +257,22 @@ <string name="notification_channel_network_available" msgid="4531717914138179517">"Tilgængeligt netværk"</string> <string name="notification_channel_vpn" msgid="8330103431055860618">"VPN-status"</string> <string name="notification_channel_device_admin" msgid="1568154104368069249">"Enhedsadministration"</string> - <string name="notification_channel_alerts" msgid="4496839309318519037">"Underretninger"</string> + <string name="notification_channel_alerts" msgid="4496839309318519037">"Notifikationer"</string> <string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demo til udstilling i butik"</string> <string name="notification_channel_usb" msgid="9006850475328924681">"USB-forbindelse"</string> <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"Appen kører"</string> <string name="notification_channel_foreground_service" msgid="3931987440602669158">"Apps, der bruger batteri"</string> <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> bruger batteri"</string> <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> apps bruger batteri"</string> - <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Tryk for at se oplysninger om batteri- og dataforbrug"</string> + <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Tryk for at se info om batteri- og dataforbrug"</string> <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string> <string name="safeMode" msgid="2788228061547930246">"Sikker tilstand"</string> <string name="android_system_label" msgid="6577375335728551336">"Android-system"</string> <string name="user_owner_label" msgid="8836124313744349203">"Skift til personlig profil"</string> <string name="managed_profile_label" msgid="8947929265267690522">"Skift til arbejdsprofil"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontakter"</string> - <string name="permgroupdesc_contacts" msgid="6951499528303668046">"have adgang til dine kontaktpersoner"</string> - <string name="permgrouprequest_contacts" msgid="6032805601881764300">"Vil du give <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> adgang til dine kontaktpersoner?"</string> + <string name="permgroupdesc_contacts" msgid="6951499528303668046">"have adgang til dine kontakter"</string> + <string name="permgrouprequest_contacts" msgid="6032805601881764300">"Vil du give <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> adgang til dine kontakter?"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Placering"</string> <string name="permgroupdesc_location" msgid="1346617465127855033">"få adgang til enhedens placering"</string> <string name="permgrouprequest_location" msgid="3788275734953323491">"Vil du give <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> adgang til enhedens placering?"</string> @@ -376,11 +376,11 @@ <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"Tillader, at appen kan sende klæbende udsendelser, der forbliver tilbage, når udsendelsen er slut. Overdreven brug kan gøre din tablet langsom eller ustabil ved at tvinge den til at bruge for meget hukommelse."</string> <string name="permdesc_broadcastSticky" product="tv" msgid="6839285697565389467">"Giver appen lov til at sende klæbende udsendelser, som ikke forsvinder, når udsendelsen er slut. Overdreven brug kan gøre fjernsynet langsomt eller ustabilt ved at få det til at bruge for meget hukommelse."</string> <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"Tillader, at appen kan sende klæbende udsendelser, der forbliver tilbage, når udsendelsen er slut. Overdreven brug kan gøre din telefon langsom eller ustabil ved at tvinge den til at bruge for meget hukommelse."</string> - <string name="permlab_readContacts" msgid="8348481131899886131">"læse dine kontaktpersoner"</string> + <string name="permlab_readContacts" msgid="8348481131899886131">"læse dine kontakter"</string> <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"Tillader, at appen kan læse data om de kontakter, der er gemt på din tablet, f.eks. hvor ofte du har ringet til, sendt mail til eller på anden måde kommunikeret med bestemte personer. Med denne tilladelse kan apps gemme dine kontaktdata, og skadelige apps kan dele kontaktdata uden din viden."</string> <string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"Giver appen lov til at læse data om dine kontakter, der er gemt på dit tv, herunder hvor ofte du har ringet, mailet eller på andre måder kommunikeret med bestemte personer. Denne tilladelse gør det muligt for apps at gemme dine kontaktoplysninger, og ondsindede apps kan dele kontaktoplysninger uden din viden."</string> <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"Tillader, at appen kan læse data om de kontakter, der er gemt på din telefon, f.eks. hvor ofte du har ringet til, sendt mail til eller på anden måde kommunikeret med bestemte personer. Med denne tilladelse kan apps gemme dine kontaktdata, og skadelige apps kan dele kontaktdata uden din viden."</string> - <string name="permlab_writeContacts" msgid="5107492086416793544">"ændre dine kontaktpersoner"</string> + <string name="permlab_writeContacts" msgid="5107492086416793544">"ændre dine kontakter"</string> <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Tillader, at appen kan ændre data om de kontakter, der er gemt på din tablet, f.eks. hvor ofte du har ringet til dem, sendt dem en mail eller på anden måde kommunikeret med bestemte kontakter. Med denne tilladelse kan apps slette kontaktoplysninger."</string> <string name="permdesc_writeContacts" product="tv" msgid="5438230957000018959">"Giver appen lov til at ændre data om dine kontakter, der er gemt på dit tv, herunder hvor ofte du har ringet, mailet eller på anden måde kommunikeret med bestemte kontakter. Denne tilladelse gør det muligt for apps at slette kontaktoplysninger."</string> <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"Tillader, at appen kan ændre data om de kontakter, der er gemt på din telefon, f.eks. hvor ofte du har ringet til dem, sendt en mail til dem eller på anden måde kommunikeret med bestemte kontakter. Med denne tilladelse kan apps slette kontaktoplysninger."</string> @@ -549,10 +549,10 @@ <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Tillader, at appen kan administrere netværkspolitikker og definere appspecifikke regler."</string> <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"skift afregning af netværksbrug"</string> <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Tillader, at appen kan ændre den måde, som netværksforbrug udregnes på i forhold til apps. Anvendes ikke af normale apps."</string> - <string name="permlab_accessNotifications" msgid="7673416487873432268">"adgang til underretninger"</string> - <string name="permdesc_accessNotifications" msgid="458457742683431387">"Tillader, at appen kan hente, undersøge og rydde underretninger, f.eks. dem, der er sendt af andre apps."</string> - <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"forpligte sig til en underretningslyttertjeneste"</string> - <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Tillader brugeren at forpligte sig til en underretningslyttertjenestes grænseflade på øverste niveau. Bør aldrig være nødvendigt til almindelige apps."</string> + <string name="permlab_accessNotifications" msgid="7673416487873432268">"adgang til notifikationer"</string> + <string name="permdesc_accessNotifications" msgid="458457742683431387">"Tillader, at appen kan hente, undersøge og rydde notifikationer, f.eks. dem, der er sendt af andre apps."</string> + <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"forpligte sig til en notifikationslyttertjeneste"</string> + <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Tillader brugeren at forpligte sig til en notifikationslyttertjenestes grænseflade på øverste niveau. Bør aldrig være nødvendigt til almindelige apps."</string> <string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"oprette binding til en tjeneste til formidling af betingelser"</string> <string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Tillader, at brugeren opretter en binding til det øverste niveau af grænsefladen i en tjeneste til formidling af betingelser. Dette bør aldrig være nødvendigt for almindelige apps."</string> <string name="permlab_bindDreamService" msgid="4153646965978563462">"fastlås til en drømmetjeneste"</string> @@ -1023,7 +1023,7 @@ <string name="sms" msgid="4560537514610063430">"Send besked"</string> <string name="sms_desc" msgid="7526588350969638809">"Send en besked til det valgte telefonnummer"</string> <string name="add_contact" msgid="7867066569670597203">"Tilføj"</string> - <string name="add_contact_desc" msgid="4830217847004590345">"Føj til kontaktpersoner"</string> + <string name="add_contact_desc" msgid="4830217847004590345">"Føj til kontakter"</string> <string name="view_calendar" msgid="979609872939597838">"Se"</string> <string name="view_calendar_desc" msgid="5828320291870344584">"Se det valgte tidspunkt i kalenderen"</string> <string name="add_calendar_event" msgid="1953664627192056206">"Planlæg"</string> @@ -1134,19 +1134,19 @@ <string name="volume_call" msgid="3941680041282788711">"Lydstyrke for opkald"</string> <string name="volume_bluetooth_call" msgid="2002891926351151534">"Lydstyrke for Bluetooth under opkald"</string> <string name="volume_alarm" msgid="1985191616042689100">"Lydstyrke for alarm"</string> - <string name="volume_notification" msgid="2422265656744276715">"Lydstyrke for underretninger"</string> + <string name="volume_notification" msgid="2422265656744276715">"Lydstyrke for notifikationer"</string> <string name="volume_unknown" msgid="1400219669770445902">"Lydstyrke"</string> <string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"Lydstyrke for bluetooth"</string> <string name="volume_icon_description_ringer" msgid="3326003847006162496">"Lydstyrke for ringetone"</string> <string name="volume_icon_description_incall" msgid="8890073218154543397">"Lydstyrke for opkald"</string> <string name="volume_icon_description_media" msgid="4217311719665194215">"Lydstyrke for medier"</string> - <string name="volume_icon_description_notification" msgid="7044986546477282274">"Lydstyrke for underretninger"</string> + <string name="volume_icon_description_notification" msgid="7044986546477282274">"Lydstyrke for notifikationer"</string> <string name="ringtone_default" msgid="3789758980357696936">"Standardringetone"</string> <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Standard (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> <string name="ringtone_silent" msgid="7937634392408977062">"Ingen"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Ringetoner"</string> <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Alarmlyde"</string> - <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Underretningslyde"</string> + <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Notifikationslyde"</string> <string name="ringtone_unknown" msgid="3914515995813061520">"Ukendt"</string> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> <item quantity="one">Tilgængelige Wi-Fi-netværk</item> @@ -1352,10 +1352,10 @@ <string name="accessibility_binding_label" msgid="4148120742096474641">"Hjælpefunktioner"</string> <string name="wallpaper_binding_label" msgid="1240087844304687662">"Baggrund"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Skift baggrund"</string> - <string name="notification_listener_binding_label" msgid="2014162835481906429">"Underretningslytter"</string> + <string name="notification_listener_binding_label" msgid="2014162835481906429">"Notifikationslytter"</string> <string name="vr_listener_binding_label" msgid="4316591939343607306">"VR-lyttefunktion"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Tjeneste til formidling af betingelser"</string> - <string name="notification_ranker_binding_label" msgid="774540592299064747">"Tjeneste til rangering af underretninger"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Tjeneste til rangering af notifikationer"</string> <string name="vpn_title" msgid="19615213552042827">"VPN er aktiveret."</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN aktiveres af <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="1610714069627824309">"Tryk for at administrere netværket."</string> @@ -1773,7 +1773,7 @@ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> valgt</item> </plurals> <string name="default_notification_channel_label" msgid="5929663562028088222">"Uden kategori"</string> - <string name="importance_from_user" msgid="7318955817386549931">"Du angiver, hvor vigtige disse underretninger er."</string> + <string name="importance_from_user" msgid="7318955817386549931">"Du angiver, hvor vigtige disse notifikationer er."</string> <string name="importance_from_person" msgid="9160133597262938296">"Dette er vigtigt på grund af de personer, det handler om."</string> <string name="user_creation_account_exists" msgid="1942606193570143289">"Vil du give <xliff:g id="APP">%1$s</xliff:g> tilladelse til at oprette en ny bruger med <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string> <string name="user_creation_adding" msgid="4482658054622099197">"Vil du give <xliff:g id="APP">%1$s</xliff:g> tilladelse til at oprette en ny bruger med <xliff:g id="ACCOUNT">%2$s</xliff:g> (der findes allerede en bruger med denne konto)?"</string> @@ -1788,7 +1788,7 @@ <string name="app_suspended_default_message" msgid="123166680425711887">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> er ikke tilgængelig lige nu. Dette administreres af <xliff:g id="APP_NAME_1">%2$s</xliff:g>."</string> <string name="app_suspended_more_details" msgid="1131804827776778187">"Få flere oplysninger"</string> <string name="work_mode_off_title" msgid="1118691887588435530">"Skal arbejdsprofilen slås til?"</string> - <string name="work_mode_off_message" msgid="5130856710614337649">"Dine arbejdsapps, underretninger, data og andre funktioner til din arbejdsprofil deaktiveres"</string> + <string name="work_mode_off_message" msgid="5130856710614337649">"Dine arbejdsapps, notifikationer, data og andre funktioner til din arbejdsprofil deaktiveres"</string> <string name="work_mode_turn_on" msgid="2062544985670564875">"Slå til"</string> <string name="deprecated_target_sdk_message" msgid="1449696506742572767">"Denne app er lavet til en ældre version af Android og fungerer muligvis ikke korrekt. Prøv at søge efter opdateringer, eller kontakt udvikleren."</string> <string name="deprecated_target_sdk_app_store" msgid="5032340500368495077">"Søg efter opdatering"</string> @@ -1872,11 +1872,11 @@ <string name="harmful_app_warning_title" msgid="8982527462829423432">"Der er registreret en skadelig app"</string> <string name="slices_permission_request" msgid="8484943441501672932">"<xliff:g id="APP_0">%1$s</xliff:g> anmoder om tilladelse til at vise eksempler fra <xliff:g id="APP_2">%2$s</xliff:g>"</string> <string name="screenshot_edit" msgid="7867478911006447565">"Rediger"</string> - <string name="volume_dialog_ringer_guidance_vibrate" msgid="8902050240801159042">"Telefonen vil vibrere ved opkald og underretninger"</string> - <string name="volume_dialog_ringer_guidance_silent" msgid="2128975224280276122">"Der afspilles ikke lyd ved opkald og underretninger"</string> + <string name="volume_dialog_ringer_guidance_vibrate" msgid="8902050240801159042">"Telefonen vil vibrere ved opkald og notifikationer"</string> + <string name="volume_dialog_ringer_guidance_silent" msgid="2128975224280276122">"Der afspilles ikke lyd ved opkald og notifikationer"</string> <string name="notification_channel_system_changes" msgid="5072715579030948646">"Systemændringer"</string> <string name="notification_channel_do_not_disturb" msgid="6766940333105743037">"Forstyr ikke"</string> - <string name="zen_upgrade_notification_visd_title" msgid="3288313883409759733">"Nyhed! Forstyr ikke skjuler underretninger"</string> + <string name="zen_upgrade_notification_visd_title" msgid="3288313883409759733">"Nyhed! Forstyr ikke skjuler notifikationer"</string> <string name="zen_upgrade_notification_visd_content" msgid="5533674060311631165">"Tryk for at få flere oplysninger og foretage ændringer."</string> <string name="zen_upgrade_notification_title" msgid="3799603322910377294">"Tilstanden Forstyr ikke blev ændret"</string> <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Tryk for at se, hvad der er blokeret."</string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 2e2bbade09f9..f75197d26b4c 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -604,7 +604,7 @@ <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"Anforderung, dass gespeicherte App-Daten verschlüsselt werden"</string> <string name="policylab_disableCamera" msgid="6395301023152297826">"Kameras deaktivieren"</string> <string name="policydesc_disableCamera" msgid="2306349042834754597">"Nutzung sämtlicher Gerätekameras unterbinden"</string> - <string name="policylab_disableKeyguardFeatures" msgid="8552277871075367771">"Einige Funktionen der Displaysperre deaktivieren"</string> + <string name="policylab_disableKeyguardFeatures" msgid="8552277871075367771">"Displaysperre teilweise deaktivieren"</string> <string name="policydesc_disableKeyguardFeatures" msgid="2044755691354158439">"Verwendung einiger Funktionen der Displaysperre verhindern"</string> <string-array name="phoneTypes"> <item msgid="8901098336658710359">"Privat"</item> diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index cebcc06230af..45e71b7e16da 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -1442,7 +1442,7 @@ <string name="action_menu_overflow_description" msgid="2295659037509008453">"మరిన్ని ఎంపికలు"</string> <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string> <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string> - <string name="storage_internal" msgid="3570990907910199483">"అంతర్గత భాగస్వామ్య నిల్వ"</string> + <string name="storage_internal" msgid="3570990907910199483">"షేర్ చేయబడిన అంతర్గత నిల్వ"</string> <string name="storage_sd_card" msgid="3282948861378286745">"SD కార్డు"</string> <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD కార్డ్"</string> <string name="storage_usb_drive" msgid="6261899683292244209">"USB డ్రైవ్"</string> diff --git a/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java b/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java index c8a53cc86347..9015e92a4f08 100644 --- a/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java +++ b/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java @@ -39,6 +39,8 @@ import android.service.textclassifier.TextClassifierService; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; +import android.text.Spannable; +import android.text.SpannableString; import org.hamcrest.BaseMatcher; import org.hamcrest.Description; @@ -307,6 +309,16 @@ public class TextClassificationManagerTest { } @Test + public void testApplyLinks_unsupportedCharacter() { + if (isTextClassifierDisabled()) return; + Spannable url = new SpannableString("\u202Emoc.diordna.com"); + TextLinks.Request request = new TextLinks.Request.Builder(url).build(); + assertEquals( + TextLinks.STATUS_NO_LINKS_APPLIED, + mClassifier.generateLinks(request).apply(url, 0, null)); + } + + @Test public void testSetTextClassifier() { TextClassifier classifier = mock(TextClassifier.class); mTcm.setTextClassifier(classifier); diff --git a/core/tests/coretests/src/android/widget/TextViewActivityTest.java b/core/tests/coretests/src/android/widget/TextViewActivityTest.java index 70dc6189c6c2..90758ba7c418 100644 --- a/core/tests/coretests/src/android/widget/TextViewActivityTest.java +++ b/core/tests/coretests/src/android/widget/TextViewActivityTest.java @@ -983,6 +983,19 @@ public class TextViewActivityTest { } @Test + public void testNoAssistItemForTextFieldWithUnsupportedCharacters() throws Throwable { + useSystemDefaultTextClassifier(); + final String text = "\u202Emoc.diordna.com"; + final TextView textView = mActivity.findViewById(R.id.textview); + mActivityRule.runOnUiThread(() -> textView.setText(text)); + mInstrumentation.waitForIdleSync(); + + onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('.'))); + sleepForFloatingToolbarPopup(); + assertFloatingToolbarDoesNotContainItem(android.R.id.textAssist); + } + + @Test public void testSelectionMetricsLogger_noAbandonAfterCopy() throws Throwable { final List<SelectionEvent> selectionEvents = new ArrayList<>(); final TextClassifier classifier = new TextClassifier() { diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml index b54404f215f0..27fbce49e9a1 100644 --- a/packages/SettingsLib/res/values-bs/strings.xml +++ b/packages/SettingsLib/res/values-bs/strings.xml @@ -27,7 +27,7 @@ <string name="wifi_disabled_network_failure" msgid="2364951338436007124">"Greška u konfiguraciji IP-a"</string> <string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"Niste povezani zbog slabog kvaliteta mreže"</string> <string name="wifi_disabled_wifi_failure" msgid="3081668066612876581">"Greška pri povezivanju na WiFi"</string> - <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Problem pri provjeri vjerodostojnosti."</string> + <string name="wifi_disabled_password_failure" msgid="8659805351763133575">"Problem pri autentifikaciji."</string> <string name="wifi_cant_connect" msgid="5410016875644565884">"Nije se moguće povezati"</string> <string name="wifi_cant_connect_to_ap" msgid="1222553274052685331">"Nije se moguće povezati na aplikaciju \'<xliff:g id="AP_NAME">%1$s</xliff:g>\'"</string> <string name="wifi_check_password_try_again" msgid="516958988102584767">"Provjerite lozinku i pokušajte ponovo"</string> diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml index fb9df2b24e0c..0b56f9661276 100644 --- a/packages/SettingsLib/res/values-da/strings.xml +++ b/packages/SettingsLib/res/values-da/strings.xml @@ -73,8 +73,8 @@ <string name="bluetooth_profile_opp" msgid="9168139293654233697">"Filoverførsel"</string> <string name="bluetooth_profile_hid" msgid="3680729023366986480">"Inputenhed"</string> <string name="bluetooth_profile_pan" msgid="3391606497945147673">"Internetadgang"</string> - <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Deling af kontaktpersoner"</string> - <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Brug til deling af kontaktpersoner"</string> + <string name="bluetooth_profile_pbap" msgid="5372051906968576809">"Deling af kontakter"</string> + <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Brug til deling af kontakter"</string> <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Deling af internetforbindelse"</string> <string name="bluetooth_profile_map" msgid="1019763341565580450">"Sms-beskeder"</string> <string name="bluetooth_profile_sap" msgid="5764222021851283125">"SIM-adgang"</string> @@ -102,7 +102,7 @@ <string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Par"</string> <string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"ACCEPTÉR PARRING"</string> <string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Annuller"</string> - <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"Parring giver adgang til dine kontaktpersoner og din opkaldshistorik, når enhederne er forbundet."</string> + <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"Parring giver adgang til dine kontakter og din opkaldshistorik, når enhederne er forbundet."</string> <string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"Der kunne ikke parres med <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string> <string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Der kunne ikke parres med <xliff:g id="DEVICE_NAME">%1$s</xliff:g> på grund af en forkert pinkode eller adgangsnøgle."</string> <string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Der kan ikke kommunikeres med <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string> @@ -252,7 +252,7 @@ <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Hold altid mobildata aktiveret, selv når Wi-Fi er aktiveret (for at skifte hurtigt mellem netværk)."</string> <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Brug hardwareacceleration ved netdeling, hvis det er muligt"</string> <string name="adb_warning_title" msgid="6234463310896563253">"Vil du tillade USB-fejlretning?"</string> - <string name="adb_warning_message" msgid="7316799925425402244">"USB-fejlretning er kun beregnet til udvikling og kan bruges til at kopiere data mellem din computer og enheden, installere apps på enheden uden underretning og læse logdata."</string> + <string name="adb_warning_message" msgid="7316799925425402244">"USB-fejlretning er kun beregnet til udvikling og kan bruges til at kopiere data mellem din computer og enheden, installere apps på enheden uden notifikation og læse logdata."</string> <string name="adb_keys_warning_message" msgid="5659849457135841625">"Vil du ophæve adgangen til USB-fejlfinding for alle computere, du tidligere har godkendt?"</string> <string name="dev_settings_warning_title" msgid="7244607768088540165">"Vil du tillade udviklingsindstillinger?"</string> <string name="dev_settings_warning_message" msgid="2298337781139097964">"Disse indstillinger er kun beregnet til brug i forbindelse med udvikling. De kan forårsage, at din enhed og dens apps går ned eller ikke fungerer korrekt."</string> @@ -318,8 +318,8 @@ <string name="app_process_limit_title" msgid="4280600650253107163">"Grænse for baggrundsprocesser"</string> <string name="show_all_anrs" msgid="4924885492787069007">"Vis ANR-fejl i baggrunden"</string> <string name="show_all_anrs_summary" msgid="6636514318275139826">"Vis dialogboksen \"Appen svarer ikke\" for baggrundsapps"</string> - <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Vis advarsler om underretningskanal"</string> - <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Viser en advarsel, når en app sender en underretning uden en gyldig kanal"</string> + <string name="show_notification_channel_warnings" msgid="1399948193466922683">"Vis advarsler om notifikationskanal"</string> + <string name="show_notification_channel_warnings_summary" msgid="5536803251863694895">"Viser en advarsel, når en app sender en notifikation uden en gyldig kanal"</string> <string name="force_allow_on_external" msgid="3215759785081916381">"Gennemtving tilladelse til eksternt lager"</string> <string name="force_allow_on_external_summary" msgid="3640752408258034689">"Gør det muligt at overføre enhver app til et eksternt lager uafhængigt af manifestværdier"</string> <string name="force_resizable_activities" msgid="8615764378147824985">"Tving aktiviteter til at kunne tilpasses"</string> diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml index 6a4e3800cf01..c78ac590033b 100644 --- a/packages/SettingsLib/res/values-es-rUS/strings.xml +++ b/packages/SettingsLib/res/values-es-rUS/strings.xml @@ -144,7 +144,7 @@ <string name="tts_settings_title" msgid="1237820681016639683">"Salida de texto a voz"</string> <string name="tts_default_rate_title" msgid="6030550998379310088">"Velocidad de voz"</string> <string name="tts_default_rate_summary" msgid="4061815292287182801">"Velocidad en la que se habla el texto"</string> - <string name="tts_default_pitch_title" msgid="6135942113172488671">"Sonido"</string> + <string name="tts_default_pitch_title" msgid="6135942113172488671">"Tono"</string> <string name="tts_default_pitch_summary" msgid="1944885882882650009">"Afecta el tono de la voz sintetizada"</string> <string name="tts_default_lang_title" msgid="8018087612299820556">"Idioma"</string> <string name="tts_lang_use_system" msgid="2679252467416513208">"Usar el idioma del sistema"</string> diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml index 2eec15aac810..8606802d5539 100644 --- a/packages/SettingsLib/res/values-fr/strings.xml +++ b/packages/SettingsLib/res/values-fr/strings.xml @@ -373,10 +373,10 @@ <string name="power_remaining_duration_only_enhanced" msgid="4189311599812296592">"Temps restant en fonction de votre utilisation : environ <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_discharging_duration_enhanced" msgid="1992003260664804080">"Temps restant en fonction de votre utilisation (<xliff:g id="LEVEL">%2$s</xliff:g>) : environ <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only_short" msgid="3463575350656389957">"Temps restant : <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string> - <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"Temps restant estimé en fonction de votre utilisation : <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"Temps restant estimé en fonction de votre utilisation : <xliff:g id="TIME">%1$s</xliff:g>"</string> - <string name="power_discharge_by" msgid="6453537733650125582">"Temps restant estimé : <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> - <string name="power_discharge_by_only" msgid="107616694963545745">"Temps restant estimé : <xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g> en fonction de votre utilisation (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g> en fonction de votre utilisation"</string> + <string name="power_discharge_by" msgid="6453537733650125582">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> + <string name="power_discharge_by_only" msgid="107616694963545745">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Il reste moins de <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string> <string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Il reste moins de <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> <string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Il reste plus de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string> diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml index 399dc5d07022..7a602691f254 100644 --- a/packages/SettingsLib/res/values-nl/strings.xml +++ b/packages/SettingsLib/res/values-nl/strings.xml @@ -144,7 +144,7 @@ <string name="tts_settings_title" msgid="1237820681016639683">"Spraakuitvoer"</string> <string name="tts_default_rate_title" msgid="6030550998379310088">"Spreeksnelheid"</string> <string name="tts_default_rate_summary" msgid="4061815292287182801">"Snelheid waarmee de tekst wordt gesproken"</string> - <string name="tts_default_pitch_title" msgid="6135942113172488671">"Hoogte"</string> + <string name="tts_default_pitch_title" msgid="6135942113172488671">"Toonhoogte"</string> <string name="tts_default_pitch_summary" msgid="1944885882882650009">"Is van invloed op de toon van de synthetisch gegenereerde spraak"</string> <string name="tts_default_lang_title" msgid="8018087612299820556">"Taal"</string> <string name="tts_lang_use_system" msgid="2679252467416513208">"Systeemtaal gebruiken"</string> @@ -236,7 +236,7 @@ <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Opties weergeven voor certificering van draadloze weergave"</string> <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Logniveau voor wifi verhogen, weergeven per SSID RSSI in wifi-kiezer"</string> <string name="wifi_connected_mac_randomization_summary" msgid="1743059848752201485">"Een willekeurig MAC-adres bij het maken van verbinding met wifi-netwerken"</string> - <string name="wifi_metered_label" msgid="4514924227256839725">"Betaald"</string> + <string name="wifi_metered_label" msgid="4514924227256839725">"Met datalimiet"</string> <string name="wifi_unmetered_label" msgid="6124098729457992931">"Gratis"</string> <string name="select_logd_size_title" msgid="7433137108348553508">"Logger-buffergrootten"</string> <string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Kies Logger-grootten per logbuffer"</string> diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml index a8e7704cd5dc..899a58d4191a 100644 --- a/packages/SettingsLib/res/values-pa/strings.xml +++ b/packages/SettingsLib/res/values-pa/strings.xml @@ -142,7 +142,7 @@ <string name="launch_defaults_none" msgid="4241129108140034876">"ਕੋਈ ਡਿਫੌਲਟਸ ਸੈਟ ਨਹੀਂ ਕੀਤੇ"</string> <string name="tts_settings" msgid="8186971894801348327">"ਲਿਖਤ ਤੋਂ ਬੋਲੀ ਸੈਟਿੰਗਾਂ"</string> <string name="tts_settings_title" msgid="1237820681016639683">"ਲਿਖਤ-ਤੋਂ-ਬੋਲੀ ਆਊਟਪੁੱਟ"</string> - <string name="tts_default_rate_title" msgid="6030550998379310088">"ਸਪੀਚ ਰੇਟ"</string> + <string name="tts_default_rate_title" msgid="6030550998379310088">"ਬੋਲਣ ਦੀ ਗਤੀ"</string> <string name="tts_default_rate_summary" msgid="4061815292287182801">"ਸਪੀਡ ਜਿਸਤੇ ਟੈਕਸਟ ਬੋਲਿਆ ਜਾਂਦਾ ਹੈ"</string> <string name="tts_default_pitch_title" msgid="6135942113172488671">"ਪਿਚ"</string> <string name="tts_default_pitch_summary" msgid="1944885882882650009">"ਬਣਾਵਟੀ ਬੋਲੀ ਦੇ ਲਹਿਜੇ \'ਤੇ ਅਸਰ ਪਾਉਂਦੀ ਹੈ"</string> diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml index 29012a930f3c..d991e84f879a 100644 --- a/packages/SettingsLib/res/values-pt-rBR/strings.xml +++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml @@ -142,9 +142,9 @@ <string name="launch_defaults_none" msgid="4241129108140034876">"Nenhum padrão definido"</string> <string name="tts_settings" msgid="8186971894801348327">"Configurações da conversão de texto em voz"</string> <string name="tts_settings_title" msgid="1237820681016639683">"Conversão de texto em voz"</string> - <string name="tts_default_rate_title" msgid="6030550998379310088">"Taxa de fala"</string> + <string name="tts_default_rate_title" msgid="6030550998379310088">"Velocidade da fala"</string> <string name="tts_default_rate_summary" msgid="4061815292287182801">"Velocidade em que o texto é falado"</string> - <string name="tts_default_pitch_title" msgid="6135942113172488671">"Tom da fala"</string> + <string name="tts_default_pitch_title" msgid="6135942113172488671">"Tom de voz"</string> <string name="tts_default_pitch_summary" msgid="1944885882882650009">"Afeta o tom da voz sintetizada"</string> <string name="tts_default_lang_title" msgid="8018087612299820556">"Idioma"</string> <string name="tts_lang_use_system" msgid="2679252467416513208">"Usar idioma do sistema"</string> @@ -166,8 +166,8 @@ <string name="tts_engine_settings_button" msgid="1030512042040722285">"Iniciar configurações do mecanismo"</string> <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Mecanismo preferencial"</string> <string name="tts_general_section_title" msgid="4402572014604490502">"Gerais"</string> - <string name="tts_reset_speech_pitch_title" msgid="5789394019544785915">"Redefinir o tom da fala"</string> - <string name="tts_reset_speech_pitch_summary" msgid="8700539616245004418">"Redefinir o tom no qual o texto é falado para o padrão."</string> + <string name="tts_reset_speech_pitch_title" msgid="5789394019544785915">"Redefinir o tom de voz"</string> + <string name="tts_reset_speech_pitch_summary" msgid="8700539616245004418">"Redefinir o tom de voz para o padrão."</string> <string-array name="tts_rate_entries"> <item msgid="6695494874362656215">"Muito devagar"</item> <item msgid="4795095314303559268">"Devagar"</item> diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml index 29012a930f3c..d991e84f879a 100644 --- a/packages/SettingsLib/res/values-pt/strings.xml +++ b/packages/SettingsLib/res/values-pt/strings.xml @@ -142,9 +142,9 @@ <string name="launch_defaults_none" msgid="4241129108140034876">"Nenhum padrão definido"</string> <string name="tts_settings" msgid="8186971894801348327">"Configurações da conversão de texto em voz"</string> <string name="tts_settings_title" msgid="1237820681016639683">"Conversão de texto em voz"</string> - <string name="tts_default_rate_title" msgid="6030550998379310088">"Taxa de fala"</string> + <string name="tts_default_rate_title" msgid="6030550998379310088">"Velocidade da fala"</string> <string name="tts_default_rate_summary" msgid="4061815292287182801">"Velocidade em que o texto é falado"</string> - <string name="tts_default_pitch_title" msgid="6135942113172488671">"Tom da fala"</string> + <string name="tts_default_pitch_title" msgid="6135942113172488671">"Tom de voz"</string> <string name="tts_default_pitch_summary" msgid="1944885882882650009">"Afeta o tom da voz sintetizada"</string> <string name="tts_default_lang_title" msgid="8018087612299820556">"Idioma"</string> <string name="tts_lang_use_system" msgid="2679252467416513208">"Usar idioma do sistema"</string> @@ -166,8 +166,8 @@ <string name="tts_engine_settings_button" msgid="1030512042040722285">"Iniciar configurações do mecanismo"</string> <string name="tts_engine_preference_section_title" msgid="448294500990971413">"Mecanismo preferencial"</string> <string name="tts_general_section_title" msgid="4402572014604490502">"Gerais"</string> - <string name="tts_reset_speech_pitch_title" msgid="5789394019544785915">"Redefinir o tom da fala"</string> - <string name="tts_reset_speech_pitch_summary" msgid="8700539616245004418">"Redefinir o tom no qual o texto é falado para o padrão."</string> + <string name="tts_reset_speech_pitch_title" msgid="5789394019544785915">"Redefinir o tom de voz"</string> + <string name="tts_reset_speech_pitch_summary" msgid="8700539616245004418">"Redefinir o tom de voz para o padrão."</string> <string-array name="tts_rate_entries"> <item msgid="6695494874362656215">"Muito devagar"</item> <item msgid="4795095314303559268">"Devagar"</item> diff --git a/packages/SettingsLib/res/values-te/arrays.xml b/packages/SettingsLib/res/values-te/arrays.xml index ddb40ce96c94..5d79065885d2 100644 --- a/packages/SettingsLib/res/values-te/arrays.xml +++ b/packages/SettingsLib/res/values-te/arrays.xml @@ -173,7 +173,7 @@ <item msgid="2850427388488887328">"కెర్నెల్ మాత్రమే"</item> </string-array> <string-array name="select_logpersist_summaries"> - <item msgid="2216470072500521830">"ఆఫ్ చేయి"</item> + <item msgid="2216470072500521830">"ఆఫ్"</item> <item msgid="172978079776521897">"అన్ని లాగ్ బఫర్లు"</item> <item msgid="3873873912383879240">"అన్నీ కానీ రేడియో లాగ్ బఫర్లు"</item> <item msgid="8489661142527693381">"కెర్నెల్ లాగ్ బఫర్ మాత్రమే"</item> diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java index 505cfeac220c..2d321f9a1a9a 100644 --- a/packages/SettingsLib/src/com/android/settingslib/Utils.java +++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java @@ -35,8 +35,8 @@ public class Utils { private static final String CURRENT_MODE_KEY = "CURRENT_MODE"; private static final String NEW_MODE_KEY = "NEW_MODE"; @VisibleForTesting - static final String STORAGE_MANAGER_SHOW_OPT_IN_PROPERTY = - "ro.storage_manager.show_opt_in"; + static final String STORAGE_MANAGER_ENABLED_PROPERTY = + "ro.storage_manager.enabled"; private static Signature[] sSystemSignature; private static String sPermissionControllerPackageName; @@ -353,8 +353,7 @@ public class Utils { public static boolean isStorageManagerEnabled(Context context) { boolean isDefaultOn; try { - // Turn off by default if the opt-in was shown. - isDefaultOn = !SystemProperties.getBoolean(STORAGE_MANAGER_SHOW_OPT_IN_PROPERTY, true); + isDefaultOn = SystemProperties.getBoolean(STORAGE_MANAGER_ENABLED_PROPERTY, false); } catch (Resources.NotFoundException e) { isDefaultOn = false; } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java index a79f841e70c6..2dd57ff60bbe 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java @@ -17,7 +17,7 @@ package com.android.settingslib; import static android.Manifest.permission.WRITE_SECURE_SETTINGS; -import static com.android.settingslib.Utils.STORAGE_MANAGER_SHOW_OPT_IN_PROPERTY; +import static com.android.settingslib.Utils.STORAGE_MANAGER_ENABLED_PROPERTY; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.argThat; @@ -160,7 +160,7 @@ public class UtilsTest { @Test public void testIsStorageManagerEnabled_UsesSystemProperties() { - SystemProperties.set(STORAGE_MANAGER_SHOW_OPT_IN_PROPERTY, "false"); + SystemProperties.set(STORAGE_MANAGER_ENABLED_PROPERTY, "true"); assertThat(Utils.isStorageManagerEnabled(mContext)).isTrue(); } diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java index 73393047cc45..f495cedbf028 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java @@ -38,6 +38,7 @@ public class DozeService extends DreamService private DozeMachine mDozeMachine; private DozeServicePlugin mDozePlugin; + private PluginManager mPluginManager; public DozeService() { setDebug(DEBUG); @@ -53,14 +54,14 @@ public class DozeService extends DreamService finish(); return; } - Dependency.get(PluginManager.class).addPluginListener(this, - DozeServicePlugin.class, false /* Allow multiple */); + mPluginManager = Dependency.get(PluginManager.class); + mPluginManager.addPluginListener(this, DozeServicePlugin.class, false /* allowMultiple */); mDozeMachine = new DozeFactory().assembleMachine(this); } @Override public void onDestroy() { - Dependency.get(PluginManager.class).removePluginListener(this); + mPluginManager.removePluginListener(this); super.onDestroy(); mDozeMachine = null; } diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java index f79a51b13afd..47b646c1a667 100644 --- a/services/core/java/com/android/server/AlarmManagerService.java +++ b/services/core/java/com/android/server/AlarmManagerService.java @@ -48,6 +48,7 @@ import android.content.pm.PermissionInfo; import android.database.ContentObserver; import android.net.Uri; import android.os.Binder; +import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.os.Handler; @@ -1288,9 +1289,13 @@ class AlarmManagerService extends SystemService { // because kernel doesn't keep this after reboot setTimeZoneImpl(SystemProperties.get(TIMEZONE_PROPERTY)); - // Also sure that we're booting with a halfway sensible current time if (mNativeData != 0) { - final long systemBuildTime = Environment.getRootDirectory().lastModified(); + // Ensure that we're booting with a halfway sensible current time. Use the + // most recent of Build.TIME, the root file system's timestamp, and the + // value of the ro.build.date.utc system property (which is in seconds). + final long systemBuildTime = Long.max( + 1000L * SystemProperties.getLong("ro.build.date.utc", -1L), + Long.max(Environment.getRootDirectory().lastModified(), Build.TIME)); if (System.currentTimeMillis() < systemBuildTime) { Slog.i(TAG, "Current time only " + System.currentTimeMillis() + ", advancing to build time " + systemBuildTime); diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java index 78b738500a97..555e89947a64 100644 --- a/services/core/java/com/android/server/BluetoothManagerService.java +++ b/services/core/java/com/android/server/BluetoothManagerService.java @@ -76,6 +76,7 @@ import java.util.HashMap; import java.util.LinkedList; import java.util.Locale; import java.util.Map; +import java.util.NoSuchElementException; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -1174,6 +1175,26 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } private boolean bindService() { + int state = BluetoothAdapter.STATE_OFF; + try { + mBluetoothLock.readLock().lock(); + if (mBluetooth != null) { + state = mBluetooth.getState(); + } + } catch (RemoteException e) { + Slog.e(TAG, "Unable to call getState", e); + return false; + } finally { + mBluetoothLock.readLock().unlock(); + } + + if (!mEnable || state != BluetoothAdapter.STATE_ON) { + if (DBG) { + Slog.d(TAG, "Unable to bindService while Bluetooth is disabled"); + } + return false; + } + if (mIntent != null && mService == null && doBind(mIntent, this, 0, UserHandle.CURRENT_OR_SELF)) { Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE); @@ -1259,7 +1280,11 @@ class BluetoothManagerService extends IBluetoothManager.Stub { if (mService == null) { return; } - mService.unlinkToDeath(this, 0); + try { + mService.unlinkToDeath(this, 0); + } catch (NoSuchElementException e) { + Log.e(TAG, "error unlinking to death", e); + } mService = null; mClassName = null; diff --git a/services/core/java/com/android/server/content/SyncLogger.java b/services/core/java/com/android/server/content/SyncLogger.java index 8c35e27671eb..b714077aab0f 100644 --- a/services/core/java/com/android/server/content/SyncLogger.java +++ b/services/core/java/com/android/server/content/SyncLogger.java @@ -16,6 +16,7 @@ package com.android.server.content; +import android.accounts.Account; import android.app.job.JobParameters; import android.os.Build; import android.os.Environment; @@ -26,6 +27,8 @@ import android.util.Log; import android.util.Slog; import com.android.internal.annotations.GuardedBy; +import com.android.server.content.SyncManager.ActiveSyncContext; +import com.android.server.content.SyncStorageEngine.EndPoint; import libcore.io.IoUtils; @@ -273,4 +276,20 @@ public class SyncLogger { } } } + + static String logSafe(Account account) { + return account == null ? "[null]" : "***/" + account.type; + } + + static String logSafe(EndPoint endPoint) { + return endPoint == null ? "[null]" : endPoint.toSafeString(); + } + + static String logSafe(SyncOperation operation) { + return operation == null ? "[null]" : operation.toSafeString(); + } + + static String logSafe(ActiveSyncContext asc) { + return asc == null ? "[null]" : asc.toSafeString(); + } } diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java index 0a640b8a76c6..132bf0bc9978 100644 --- a/services/core/java/com/android/server/content/SyncManager.java +++ b/services/core/java/com/android/server/content/SyncManager.java @@ -16,6 +16,8 @@ package com.android.server.content; +import static com.android.server.content.SyncLogger.logSafe; + import android.accounts.Account; import android.accounts.AccountAndUser; import android.accounts.AccountManager; @@ -1175,7 +1177,7 @@ public class SyncManager { /* ignore - local call */ } if (checkAccountAccess && !canAccessAccount(account, owningPackage, owningUid)) { - Log.w(TAG, "Access to " + account + " denied for package " + Log.w(TAG, "Access to " + logSafe(account) + " denied for package " + owningPackage + " in UID " + syncAdapterInfo.uid); return AuthorityInfo.SYNCABLE_NO_ACCOUNT_ACCESS; } @@ -1508,7 +1510,8 @@ public class SyncManager { if (!syncOperation.ignoreBackoff()) { Pair<Long, Long> backoff = mSyncStorageEngine.getBackoff(syncOperation.target); if (backoff == null) { - Slog.e(TAG, "Couldn't find backoff values for " + syncOperation.target); + Slog.e(TAG, "Couldn't find backoff values for " + + logSafe(syncOperation.target)); backoff = new Pair<Long, Long>(SyncStorageEngine.NOT_IN_BACKOFF_MODE, SyncStorageEngine.NOT_IN_BACKOFF_MODE); } @@ -1779,8 +1782,8 @@ public class SyncManager { scheduleSyncOperationH(operation); } else { // Otherwise do not reschedule. - Log.d(TAG, "not retrying sync operation because the error is a hard error: " - + operation); + Log.e(TAG, "not retrying sync operation because the error is a hard error: " + + logSafe(operation)); } } @@ -1914,11 +1917,12 @@ public class SyncManager { sendSyncFinishedOrCanceledMessage(this, result); } - public void toString(StringBuilder sb) { + public void toString(StringBuilder sb, boolean logSafe) { sb.append("startTime ").append(mStartTime) .append(", mTimeoutStartTime ").append(mTimeoutStartTime) .append(", mHistoryRowId ").append(mHistoryRowId) - .append(", syncOperation ").append(mSyncOperation); + .append(", syncOperation ").append( + logSafe ? logSafe(mSyncOperation) : mSyncOperation); } public void onServiceConnected(ComponentName name, IBinder service) { @@ -1980,7 +1984,13 @@ public class SyncManager { public String toString() { StringBuilder sb = new StringBuilder(); - toString(sb); + toString(sb, false); + return sb.toString(); + } + + public String toSafeString() { + StringBuilder sb = new StringBuilder(); + toString(sb, true); return sb.toString(); } @@ -2069,7 +2079,7 @@ public class SyncManager { int count = 0; for (SyncOperation op: pendingSyncs) { if (!op.isPeriodic) { - pw.println(op.dump(null, false, buckets)); + pw.println(op.dump(null, false, buckets, /*logSafe=*/ false)); count++; } } @@ -2086,7 +2096,7 @@ public class SyncManager { int count = 0; for (SyncOperation op: pendingSyncs) { if (op.isPeriodic) { - pw.println(op.dump(null, false, buckets)); + pw.println(op.dump(null, false, buckets, /*logSafe=*/ false)); count++; } } @@ -2219,7 +2229,7 @@ public class SyncManager { sb.setLength(0); pw.print(formatDurationHMS(sb, durationInSeconds)); pw.print(" - "); - pw.print(activeSyncContext.mSyncOperation.dump(pm, false, buckets)); + pw.print(activeSyncContext.mSyncOperation.dump(pm, false, buckets, /*logSafe=*/ false)); pw.println(); } pw.println(); @@ -3050,7 +3060,7 @@ public class SyncManager { case SyncHandler.MESSAGE_CANCEL: SyncStorageEngine.EndPoint endpoint = (SyncStorageEngine.EndPoint) msg.obj; Bundle extras = msg.peekData(); - if (Log.isLoggable(TAG, Log.DEBUG)) { + if (isLoggable) { Log.d(TAG, "handleSyncHandlerMessage: MESSAGE_CANCEL: " + endpoint + " bundle: " + extras); } @@ -3061,9 +3071,11 @@ public class SyncManager { SyncFinishedOrCancelledMessagePayload payload = (SyncFinishedOrCancelledMessagePayload) msg.obj; if (!isSyncStillActiveH(payload.activeSyncContext)) { - Log.d(TAG, "handleSyncHandlerMessage: dropping since the " - + "sync is no longer active: " - + payload.activeSyncContext); + if (isLoggable) { + Log.d(TAG, "handleSyncHandlerMessage: dropping since the " + + "sync is no longer active: " + + payload.activeSyncContext); + } break; } if (isLoggable) { @@ -3078,7 +3090,7 @@ public class SyncManager { case SyncHandler.MESSAGE_SERVICE_CONNECTED: { ServiceConnectionData msgData = (ServiceConnectionData) msg.obj; - if (Log.isLoggable(TAG, Log.VERBOSE)) { + if (isLoggable) { Log.d(TAG, "handleSyncHandlerMessage: MESSAGE_SERVICE_CONNECTED: " + msgData.activeSyncContext); } @@ -3094,7 +3106,7 @@ public class SyncManager { case SyncHandler.MESSAGE_SERVICE_DISCONNECTED: { final ActiveSyncContext currentSyncContext = ((ServiceConnectionData) msg.obj).activeSyncContext; - if (Log.isLoggable(TAG, Log.VERBOSE)) { + if (isLoggable) { Log.d(TAG, "handleSyncHandlerMessage: MESSAGE_SERVICE_DISCONNECTED: " + currentSyncContext); } @@ -3129,7 +3141,7 @@ public class SyncManager { case SyncHandler.MESSAGE_MONITOR_SYNC: ActiveSyncContext monitoredSyncContext = (ActiveSyncContext) msg.obj; - if (Log.isLoggable(TAG, Log.DEBUG)) { + if (isLoggable) { Log.d(TAG, "handleSyncHandlerMessage: MESSAGE_MONITOR_SYNC: " + monitoredSyncContext.mSyncOperation.target); } @@ -3137,7 +3149,7 @@ public class SyncManager { if (isSyncNotUsingNetworkH(monitoredSyncContext)) { Log.w(TAG, String.format( "Detected sync making no progress for %s. cancelling.", - monitoredSyncContext)); + logSafe(monitoredSyncContext))); mSyncJobService.callJobFinished( monitoredSyncContext.mSyncOperation.jobId, false, "no network activity"); @@ -3636,7 +3648,8 @@ public class SyncManager { } catch (RuntimeException exc) { mLogger.log("Sync failed with RuntimeException: ", exc.toString()); closeActiveSyncContext(activeSyncContext); - Slog.e(TAG, "Caught RuntimeException while starting the sync " + syncOperation, exc); + Slog.e(TAG, "Caught RuntimeException while starting the sync " + + logSafe(syncOperation), exc); } } @@ -3736,7 +3749,8 @@ public class SyncManager { reschedulePeriodicSyncH(syncOperation); } } else { - Log.w(TAG, "failed sync operation " + syncOperation + ", " + syncResult); + Log.w(TAG, "failed sync operation " + + logSafe(syncOperation) + ", " + syncResult); syncOperation.retries++; if (syncOperation.retries > mConstants.getMaxRetriesWithAppStandbyExemption()) { @@ -4120,11 +4134,6 @@ public class SyncManager { getJobScheduler().cancel(op.jobId); } - private void wtfWithLog(String message) { - Slog.wtf(TAG, message); - mLogger.log("WTF: ", message); - } - public void resetTodayStats() { mSyncStorageEngine.resetTodayStats(/*force=*/ true); } diff --git a/services/core/java/com/android/server/content/SyncOperation.java b/services/core/java/com/android/server/content/SyncOperation.java index 25edf4070689..2abc2e60a47b 100644 --- a/services/core/java/com/android/server/content/SyncOperation.java +++ b/services/core/java/com/android/server/content/SyncOperation.java @@ -363,14 +363,19 @@ public class SyncOperation { @Override public String toString() { - return dump(null, true, null); + return dump(null, true, null, false); } - String dump(PackageManager pm, boolean shorter, SyncAdapterStateFetcher appStates) { + public String toSafeString() { + return dump(null, true, null, true); + } + + String dump(PackageManager pm, boolean shorter, SyncAdapterStateFetcher appStates, + boolean logSafe) { StringBuilder sb = new StringBuilder(); sb.append("JobId=").append(jobId) .append(" ") - .append(target.account.name) + .append(logSafe ? "***" : target.account.name) .append("/") .append(target.account.type) .append(" u") diff --git a/services/core/java/com/android/server/content/SyncStorageEngine.java b/services/core/java/com/android/server/content/SyncStorageEngine.java index 11f07015ef12..0a2af9ee109b 100644 --- a/services/core/java/com/android/server/content/SyncStorageEngine.java +++ b/services/core/java/com/android/server/content/SyncStorageEngine.java @@ -16,6 +16,8 @@ package com.android.server.content; +import static com.android.server.content.SyncLogger.logSafe; + import android.accounts.Account; import android.accounts.AccountAndUser; import android.accounts.AccountManager; @@ -228,6 +230,15 @@ public class SyncStorageEngine { sb.append(":u" + userId); return sb.toString(); } + + public String toSafeString() { + StringBuilder sb = new StringBuilder(); + sb.append(account == null ? "ALL ACCS" : logSafe(account)) + .append("/") + .append(provider == null ? "ALL PDRS" : provider); + sb.append(":u" + userId); + return sb.toString(); + } } public static class AuthorityInfo { @@ -1863,8 +1874,8 @@ public class SyncStorageEngine { } } else { - Slog.w(TAG, "Failure adding authority: account=" - + accountName + " auth=" + authorityName + Slog.w(TAG, "Failure adding authority:" + + " auth=" + authorityName + " enabled=" + enabled + " syncable=" + syncable); } diff --git a/services/core/java/com/android/server/locksettings/SP800Derive.java b/services/core/java/com/android/server/locksettings/SP800Derive.java new file mode 100644 index 000000000000..77561fc30db9 --- /dev/null +++ b/services/core/java/com/android/server/locksettings/SP800Derive.java @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.locksettings; + +import java.nio.ByteBuffer; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; + +/** + * Implementation of NIST SP800-108 + * "Recommendation for Key Derivation Using Pseudorandom Functions" + * Hardcoded: + * [PRF=HMAC_SHA256] + * [CTRLOCATION=BEFORE_FIXED] + * [RLEN=32_BITS] + * L = 256 + * L suffix: 32 bits + */ +class SP800Derive { + private final byte[] mKeyBytes; + + SP800Derive(byte[] keyBytes) { + mKeyBytes = keyBytes; + } + + private Mac getMac() { + try { + final Mac m = Mac.getInstance("HmacSHA256"); + m.init(new SecretKeySpec(mKeyBytes, m.getAlgorithm())); + return m; + } catch (InvalidKeyException | NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } + } + + private static void update32(Mac m, int v) { + m.update(ByteBuffer.allocate(Integer.BYTES).putInt(v).array()); + } + + /** + * Generate output from a single, fixed input. + */ + public byte[] fixedInput(byte[] fixedInput) { + final Mac m = getMac(); + update32(m, 1); // Hardwired counter value + m.update(fixedInput); + return m.doFinal(); + } + + /** + * Generate output from a label and context. We add a length field at the end of the context to + * disambiguate it from the length even in the presence of zero bytes. + */ + public byte[] withContext(byte[] label, byte[] context) { + final Mac m = getMac(); + // Hardwired counter value: 1 + update32(m, 1); // Hardwired counter value + m.update(label); + m.update((byte) 0); + m.update(context); + update32(m, context.length * 8); // Disambiguate context + update32(m, 256); // Hardwired output length + return m.doFinal(); + } +} diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java index 596daeb1427b..d32c299074a9 100644 --- a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java +++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java @@ -26,9 +26,9 @@ import android.hardware.weaver.V1_0.WeaverConfig; import android.hardware.weaver.V1_0.WeaverReadResponse; import android.hardware.weaver.V1_0.WeaverReadStatus; import android.hardware.weaver.V1_0.WeaverStatus; -import android.security.GateKeeper; import android.os.RemoteException; import android.os.UserManager; +import android.security.GateKeeper; import android.service.gatekeeper.GateKeeperResponse; import android.service.gatekeeper.IGateKeeperService; import android.util.ArrayMap; @@ -102,7 +102,8 @@ public class SyntheticPasswordManager { private static final int INVALID_WEAVER_SLOT = -1; private static final byte SYNTHETIC_PASSWORD_VERSION_V1 = 1; - private static final byte SYNTHETIC_PASSWORD_VERSION = 2; + private static final byte SYNTHETIC_PASSWORD_VERSION_V2 = 2; + private static final byte SYNTHETIC_PASSWORD_VERSION_V3 = 3; private static final byte SYNTHETIC_PASSWORD_PASSWORD_BASED = 0; private static final byte SYNTHETIC_PASSWORD_TOKEN_BASED = 1; @@ -128,6 +129,8 @@ public class SyntheticPasswordManager { private static final byte[] PERSONALISATION_WEAVER_PASSWORD = "weaver-pwd".getBytes(); private static final byte[] PERSONALISATION_WEAVER_KEY = "weaver-key".getBytes(); private static final byte[] PERSONALISATION_WEAVER_TOKEN = "weaver-token".getBytes(); + private static final byte[] PERSONALISATION_CONTEXT = + "android-synthetic-password-personalization-context".getBytes(); static class AuthenticationResult { public AuthenticationToken authToken; @@ -136,6 +139,7 @@ public class SyntheticPasswordManager { } static class AuthenticationToken { + private final byte mVersion; /* * Here is the relationship between all three fields: * P0 and P1 are two randomly-generated blocks. P1 is stored on disk but P0 is not. @@ -146,29 +150,38 @@ public class SyntheticPasswordManager { private @Nullable byte[] P1; private @NonNull String syntheticPassword; + AuthenticationToken(byte version) { + mVersion = version; + } + + private byte[] derivePassword(byte[] personalization) { + if (mVersion == SYNTHETIC_PASSWORD_VERSION_V3) { + return (new SP800Derive(syntheticPassword.getBytes())) + .withContext(personalization, PERSONALISATION_CONTEXT); + } else { + return SyntheticPasswordCrypto.personalisedHash(personalization, + syntheticPassword.getBytes()); + } + } + public String deriveKeyStorePassword() { - return bytesToHex(SyntheticPasswordCrypto.personalisedHash( - PERSONALIZATION_KEY_STORE_PASSWORD, syntheticPassword.getBytes())); + return bytesToHex(derivePassword(PERSONALIZATION_KEY_STORE_PASSWORD)); } public byte[] deriveGkPassword() { - return SyntheticPasswordCrypto.personalisedHash(PERSONALIZATION_SP_GK_AUTH, - syntheticPassword.getBytes()); + return derivePassword(PERSONALIZATION_SP_GK_AUTH); } public byte[] deriveDiskEncryptionKey() { - return SyntheticPasswordCrypto.personalisedHash(PERSONALIZATION_FBE_KEY, - syntheticPassword.getBytes()); + return derivePassword(PERSONALIZATION_FBE_KEY); } public byte[] deriveVendorAuthSecret() { - return SyntheticPasswordCrypto.personalisedHash(PERSONALIZATION_AUTHSECRET_KEY, - syntheticPassword.getBytes()); + return derivePassword(PERSONALIZATION_AUTHSECRET_KEY); } public byte[] derivePasswordHashFactor() { - return SyntheticPasswordCrypto.personalisedHash(PERSONALIZATION_PASSWORD_HASH, - syntheticPassword.getBytes()); + return derivePassword(PERSONALIZATION_PASSWORD_HASH); } private void initialize(byte[] P0, byte[] P1) { @@ -185,7 +198,7 @@ public class SyntheticPasswordManager { } protected static AuthenticationToken create() { - AuthenticationToken result = new AuthenticationToken(); + AuthenticationToken result = new AuthenticationToken(SYNTHETIC_PASSWORD_VERSION_V3); result.initialize(secureRandom(SYNTHETIC_PASSWORD_LENGTH), secureRandom(SYNTHETIC_PASSWORD_LENGTH)); return result; @@ -802,7 +815,16 @@ public class SyntheticPasswordManager { } byte[] content = createSPBlob(getHandleName(handle), secret, applicationId, sid); byte[] blob = new byte[content.length + 1 + 1]; - blob[0] = SYNTHETIC_PASSWORD_VERSION; + /* + * We can upgrade from v1 to v2 because that's just a change in the way that + * the SP is stored. However, we can't upgrade to v3 because that is a change + * in the way that passwords are derived from the SP. + */ + if (authToken.mVersion == SYNTHETIC_PASSWORD_VERSION_V3) { + blob[0] = SYNTHETIC_PASSWORD_VERSION_V3; + } else { + blob[0] = SYNTHETIC_PASSWORD_VERSION_V2; + } blob[1] = type; System.arraycopy(content, 0, blob, 2, content.length); saveState(SP_BLOB_NAME, blob, handle, userId); @@ -940,7 +962,9 @@ public class SyntheticPasswordManager { return null; } final byte version = blob[0]; - if (version != SYNTHETIC_PASSWORD_VERSION && version != SYNTHETIC_PASSWORD_VERSION_V1) { + if (version != SYNTHETIC_PASSWORD_VERSION_V3 + && version != SYNTHETIC_PASSWORD_VERSION_V2 + && version != SYNTHETIC_PASSWORD_VERSION_V1) { throw new RuntimeException("Unknown blob version"); } if (blob[1] != type) { @@ -958,7 +982,7 @@ public class SyntheticPasswordManager { Log.e(TAG, "Fail to decrypt SP for user " + userId); return null; } - AuthenticationToken result = new AuthenticationToken(); + AuthenticationToken result = new AuthenticationToken(version); if (type == SYNTHETIC_PASSWORD_TOKEN_BASED) { if (!loadEscrowData(result, userId)) { Log.e(TAG, "User is not escrowable: " + userId); diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index b7247166855d..82363d102c40 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -1249,6 +1249,11 @@ public class NotificationManagerService extends SystemService { } @VisibleForTesting + void setHints(int hints) { + mListenerHints = hints; + } + + @VisibleForTesting void setVibrator(Vibrator vibrator) { mVibrator = vibrator; } @@ -3689,6 +3694,20 @@ public class NotificationManagerService extends SystemService { if ((mListenerHints & HINT_HOST_DISABLE_EFFECTS) != 0) { return "listenerHints"; } + if (record != null && record.getAudioAttributes() != null) { + if ((mListenerHints & HINT_HOST_DISABLE_NOTIFICATION_EFFECTS) != 0) { + if (record.getAudioAttributes().getUsage() + != AudioAttributes.USAGE_VOICE_COMMUNICATION) { + return "listenerNoti"; + } + } + if ((mListenerHints & HINT_HOST_DISABLE_CALL_EFFECTS) != 0) { + if (record.getAudioAttributes().getUsage() + == AudioAttributes.USAGE_VOICE_COMMUNICATION) { + return "listenerCall"; + } + } + } if (mCallState != TelephonyManager.CALL_STATE_IDLE && !mZenModeHelper.isCall(record)) { return "callState"; } @@ -3960,25 +3979,30 @@ public class NotificationManagerService extends SystemService { public void removeForegroundServiceFlagFromNotification(String pkg, int notificationId, int userId) { checkCallerIsSystem(); - mHandler.post(new Runnable() { - @Override - public void run() { - synchronized (mNotificationLock) { - removeForegroundServiceFlagByListLocked( - mEnqueuedNotifications, pkg, notificationId, userId); - removeForegroundServiceFlagByListLocked( - mNotificationList, pkg, notificationId, userId); + mHandler.post(() -> { + synchronized (mNotificationLock) { + // strip flag from all enqueued notifications. listeners will be informed + // in post runnable. + List<NotificationRecord> enqueued = findNotificationsByListLocked( + mEnqueuedNotifications, pkg, null, notificationId, userId); + for (int i = 0; i < enqueued.size(); i++) { + removeForegroundServiceFlagLocked(enqueued.get(i)); + } + + // if posted notification exists, strip its flag and tell listeners + NotificationRecord r = findNotificationByListLocked( + mNotificationList, pkg, null, notificationId, userId); + if (r != null) { + removeForegroundServiceFlagLocked(r); + mRankingHelper.sort(mNotificationList); + mListeners.notifyPostedLocked(r, r); } } }); } @GuardedBy("mNotificationLock") - private void removeForegroundServiceFlagByListLocked( - ArrayList<NotificationRecord> notificationList, String pkg, int notificationId, - int userId) { - NotificationRecord r = findNotificationByListLocked( - notificationList, pkg, null, notificationId, userId); + private void removeForegroundServiceFlagLocked(NotificationRecord r) { if (r == null) { return; } @@ -3989,8 +4013,6 @@ public class NotificationManagerService extends SystemService { // initially *and* force remove FLAG_FOREGROUND_SERVICE. sbn.getNotification().flags = (r.mOriginalFlags & ~FLAG_FOREGROUND_SERVICE); - mRankingHelper.sort(mNotificationList); - mListeners.notifyPostedLocked(r, r); } }; @@ -6074,6 +6096,21 @@ public class NotificationManagerService extends SystemService { } @GuardedBy("mNotificationLock") + private List<NotificationRecord> findNotificationsByListLocked( + ArrayList<NotificationRecord> list, String pkg, String tag, int id, int userId) { + List<NotificationRecord> matching = new ArrayList<>(); + final int len = list.size(); + for (int i = 0; i < len; i++) { + NotificationRecord r = list.get(i); + if (notificationMatchesUserId(r, userId) && r.sbn.getId() == id && + TextUtils.equals(r.sbn.getTag(), tag) && r.sbn.getPackageName().equals(pkg)) { + matching.add(r); + } + } + return matching; + } + + @GuardedBy("mNotificationLock") private NotificationRecord findNotificationByListLocked(ArrayList<NotificationRecord> list, String key) { final int N = list.size(); diff --git a/services/core/java/com/android/server/slice/SliceClientPermissions.java b/services/core/java/com/android/server/slice/SliceClientPermissions.java index e461e0d43735..ab94a59c4d9c 100644 --- a/services/core/java/com/android/server/slice/SliceClientPermissions.java +++ b/services/core/java/com/android/server/slice/SliceClientPermissions.java @@ -282,9 +282,12 @@ public class SliceClientPermissions implements DirtyTracker, Persistable { public synchronized void writeTo(XmlSerializer out) throws IOException { final int N = mPaths.size(); for (int i = 0; i < N; i++) { - out.startTag(NAMESPACE, TAG_PATH); - out.text(encodeSegments(mPaths.valueAt(i))); - out.endTag(NAMESPACE, TAG_PATH); + final String[] segments = mPaths.valueAt(i); + if (segments != null) { + out.startTag(NAMESPACE, TAG_PATH); + out.text(encodeSegments(segments)); + out.endTag(NAMESPACE, TAG_PATH); + } } } diff --git a/services/core/java/com/android/server/slice/SlicePermissionManager.java b/services/core/java/com/android/server/slice/SlicePermissionManager.java index 780bc962afba..315d5e39c94b 100644 --- a/services/core/java/com/android/server/slice/SlicePermissionManager.java +++ b/services/core/java/com/android/server/slice/SlicePermissionManager.java @@ -315,7 +315,8 @@ public class SlicePermissionManager implements DirtyTracker { return new AtomicFile(new File(mSliceDir, fileName)); } - private void handlePersist() { + @VisibleForTesting + void handlePersist() { synchronized (this) { for (Persistable persistable : mDirty) { AtomicFile file = getFile(persistable.getFileName()); @@ -335,7 +336,7 @@ public class SlicePermissionManager implements DirtyTracker { out.flush(); file.finishWrite(stream); - } catch (IOException | XmlPullParserException e) { + } catch (IOException | XmlPullParserException | RuntimeException e) { Slog.w(TAG, "Failed to save access file, restoring backup", e); file.failWrite(stream); } @@ -344,6 +345,12 @@ public class SlicePermissionManager implements DirtyTracker { } } + // use addPersistableDirty(); this is just for tests + @VisibleForTesting + void addDirtyImmediate(Persistable obj) { + mDirty.add(obj); + } + private void handleRemove(PkgUser pkgUser) { getFile(SliceClientPermissions.getFileName(pkgUser)).delete(); getFile(SliceProviderPermissions.getFileName(pkgUser)).delete(); diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java index 547ab0ed443d..0d0004134eb6 100644 --- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java +++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java @@ -541,6 +541,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub */ private void extractColors(WallpaperData wallpaper) { String cropFile = null; + boolean defaultImageWallpaper = false; int wallpaperId; synchronized (mLock) { @@ -549,6 +550,8 @@ public class WallpaperManagerService extends IWallpaperManager.Stub || wallpaper.wallpaperComponent == null; if (imageWallpaper && wallpaper.cropFile != null && wallpaper.cropFile.exists()) { cropFile = wallpaper.cropFile.getAbsolutePath(); + } else if (imageWallpaper && !wallpaper.cropExists() && !wallpaper.sourceExists()) { + defaultImageWallpaper = true; } wallpaperId = wallpaper.wallpaperId; } @@ -560,6 +563,25 @@ public class WallpaperManagerService extends IWallpaperManager.Stub colors = WallpaperColors.fromBitmap(bitmap); bitmap.recycle(); } + } else if (defaultImageWallpaper) { + // There is no crop and source file because this is default image wallpaper. + try (final InputStream is = + WallpaperManager.openDefaultWallpaper(mContext, FLAG_SYSTEM)) { + if (is != null) { + try { + final BitmapFactory.Options options = new BitmapFactory.Options(); + final Bitmap bitmap = BitmapFactory.decodeStream(is, null, options); + if (bitmap != null) { + colors = WallpaperColors.fromBitmap(bitmap); + bitmap.recycle(); + } + } catch (OutOfMemoryError e) { + Slog.w(TAG, "Can't decode default wallpaper stream", e); + } + } + } catch (IOException e) { + Slog.w(TAG, "Can't close default wallpaper stream", e); + } } if (colors == null) { diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 8f5d36abcf2c..11fe76383c76 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -4789,26 +4789,22 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { private boolean resetPasswordInternal(String password, long tokenHandle, byte[] token, int flags, int callingUid, int userHandle) { int quality; - final int realQuality; synchronized (getLockObject()) { quality = getPasswordQuality(null, userHandle, /* parent */ false); if (quality == DevicePolicyManager.PASSWORD_QUALITY_MANAGED) { quality = PASSWORD_QUALITY_UNSPECIFIED; } final PasswordMetrics metrics = PasswordMetrics.computeForPassword(password); - realQuality = metrics.quality; - if (quality != PASSWORD_QUALITY_UNSPECIFIED) { - - if (realQuality < quality - && quality != DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) { - Slog.w(LOG_TAG, "resetPassword: password quality 0x" - + Integer.toHexString(realQuality) - + " does not meet required quality 0x" - + Integer.toHexString(quality)); - return false; - } - quality = Math.max(realQuality, quality); + final int realQuality = metrics.quality; + if (realQuality < quality + && quality != DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) { + Slog.w(LOG_TAG, "resetPassword: password quality 0x" + + Integer.toHexString(realQuality) + + " does not meet required quality 0x" + + Integer.toHexString(quality)); + return false; } + quality = Math.max(realQuality, quality); int length = getPasswordMinimumLength(null, userHandle, /* parent */ false); if (password.length() < length) { Slog.w(LOG_TAG, "resetPassword: password length " + password.length() @@ -4885,7 +4881,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { try { if (token == null) { if (!TextUtils.isEmpty(password)) { - mLockPatternUtils.saveLockPassword(password, null, realQuality, userHandle); + mLockPatternUtils.saveLockPassword(password, null, quality, userHandle); } else { mLockPatternUtils.clearLock(null, userHandle); } @@ -4894,7 +4890,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { result = mLockPatternUtils.setLockCredentialWithToken(password, TextUtils.isEmpty(password) ? LockPatternUtils.CREDENTIAL_TYPE_NONE : LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, - realQuality, tokenHandle, token, userHandle); + quality, tokenHandle, token, userHandle); } boolean requireEntry = (flags & DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY) != 0; if (requireEntry) { diff --git a/services/tests/servicestests/src/com/android/server/locksettings/SP800DeriveTests.java b/services/tests/servicestests/src/com/android/server/locksettings/SP800DeriveTests.java new file mode 100644 index 000000000000..fc2dcb9cc83b --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/locksettings/SP800DeriveTests.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.locksettings; + +import android.test.AndroidTestCase; + +import com.android.internal.util.HexDump; + +public class SP800DeriveTests extends AndroidTestCase { + public void testFixedInput() throws Exception { + // CAVP: https://csrc.nist.gov/projects/cryptographic-algorithm-validation-program/key-derivation + byte[] keyBytes = HexDump.hexStringToByteArray( + "e204d6d466aad507ffaf6d6dab0a5b26" + + "152c9e21e764370464e360c8fbc765c6"); + SP800Derive sk = new SP800Derive(keyBytes); + byte[] fixedInput = HexDump.hexStringToByteArray( + "7b03b98d9f94b899e591f3ef264b71b1" + + "93fba7043c7e953cde23bc5384bc1a62" + + "93580115fae3495fd845dadbd02bd645" + + "5cf48d0f62b33e62364a3a80"); + byte[] res = sk.fixedInput(fixedInput); + assertEquals(( + "770dfab6a6a4a4bee0257ff335213f78" + + "d8287b4fd537d5c1fffa956910e7c779").toUpperCase(), HexDump.toHexString(res)); + } +} diff --git a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java index bdba3d5cd677..2e6992704880 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java @@ -58,6 +58,7 @@ import android.os.UserHandle; import android.os.VibrationEffect; import android.os.Vibrator; import android.provider.Settings; +import android.service.notification.NotificationListenerService; import android.service.notification.StatusBarNotification; import android.support.test.runner.AndroidJUnit4; import android.test.suitebuilder.annotation.SmallTest; @@ -112,7 +113,7 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { private static final Uri CUSTOM_SOUND = Settings.System.DEFAULT_ALARM_ALERT_URI; private static final AudioAttributes CUSTOM_ATTRIBUTES = new AudioAttributes.Builder() .setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN) - .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE) + .setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION) .build(); private static final int CUSTOM_LIGHT_COLOR = Color.BLACK; private static final int CUSTOM_LIGHT_ON = 10000; @@ -230,11 +231,11 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { false /* noisy */, false /* buzzy*/, true /* lights */); } - private NotificationRecord getCustomLightsNotification() { - return getNotificationRecord(mId, false /* insistent */, true /* once */, - false /* noisy */, true /* buzzy*/, true /* lights */, - true /* defaultVibration */, true /* defaultSound */, false /* defaultLights */, - null, Notification.GROUP_ALERT_ALL, false); + private NotificationRecord getCallRecord(int id, boolean insistent) { + return getNotificationRecord(id, false, false /* once */, true /* noisy */, + false /* buzzy */, false /* lights */, false /* default vib */, + false /* default sound */, false /* default lights */, "", + Notification.GROUP_ALERT_ALL, false); } private NotificationRecord getNotificationRecord(int id, boolean insistent, boolean once, @@ -344,11 +345,6 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { eq(false), (AudioAttributes) anyObject()); } - private void verifyCustomBeep() throws RemoteException { - verify(mRingtonePlayer, times(1)).playAsync(eq(CUSTOM_SOUND), (UserHandle) anyObject(), - eq(false), (AudioAttributes) anyObject()); - } - private void verifyNeverStopAudio() throws RemoteException { verify(mRingtonePlayer, never()).stopAsync(); } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index 955e2477fc66..f02c3f062f35 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -3103,4 +3103,46 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { verify(mAppUsageStats, times(1)).reportInterruptiveNotification( anyString(), anyString(), anyInt()); } + + @Test + public void testRemoveForegroundServiceFlagFromNotification_enqueued() { + Notification n = new Notification.Builder(mContext, "").build(); + n.flags |= FLAG_FOREGROUND_SERVICE; + + StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 9, null, mUid, 0, + n, new UserHandle(mUid), null, 0); + NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel); + + mService.addEnqueuedNotification(r); + + mInternalService.removeForegroundServiceFlagFromNotification( + PKG, r.sbn.getId(), r.sbn.getUserId()); + + waitForIdle(); + + verify(mListeners, timeout(200).times(0)).notifyPostedLocked(any(), any()); + } + + @Test + public void testRemoveForegroundServiceFlagFromNotification_posted() { + Notification n = new Notification.Builder(mContext, "").build(); + n.flags |= FLAG_FOREGROUND_SERVICE; + + StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 9, null, mUid, 0, + n, new UserHandle(mUid), null, 0); + NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel); + + mService.addNotification(r); + + mInternalService.removeForegroundServiceFlagFromNotification( + PKG, r.sbn.getId(), r.sbn.getUserId()); + + waitForIdle(); + + ArgumentCaptor<NotificationRecord> captor = + ArgumentCaptor.forClass(NotificationRecord.class); + verify(mListeners, times(1)).notifyPostedLocked(captor.capture(), any()); + + assertEquals(0, captor.getValue().getNotification().flags); + } } diff --git a/services/tests/uiservicestests/src/com/android/server/slice/SlicePermissionManagerTest.java b/services/tests/uiservicestests/src/com/android/server/slice/SlicePermissionManagerTest.java index dc057d564a84..b315e514d6a6 100644 --- a/services/tests/uiservicestests/src/com/android/server/slice/SlicePermissionManagerTest.java +++ b/services/tests/uiservicestests/src/com/android/server/slice/SlicePermissionManagerTest.java @@ -101,4 +101,34 @@ public class SlicePermissionManagerTest extends UiServiceTestCase { assertTrue(FileUtils.deleteContentsAndDir(sliceDir)); } -}
\ No newline at end of file + @Test + public void testInvalid() throws Exception { + File sliceDir = new File(mContext.getCacheDir(), "slices-test"); + if (!sliceDir.exists()) { + sliceDir.mkdir(); + } + SlicePermissionManager permissions = new SlicePermissionManager(mContext, + TestableLooper.get(this).getLooper(), sliceDir); + + DirtyTracker.Persistable junk = new DirtyTracker.Persistable() { + @Override + public String getFileName() { + return "invalidData"; + } + + @Override + public void writeTo(XmlSerializer out) throws IOException { + throw new RuntimeException("this doesn't work"); + } + }; + + // let's put something bad in here + permissions.addDirtyImmediate(junk); + // force a persist. if this throws, it would take down system_server + permissions.handlePersist(); + + // Cleanup. + assertTrue(FileUtils.deleteContentsAndDir(sliceDir)); + } + +} diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java index 9f8042c844de..d9710d9794c8 100644 --- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java +++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java @@ -152,6 +152,7 @@ public class UsbDeviceManager implements ActivityManagerInternal.ScreenObserver private static final int MSG_SET_FUNCTIONS_TIMEOUT = 15; private static final int MSG_GET_CURRENT_USB_FUNCTIONS = 16; private static final int MSG_FUNCTION_SWITCH_TIMEOUT = 17; + private static final int MSG_GADGET_HAL_REGISTERED = 18; private static final int AUDIO_MODE_SOURCE = 1; @@ -1732,10 +1733,16 @@ public class UsbDeviceManager implements ActivityManagerInternal.ScreenObserver protected static final String CTL_STOP = "ctl.stop"; /** - * Adb natvie daemon + * Adb native daemon. */ protected static final String ADBD = "adbd"; + /** + * Gadget HAL fully qualified instance name for registering for ServiceNotification. + */ + protected static final String GADGET_HAL_FQ_NAME = + "android.hardware.usb.gadget@1.0::IUsbGadget"; + protected boolean mCurrentUsbFunctionsRequested; UsbHandlerHal(Looper looper, Context context, UsbDeviceManager deviceManager, @@ -1746,8 +1753,7 @@ public class UsbDeviceManager implements ActivityManagerInternal.ScreenObserver ServiceNotification serviceNotification = new ServiceNotification(); boolean ret = IServiceManager.getService() - .registerForNotifications("android.hardware.usb.gadget@1.0::IUsbGadget", - "", serviceNotification); + .registerForNotifications(GADGET_HAL_FQ_NAME, "", serviceNotification); if (!ret) { Slog.e(TAG, "Failed to register usb gadget service start notification"); return; @@ -1758,8 +1764,8 @@ public class UsbDeviceManager implements ActivityManagerInternal.ScreenObserver mGadgetProxy.linkToDeath(new UsbGadgetDeathRecipient(), USB_GADGET_HAL_DEATH_COOKIE); mCurrentFunctions = UsbManager.FUNCTION_NONE; - mGadgetProxy.getCurrentUsbFunctions(new UsbGadgetCallback()); mCurrentUsbFunctionsRequested = true; + mGadgetProxy.getCurrentUsbFunctions(new UsbGadgetCallback()); } String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim(); updateState(state); @@ -1789,20 +1795,12 @@ public class UsbDeviceManager implements ActivityManagerInternal.ScreenObserver @Override public void onRegistration(String fqName, String name, boolean preexisting) { Slog.i(TAG, "Usb gadget hal service started " + fqName + " " + name); - synchronized (mGadgetProxyLock) { - try { - mGadgetProxy = IUsbGadget.getService(); - mGadgetProxy.linkToDeath(new UsbGadgetDeathRecipient(), - USB_GADGET_HAL_DEATH_COOKIE); - if (!mCurrentFunctionsApplied && !mCurrentUsbFunctionsRequested) { - setEnabledFunctions(mCurrentFunctions, false); - } - } catch (NoSuchElementException e) { - Slog.e(TAG, "Usb gadget hal not found", e); - } catch (RemoteException e) { - Slog.e(TAG, "Usb Gadget hal not responding", e); - } + if (!fqName.equals(GADGET_HAL_FQ_NAME)) { + Slog.e(TAG, "fqName does not match"); + return; } + + sendMessage(MSG_GADGET_HAL_REGISTERED, preexisting); } } @@ -1840,6 +1838,23 @@ public class UsbDeviceManager implements ActivityManagerInternal.ScreenObserver setEnabledFunctions(UsbManager.FUNCTION_NONE, !mAdbEnabled); } break; + case MSG_GADGET_HAL_REGISTERED: + boolean preexisting = msg.arg1 == 1; + synchronized (mGadgetProxyLock) { + try { + mGadgetProxy = IUsbGadget.getService(); + mGadgetProxy.linkToDeath(new UsbGadgetDeathRecipient(), + USB_GADGET_HAL_DEATH_COOKIE); + if (!mCurrentFunctionsApplied && !preexisting) { + setEnabledFunctions(mCurrentFunctions, false); + } + } catch (NoSuchElementException e) { + Slog.e(TAG, "Usb gadget hal not found", e); + } catch (RemoteException e) { + Slog.e(TAG, "Usb Gadget hal not responding", e); + } + } + break; default: super.handleMessage(msg); } diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index c574fb4d6605..e7361ef66531 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -7581,6 +7581,9 @@ public class TelephonyManager { @SystemApi @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setAllowedCarriers(int slotIndex, List<CarrierIdentifier> carriers) { + if (!SubscriptionManager.isValidPhoneId(slotIndex)) { + return -1; + } try { ITelephony service = getITelephony(); if (service != null) { @@ -7608,15 +7611,17 @@ public class TelephonyManager { @SystemApi @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public List<CarrierIdentifier> getAllowedCarriers(int slotIndex) { - try { - ITelephony service = getITelephony(); - if (service != null) { - return service.getAllowedCarriers(slotIndex); + if (SubscriptionManager.isValidPhoneId(slotIndex)) { + try { + ITelephony service = getITelephony(); + if (service != null) { + return service.getAllowedCarriers(slotIndex); + } + } catch (RemoteException e) { + Log.e(TAG, "Error calling ITelephony#getAllowedCarriers", e); + } catch (NullPointerException e) { + Log.e(TAG, "Error calling ITelephony#getAllowedCarriers", e); } - } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelephony#getAllowedCarriers", e); - } catch (NullPointerException e) { - Log.e(TAG, "Error calling ITelephony#getAllowedCarriers", e); } return new ArrayList<CarrierIdentifier>(0); } |