diff options
145 files changed, 1477 insertions, 540 deletions
diff --git a/core/java/android/hardware/radio/TunerCallbackAdapter.java b/core/java/android/hardware/radio/TunerCallbackAdapter.java index 0fb93e532cd3..beff0f7607f8 100644 --- a/core/java/android/hardware/radio/TunerCallbackAdapter.java +++ b/core/java/android/hardware/radio/TunerCallbackAdapter.java @@ -211,10 +211,12 @@ class TunerCallbackAdapter extends ITunerCallback.Stub { @Override public void onProgramListUpdated(ProgramList.Chunk chunk) { - synchronized (mLock) { - if (mProgramList == null) return; - mProgramList.apply(Objects.requireNonNull(chunk)); - } + mHandler.post(() -> { + synchronized (mLock) { + if (mProgramList == null) return; + mProgramList.apply(Objects.requireNonNull(chunk)); + } + }); } @Override diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java index ce1942cc6d91..7a70e93b69d5 100644 --- a/core/java/android/os/GraphicsEnvironment.java +++ b/core/java/android/os/GraphicsEnvironment.java @@ -67,6 +67,8 @@ public class GraphicsEnvironment { private static final String PROPERTY_GFX_DRIVER_PRERELEASE = "ro.gfx.driver.1"; private static final String PROPERTY_GFX_DRIVER_BUILD_TIME = "ro.gfx.driver_build_time"; private static final String METADATA_DRIVER_BUILD_TIME = "com.android.gamedriver.build_time"; + private static final String METADATA_DEVELOPER_DRIVER_ENABLE = + "com.android.graphics.developerdriver.enable"; private static final String ANGLE_RULES_FILE = "a4a_rules.json"; private static final String ANGLE_TEMP_RULES = "debug.angle.rules"; private static final String ACTION_ANGLE_FOR_ANDROID = "android.app.action.ANGLE_FOR_ANDROID"; @@ -691,7 +693,8 @@ public class GraphicsEnvironment { /** * Return the driver package name to use. Return null for system driver. */ - private static String chooseDriverInternal(Context context, Bundle coreSettings) { + private static String chooseDriverInternal( + Context context, Bundle coreSettings, PackageManager pm, String packageName) { final String gameDriver = SystemProperties.get(PROPERTY_GFX_DRIVER); final boolean hasGameDriver = gameDriver != null && !gameDriver.isEmpty(); @@ -706,12 +709,24 @@ public class GraphicsEnvironment { // To minimize risk of driver updates crippling the device beyond user repair, never use an // updated driver for privileged or non-updated system apps. Presumably pre-installed apps // were tested thoroughly with the pre-installed driver. - final ApplicationInfo ai = context.getApplicationInfo(); + ApplicationInfo ai; + try { + // Get the ApplicationInfo from PackageManager so that metadata fields present. + ai = pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA); + } catch (PackageManager.NameNotFoundException e) { + // Unlikely to fail for applications, but in case of failure, fall back to use the + // ApplicationInfo from context directly. + ai = context.getApplicationInfo(); + } if (ai.isPrivilegedApp() || (ai.isSystemApp() && !ai.isUpdatedSystemApp())) { if (DEBUG) Log.v(TAG, "Ignoring driver package for privileged/non-updated system app."); return null; } + final boolean enablePrereleaseDriver = + (ai.metaData != null && ai.metaData.getBoolean(METADATA_DEVELOPER_DRIVER_ENABLE)) + || getCanLoadSystemLibraries() == 1; + // Priority for Game Driver settings global on confliction (Higher priority comes first): // 1. GAME_DRIVER_ALL_APPS // 2. GAME_DRIVER_OPT_OUT_APPS @@ -728,7 +743,7 @@ public class GraphicsEnvironment { return hasGameDriver ? gameDriver : null; case GAME_DRIVER_GLOBAL_OPT_IN_PRERELEASE_DRIVER: if (DEBUG) Log.v(TAG, "All apps opt in to use prerelease driver."); - return hasPrereleaseDriver ? prereleaseDriver : null; + return hasPrereleaseDriver && enablePrereleaseDriver ? prereleaseDriver : null; case GAME_DRIVER_GLOBAL_OPT_IN_DEFAULT: default: break; @@ -745,7 +760,7 @@ public class GraphicsEnvironment { null, coreSettings, Settings.Global.GAME_DRIVER_PRERELEASE_OPT_IN_APPS) .contains(appPackageName)) { if (DEBUG) Log.v(TAG, "App opts in for prerelease Game Driver."); - return hasPrereleaseDriver ? prereleaseDriver : null; + return hasPrereleaseDriver && enablePrereleaseDriver ? prereleaseDriver : null; } // Early return here since the rest logic is only for Game Driver. @@ -783,7 +798,8 @@ public class GraphicsEnvironment { */ private static boolean chooseDriver( Context context, Bundle coreSettings, PackageManager pm, String packageName) { - final String driverPackageName = chooseDriverInternal(context, coreSettings); + final String driverPackageName = chooseDriverInternal(context, coreSettings, pm, + packageName); if (driverPackageName == null) { return false; } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index bf8b0066cb64..f92be195229e 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -8342,16 +8342,6 @@ public final class Settings { BOOLEAN_VALIDATOR; /** - * Whether or not the face unlock education screen has been shown to the user. - * @hide - */ - public static final String FACE_UNLOCK_EDUCATION_INFO_DISPLAYED = - "face_unlock_education_info_displayed"; - - private static final Validator FACE_UNLOCK_EDUCATION_INFO_DISPLAYED_VALIDATOR = - BOOLEAN_VALIDATOR; - - /** * Whether or not debugging is enabled. * @hide */ @@ -9190,8 +9180,6 @@ public final class Settings { VALIDATORS.put(FACE_UNLOCK_APP_ENABLED, FACE_UNLOCK_APP_ENABLED_VALIDATOR); VALIDATORS.put(FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION, FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION_VALIDATOR); - VALIDATORS.put(FACE_UNLOCK_EDUCATION_INFO_DISPLAYED, - FACE_UNLOCK_EDUCATION_INFO_DISPLAYED_VALIDATOR); VALIDATORS.put(ASSIST_GESTURE_ENABLED, ASSIST_GESTURE_ENABLED_VALIDATOR); VALIDATORS.put(ASSIST_GESTURE_SILENCE_ALERTS_ENABLED, ASSIST_GESTURE_SILENCE_ALERTS_ENABLED_VALIDATOR); diff --git a/core/java/android/service/textclassifier/TextClassifierService.java b/core/java/android/service/textclassifier/TextClassifierService.java index 30c4e900f83c..bb39be2b2cf0 100644 --- a/core/java/android/service/textclassifier/TextClassifierService.java +++ b/core/java/android/service/textclassifier/TextClassifierService.java @@ -51,7 +51,6 @@ import android.view.textclassifier.TextSelection; import com.android.internal.util.Preconditions; -import java.lang.ref.WeakReference; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -431,23 +430,18 @@ public abstract class TextClassifierService extends Service { * Forwards the callback result to a wrapped binder callback. */ private static final class ProxyCallback<T extends Parcelable> implements Callback<T> { - private WeakReference<ITextClassifierCallback> mTextClassifierCallback; + private ITextClassifierCallback mTextClassifierCallback; private ProxyCallback(ITextClassifierCallback textClassifierCallback) { - mTextClassifierCallback = - new WeakReference<>(Preconditions.checkNotNull(textClassifierCallback)); + mTextClassifierCallback = Preconditions.checkNotNull(textClassifierCallback); } @Override public void onSuccess(T result) { - ITextClassifierCallback callback = mTextClassifierCallback.get(); - if (callback == null) { - return; - } try { Bundle bundle = new Bundle(1); bundle.putParcelable(KEY_RESULT, result); - callback.onSuccess(bundle); + mTextClassifierCallback.onSuccess(bundle); } catch (RemoteException e) { Slog.d(LOG_TAG, "Error calling callback"); } @@ -455,12 +449,8 @@ public abstract class TextClassifierService extends Service { @Override public void onFailure(CharSequence error) { - ITextClassifierCallback callback = mTextClassifierCallback.get(); - if (callback == null) { - return; - } try { - callback.onFailure(); + mTextClassifierCallback.onFailure(); } catch (RemoteException e) { Slog.d(LOG_TAG, "Error calling callback"); } diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java index cee79439d1b3..1e7440bd5a43 100644 --- a/core/java/android/view/contentcapture/MainContentCaptureSession.java +++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java @@ -480,6 +480,8 @@ public final class MainContentCaptureSession extends ContentCaptureSession { return; } + mNextFlushForTextChanged = false; + final int numberEvents = mEvents.size(); final String reasonString = getFlushReasonAsString(reason); if (sDebug) { @@ -495,10 +497,6 @@ public final class MainContentCaptureSession extends ContentCaptureSession { try { mHandler.removeMessages(MSG_FLUSH); - if (reason == FLUSH_REASON_TEXT_CHANGE_TIMEOUT) { - mNextFlushForTextChanged = false; - } - final ParceledListSlice<ContentCaptureEvent> events = clearEvents(); mDirectServiceInterface.sendEvents(events, reason, mManager.mOptions); } catch (RemoteException e) { diff --git a/core/java/android/webkit/PermissionRequest.java b/core/java/android/webkit/PermissionRequest.java index 18ec334d0283..ac145b1d81a5 100644 --- a/core/java/android/webkit/PermissionRequest.java +++ b/core/java/android/webkit/PermissionRequest.java @@ -32,7 +32,7 @@ import android.net.Uri; * avoid unintentionally granting requests for new permissions, you should pass the * specific permissions you intend to grant to {@link #grant(String[]) grant()}, * and avoid writing code like this example: - * <pre> + * <pre class="prettyprint"> * permissionRequest.grant(permissionRequest.getResources()) // This is wrong!!! * </pre> * See the WebView's release notes for information about new protected resources. diff --git a/core/java/android/webkit/WebChromeClient.java b/core/java/android/webkit/WebChromeClient.java index 95fe963d7891..4db630808ef1 100644 --- a/core/java/android/webkit/WebChromeClient.java +++ b/core/java/android/webkit/WebChromeClient.java @@ -519,15 +519,17 @@ public class WebChromeClient { * may not be supported and applications wishing to support these sources * or more advanced file operations should build their own Intent. * - * <pre> - * How to use: - * 1. Build an intent using {@link #createIntent} - * 2. Fire the intent using {@link android.app.Activity#startActivityForResult}. - * 3. Check for ActivityNotFoundException and take a user friendly action if thrown. - * 4. Listen the result using {@link android.app.Activity#onActivityResult} - * 5. Parse the result using {@link #parseResult} only if media capture was not requested. - * 6. Send the result using filePathCallback of {@link WebChromeClient#onShowFileChooser} - * </pre> + * <p>How to use: + * <ol> + * <li>Build an intent using {@link #createIntent}</li> + * <li>Fire the intent using {@link android.app.Activity#startActivityForResult}.</li> + * <li>Check for ActivityNotFoundException and take a user friendly action if thrown.</li> + * <li>Listen the result using {@link android.app.Activity#onActivityResult}</li> + * <li>Parse the result using {@link #parseResult} only if media capture was not + * requested.</li> + * <li>Send the result using filePathCallback of {@link + * WebChromeClient#onShowFileChooser}</li> + * </ol> * * @return an Intent that supports basic file chooser sources. */ diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index 87963636a003..95fca00f2346 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -762,7 +762,7 @@ public class WebView extends AbsoluteLayout * encoded. If the data is base64 encoded, the value of the encoding * parameter must be {@code "base64"}. HTML can be encoded with {@link * android.util.Base64#encodeToString(byte[],int)} like so: - * <pre> + * <pre class="prettyprint"> * String unencodedHtml = * "<html><body>'%28' is the code for '('</body></html>"; * String encodedHtml = Base64.encodeToString(unencodedHtml.getBytes(), Base64.NO_PADDING); @@ -1854,7 +1854,7 @@ public class WebView extends AbsoluteLayout * important security note below for implications. * <p> Note that injected objects will not appear in JavaScript until the page is next * (re)loaded. JavaScript should be enabled before injecting the object. For example: - * <pre> + * <pre class="prettyprint"> * class JsObject { * {@literal @}JavascriptInterface * public String toString() { return "injectedObject"; } diff --git a/core/java/android/widget/SelectionActionModeHelper.java b/core/java/android/widget/SelectionActionModeHelper.java index 51ca80524090..d0f80936f477 100644 --- a/core/java/android/widget/SelectionActionModeHelper.java +++ b/core/java/android/widget/SelectionActionModeHelper.java @@ -999,6 +999,7 @@ public final class SelectionActionModeHelper { } private void onTimeOut() { + Log.d(LOG_TAG, "Timeout in TextClassificationAsyncTask"); if (getStatus() == Status.RUNNING) { onPostExecute(mTimeOutResultSupplier.get()); } diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index deb815cf42ea..4cf4c9f8e5cc 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -1677,7 +1677,7 @@ <string name="sending" msgid="3245653681008218030">"جارٍ الإرسال..."</string> <string name="launchBrowserDefault" msgid="2057951947297614725">"تشغيل المتصفح؟"</string> <string name="SetupCallDefault" msgid="5834948469253758575">"هل تريد قبول المكالمة؟"</string> - <string name="activity_resolver_use_always" msgid="8017770747801494933">"دومًا"</string> + <string name="activity_resolver_use_always" msgid="8017770747801494933">"دائمًا"</string> <string name="activity_resolver_set_always" msgid="1422574191056490585">"ضبط على الفتح دائمًا"</string> <string name="activity_resolver_use_once" msgid="2404644797149173758">"مرة واحدة فقط"</string> <string name="activity_resolver_app_settings" msgid="8965806928986509855">"الإعدادات"</string> diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index cb6b3707b355..4d882e5b79a3 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -840,7 +840,7 @@ <string name="lockscreen_transport_stop_description" msgid="5907083260651210034">"Спыніць"</string> <string name="lockscreen_transport_rew_description" msgid="6944412838651990410">"Перамотка назад"</string> <string name="lockscreen_transport_ffw_description" msgid="42987149870928985">"Перамотка ўперад"</string> - <string name="emergency_calls_only" msgid="6733978304386365407">"Толькі экстраныя выклікі"</string> + <string name="emergency_calls_only" msgid="6733978304386365407">"Толькі экстранныя выклікі"</string> <string name="lockscreen_network_locked_message" msgid="143389224986028501">"Сетка заблакаваная"</string> <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM-карта заблакавана PUK-кодам."</string> <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Глядзіце \"Інструкцыю для карыстальніка\" або звяжыцеся са службай тэхнiчнай падтрымкі."</string> @@ -1399,7 +1399,7 @@ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Выяўлены аксесуар аналагавага аўдыя"</string> <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Далучаная прылада не сумяшчальная з гэтым тэлефонам. Націсніце, каб даведацца больш."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Адладка па USB падключана"</string> - <string name="adb_active_notification_message" msgid="7463062450474107752">"Націсніце, каб адключыць адладку па USB"</string> + <string name="adb_active_notification_message" msgid="7463062450474107752">"Націсніце, каб выключыць адладку па USB"</string> <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Выберыце, каб адключыць адладку USB."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Тэставы рэжым уключаны"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Каб выключыць тэставы рэжым, скіньце налады да заводскіх значэнняў."</string> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index 7c44bcaedd93..49d0a378a49b 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -1355,7 +1355,7 @@ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Открит е аналогов аудиоаксесоар"</string> <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Свързаното устройство не е съвместимо с този телефон. Докоснете, за да научите повече."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Отстраняване на грешки през USB"</string> - <string name="adb_active_notification_message" msgid="7463062450474107752">"Докоснете, за да изключите отстраняването на грешки през USB"</string> + <string name="adb_active_notification_message" msgid="7463062450474107752">"Докоснете, за да изключите"</string> <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Изберете, за да деактивирате отстраняването на грешки през USB."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Режимът за тестова среда е активиран"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Възстановете фабричните настройки, за да деактивирате режима за тестова среда."</string> diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml index 3d834d5922a6..ae4e1236283e 100644 --- a/core/res/res/values-bn/strings.xml +++ b/core/res/res/values-bn/strings.xml @@ -70,7 +70,7 @@ <string name="ThreeWCMmi" msgid="9051047170321190368">"তিন ভাবে কল করা"</string> <string name="RuacMmi" msgid="7827887459138308886">"অবাঞ্ছিত বিরক্তিকর কলগুলি প্রত্যাখ্যান"</string> <string name="CndMmi" msgid="3116446237081575808">"যে নম্বরটি থেকে কল করা হয় সেটি পাঠানো"</string> - <string name="DndMmi" msgid="1265478932418334331">"বিরক্ত করবেন না"</string> + <string name="DndMmi" msgid="1265478932418334331">"বিরক্ত করবে না"</string> <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"ডিফল্টরূপে কলার আইডি সীমাবদ্ধ করা থাকে৷ পরবর্তী কল: সীমাবদ্ধ"</string> <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"ডিফল্টরূপে কলার আইডি সীমাবদ্ধ করা থাকে৷ পরবর্তী কল: সীমাবদ্ধ নয়"</string> <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"ডিফল্টরূপে কলার আইডি সীমাবদ্ধ করা থাকে না৷ পরবর্তী কল: সীমাবদ্ধ"</string> @@ -648,8 +648,8 @@ <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"ধারককে, একটি ক্যারিয়ার মেসেজিং পরিষেবার উচ্চ স্তরের ইন্টারফেসে জুড়তে অনুমতি দেয়৷ সধারণ অ্যাপ্লিকেশনগুলির জন্য কখনই প্রয়োজন হয় না৷"</string> <string name="permlab_bindCarrierServices" msgid="3233108656245526783">"পরিষেবা প্রদানকারীর সাথে যুক্ত হন"</string> <string name="permdesc_bindCarrierServices" msgid="1391552602551084192">"কোনো পরিষেবা প্রদানকারীর সাথে যুক্ত হতে ধারককে অনুমতি দিন। সাধারণ অ্যাপ্লিকেশানের জন্য প্র্রয়োজন হয় না।"</string> - <string name="permlab_access_notification_policy" msgid="4247510821662059671">"\'বিরক্ত করবেন না\' -তে অ্যাক্সেস"</string> - <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"অ্যাপটিকে \'বিরক্ত করবেন না\' কনফিগারেশন পড়া এবং লেখার অনুমতি দেয়।"</string> + <string name="permlab_access_notification_policy" msgid="4247510821662059671">"\'বিরক্ত করবে না\' -তে অ্যাক্সেস"</string> + <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"অ্যাপটিকে \'বিরক্ত করবে না\' কনফিগারেশন পড়া এবং লেখার অনুমতি দেয়।"</string> <string name="permlab_startViewPermissionUsage" msgid="5484728591597709944">"দেখার অনুমতি কাজে লাগানো শুরু করুন"</string> <string name="permdesc_startViewPermissionUsage" msgid="4808345878203594428">"কোনও অ্যাপের কোনও নির্দিষ্ট অনুমতির ব্যবহার শুরু করার ক্ষেত্রে হোল্ডারকে সাহায্য করে। সাধারণ অ্যাপের জন্য এটির পরিবর্তন হওয়ার কথা নয়।"</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"পাসওয়ার্ড নিয়মগুলি সেট করে"</string> @@ -1313,7 +1313,7 @@ <string name="sms_control_title" msgid="7296612781128917719">"এসএমএস পাঠানো হচ্ছে"</string> <string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> অনেকগুলি এসএমএস পাঠাচ্ছে৷ আপনি কি এই অ্যাপ্লিকেশানটিকে মেসেজ পাঠানো চালিয়ে যাওয়ার অনুমতি দিতে চান?"</string> <string name="sms_control_yes" msgid="3663725993855816807">"অনুমতি দিন"</string> - <string name="sms_control_no" msgid="625438561395534982">"আস্বীকার করুন"</string> + <string name="sms_control_no" msgid="625438561395534982">"অস্বীকার করুন"</string> <string name="sms_short_code_confirm_message" msgid="1645436466285310855">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b> এ একটি মেসেজ পাঠাতে চায়৷"</string> <string name="sms_short_code_details" msgid="5873295990846059400">"এটির জন্য আপনার মোবাইল অ্যাকাউন্টে "<b>"চার্জ বহন করতে হতে পারে"</b>"।"</string> <string name="sms_premium_short_code_details" msgid="7869234868023975"><b>"এর ফলে আপনার মোবাইল অ্যাকাউন্টে চার্জ লাগতে পারে।"</b></string> @@ -1355,7 +1355,7 @@ <string name="usb_power_notification_message" msgid="4647527153291917218">"সংযুক্ত ডিভাইস চার্জ করা হচ্ছে। আরও বিকল্প দেখতে ট্যাপ করুন।"</string> <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"অ্যানালগ অডিও অ্যাক্সেসরি শনাক্ত করা হয়েছে"</string> <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"সংযুক্ত ডিভাইসটি এই ফোনের সাথে ব্যবহার করা যাবে না। আরও জানতে ট্যাপ করুন।"</string> - <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ডিবাগিং সংযুক্ত হয়েছে"</string> + <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ডিবাগিং কানেক্ট হয়েছে"</string> <string name="adb_active_notification_message" msgid="7463062450474107752">"ইউএসবি ডিবাগিং বন্ধ করতে ট্যাপ করুন"</string> <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB ডিবাগিং অক্ষম করতে বেছে নিন।"</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"টেস্ট হারনেস মোড চালু আছে"</string> @@ -1448,7 +1448,7 @@ <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"আপনি কি এই অনুরোধটিকে মঞ্জুরি দিতে চান?"</string> <string name="grant_permissions_header_text" msgid="6874497408201826708">"অ্যাক্সেসের অনুরোধ"</string> <string name="allow" msgid="7225948811296386551">"অনুমতি দিন"</string> - <string name="deny" msgid="2081879885755434506">"আস্বীকার করুন"</string> + <string name="deny" msgid="2081879885755434506">"অস্বীকার করুন"</string> <string name="permission_request_notification_title" msgid="6486759795926237907">"অনুমতির অনুরোধ করা হয়েছে"</string> <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"<xliff:g id="ACCOUNT">%s</xliff:g>অ্যাকাউন্টের জন্য\nঅনুমতির অনুরোধ করা হয়েছে৷"</string> <string name="forward_intent_to_owner" msgid="1207197447013960896">"আপনি এই অ্যাপ্লিকেশানটি আপনার কর্মস্থলের প্রোফাইলের বাইরে ব্যবহার করছেন"</string> @@ -1849,10 +1849,10 @@ <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> পর্যন্ত"</string> <string name="zen_mode_alarm" msgid="9128205721301330797">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> পর্যন্ত (পরবর্তী অ্যালার্ম)"</string> <string name="zen_mode_forever" msgid="931849471004038757">"যতক্ষণ না আপনি বন্ধ করছেন"</string> - <string name="zen_mode_forever_dnd" msgid="3792132696572189081">"যতক্ষণ পর্যন্ত না আপনি বিরক্ত করবেন না বন্ধ করছেন"</string> + <string name="zen_mode_forever_dnd" msgid="3792132696572189081">"যতক্ষণ পর্যন্ত না আপনি বিরক্ত করবে না বন্ধ করছেন"</string> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"সঙ্কুচিত করুন"</string> - <string name="zen_mode_feature_name" msgid="5254089399895895004">"বিরক্ত করবেন না"</string> + <string name="zen_mode_feature_name" msgid="5254089399895895004">"বিরক্ত করবে না"</string> <string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"ডাউনটাইম"</string> <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"সপ্তাহান্তের রাত্রি"</string> <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"সপ্তাহান্ত"</string> @@ -1990,10 +1990,10 @@ <string name="volume_dialog_ringer_guidance_vibrate" msgid="8902050240801159042">"কল এবং বিজ্ঞপ্তি আসলে ভাইব্রেট হবে"</string> <string name="volume_dialog_ringer_guidance_silent" msgid="2128975224280276122">"কল এবং বিজ্ঞপ্তিগুলি মিউট করা হবে"</string> <string name="notification_channel_system_changes" msgid="5072715579030948646">"সিস্টেমে হয়ে থাকা পরিবর্তন"</string> - <string name="notification_channel_do_not_disturb" msgid="6766940333105743037">"বিরক্ত করবেন না"</string> - <string name="zen_upgrade_notification_visd_title" msgid="3288313883409759733">"নতুন: \'বিরক্ত করবেন না\' মোড চালু আছে, তাই বিজ্ঞপ্তি লুকিয়ে ফেলা হচ্ছে"</string> + <string name="notification_channel_do_not_disturb" msgid="6766940333105743037">"বিরক্ত করবে না"</string> + <string name="zen_upgrade_notification_visd_title" msgid="3288313883409759733">"নতুন: \'বিরক্ত করবে না\' মোড চালু আছে, তাই বিজ্ঞপ্তি লুকিয়ে ফেলা হচ্ছে"</string> <string name="zen_upgrade_notification_visd_content" msgid="5533674060311631165">"আরও জানতে এবং পরিবর্তন করতে ট্যাপ করুন।"</string> - <string name="zen_upgrade_notification_title" msgid="3799603322910377294">"\'বিরক্ত করবেন না\' মোডের সেটিং বদলে গেছে"</string> + <string name="zen_upgrade_notification_title" msgid="3799603322910377294">"\'বিরক্ত করবে না\' মোডের সেটিং বদলে গেছে"</string> <string name="zen_upgrade_notification_content" msgid="1794994264692424562">"কী কী ব্লক করা আছে তা দেখতে ট্যাপ করুন।"</string> <string name="notification_app_name_system" msgid="4205032194610042794">"সিস্টেম"</string> <string name="notification_app_name_settings" msgid="7751445616365753381">"সেটিংস"</string> diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml index 572b8eaec5eb..54e146b9f1da 100644 --- a/core/res/res/values-bs/strings.xml +++ b/core/res/res/values-bs/strings.xml @@ -487,9 +487,9 @@ <string name="permlab_changeWifiState" msgid="6550641188749128035">"uspostavljanje i prekidanje WiFi veze"</string> <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Omogućava aplikaciji uspostavljanje i prekidanje veze sa WiFi pristupnim tačkama, kao i promjenu konfiguracije uređaja za WiFi mreže."</string> <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"dozvoljava prijem paketa kroz WiFi Multicast"</string> - <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Omogućava aplikaciji prijem paketa poslanih svim uređajima na WiFi mreži pomoću multicast tehnologije, a ne samo na vaš tablet. Troši više energije nego rad van multicast načina rada."</string> - <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"Omogućava aplikaciji prijem paketa poslanih svim uređajima na WiFi mreži pomoću multicast tehnologije, a ne samo na vaš TV. Troši više energije nego rad van multicast načina rada."</string> - <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Omogućava aplikaciji prijem paketa poslanih svim uređajima na WiFi mreži pomoću multicast tehnologije, a ne samo na vaš telefon. Troši više energije nego rad van multicast načina rada."</string> + <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Omogućava aplikaciji prijem paketa poslanih svim uređajima na WiFi mreži pomoću višesmjernih adresa, a ne samo na vaš tablet. Troši više energije nego rad van multicast načina rada."</string> + <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"Omogućava aplikaciji prijem paketa poslanih svim uređajima na WiFi mreži pomoću višesmjernih adresa, a ne samo na vaš TV. Troši više energije nego rad van multicast načina rada."</string> + <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Omogućava aplikaciji prijem paketa poslanih svim uređajima na WiFi mreži pomoću višesmjernih adresa, a ne samo na vaš telefon. Troši više energije nego rad van multicast načina rada."</string> <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"pristup Bluetooth postavkama"</string> <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Dozvoljava aplikaciji konfiguriranje lokalnog Bluetooth tableta te otkrivanje udaljenih uređaja i sparivanje s njima."</string> <string name="permdesc_bluetoothAdmin" product="tv" msgid="3373125682645601429">"Dozvoljava aplikaciji konfiguriranje lokalnog Bluetooth TV-a te otkrivanje i povezivanje s udaljenim uređajima."</string> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index f4b341c2283d..3a74d2ab2bfc 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -846,9 +846,9 @@ <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%2$d</xliff:g> vegades més, se\'t demanarà que desbloquegis la tauleta amb l\'inici de sessió de Google.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%3$d</xliff:g> segons."</string> <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Has dibuixat el patró de desbloqueig incorrectament <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades. Tens <xliff:g id="NUMBER_1">%2$d</xliff:g> intents més abans no hagis de desbloquejar el televisor amb les dades d\'inici de sessió de Google.\n\n Torna a provar-ho d\'aquí a <xliff:g id="NUMBER_2">%3$d</xliff:g> segons."</string> <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%2$d</xliff:g> vegades més, se\'t demanarà que desbloquegis el telèfon amb l\'inici de sessió de Google.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%3$d</xliff:g> segons."</string> - <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades incorrectament. D\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> intents incorrectes més, la tauleta es restablirà a la configuració predeterminada de fàbrica i es perdran totes les dades dels usuaris."</string> + <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%2$d</xliff:g> vegades més, la tauleta es restablirà a la configuració predeterminada de fàbrica i es perdran totes les dades dels usuaris."</string> <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Has provat de desbloquejar el televisor incorrectament <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades. Tens <xliff:g id="NUMBER_1">%2$d</xliff:g> intents més abans no es restableixin els valors de fàbrica de l\'aparell i es perdin totes les dades d\'usuari."</string> - <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades incorrectament. D\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> intents incorrectes més, la tauleta es restablirà a la configuració predeterminada de fàbrica i es perdran totes les dades dels usuaris."</string> + <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%2$d</xliff:g> vegades més, la tauleta es restablirà a la configuració predeterminada de fàbrica i es perdran totes les dades dels usuaris."</string> <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER">%d</xliff:g> vegades incorrectament. Ara la tauleta es restablirà a la configuració predeterminada de fàbrica."</string> <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Has provat de desbloquejar el televisor incorrectament <xliff:g id="NUMBER">%d</xliff:g> vegades. Ara es restabliran els valors de fàbrica de l\'aparell."</string> <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Has provat de desbloquejar el telèfon <xliff:g id="NUMBER">%d</xliff:g> vegades incorrectament. Ara el telèfon es restablirà a la configuració predeterminada de fàbrica."</string> @@ -1648,9 +1648,9 @@ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Has escrit malament el PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> segons."</string> <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Has escrit malament la contrasenya <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> segons."</string> <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Has dibuixat el patró de desbloqueig de manera incorrecta <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> segons."</string> - <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. D\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> intents incorrectes més, la tauleta es restablirà a la configuració predeterminada de fàbrica i es perdran totes les dades dels usuaris."</string> + <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%2$d</xliff:g> vegades més, la tauleta es restablirà a la configuració predeterminada de fàbrica i es perdran totes les dades dels usuaris."</string> <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Has provat de desbloquejar el televisor incorrectament <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades. Tens <xliff:g id="NUMBER_1">%2$d</xliff:g> intents més abans no es restableixin els valors de fàbrica de l\'aparell i es perdin totes les dades d\'usuari."</string> - <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Has provat de desbloquejar el telèfon <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. D\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> intents incorrectes més, el telèfon es restablirà a la configuració predeterminada de fàbrica i es perdran totes les dades dels usuaris."</string> + <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Has provat de desbloquejar el telèfon <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%2$d</xliff:g> vegades més, el telèfon es restablirà a la configuració predeterminada de fàbrica i es perdran totes les dades dels usuaris."</string> <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER">%d</xliff:g> vegades de manera incorrecta. Ara la tauleta es restablirà a la configuració predeterminada de fàbrica."</string> <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Has provat de desbloquejar el televisor incorrectament <xliff:g id="NUMBER">%d</xliff:g> vegades. Ara es restabliran els valors de fàbrica de l\'aparell."</string> <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Has provat de desbloquejar el telèfon <xliff:g id="NUMBER">%d</xliff:g> vegades de manera incorrecta. Ara el telèfon es restablirà a la configuració predeterminada de fàbrica."</string> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index d0d060723572..63b3e4c6e2db 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -825,7 +825,7 @@ <string name="lockscreen_password_wrong" msgid="5737815393253165301">"Zkusit znovu"</string> <string name="lockscreen_storage_locked" msgid="9167551160010625200">"Funkce a data jsou k dispozici po odemčení"</string> <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Překročili jste maximální povolený počet pokusů o odemknutí obličejem."</string> - <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"Není vložena SIM karta"</string> + <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"Chybí SIM karta"</string> <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"V tabletu není SIM karta."</string> <string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"V televizi není SIM karta."</string> <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"V telefonu není žádná SIM karta."</string> diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index a2a1b37118ec..8897b9f599c4 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -1355,8 +1355,8 @@ <string name="usb_power_notification_message" msgid="4647527153291917218">"Konektatutako gailua kargatzen ari da. Sakatu aukera gehiago ikusteko."</string> <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Audio-osagarri analogiko bat hauteman da"</string> <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Erantsitako gailua ez da telefono honekin bateragarria. Sakatu informazio gehiago lortzeko."</string> - <string name="adb_active_notification_title" msgid="6729044778949189918">"USB arazketa konektatuta"</string> - <string name="adb_active_notification_message" msgid="7463062450474107752">"Sakatu USB arazketa desaktibatzeko"</string> + <string name="adb_active_notification_title" msgid="6729044778949189918">"USB bidezko arazketa konektatuta"</string> + <string name="adb_active_notification_message" msgid="7463062450474107752">"Sakatu USB bidezko arazketa desaktibatzeko"</string> <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Hautatu USB arazketa desgaitzeko."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Proba-materialeko modua gaitu da"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Proba-materialaren modua desgaitzeko, berrezarri jatorrizko datuak."</string> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index 8d12675b833d..cee285971c51 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -1586,7 +1586,7 @@ <string name="launchBrowserDefault" msgid="2057951947297614725">"Lancer le navigateur?"</string> <string name="SetupCallDefault" msgid="5834948469253758575">"Prendre l\'appel?"</string> <string name="activity_resolver_use_always" msgid="8017770747801494933">"Toujours"</string> - <string name="activity_resolver_set_always" msgid="1422574191056490585">"Définir cette activité comme toujours ouverte"</string> + <string name="activity_resolver_set_always" msgid="1422574191056490585">"Toujours ouvrir avec cette application"</string> <string name="activity_resolver_use_once" msgid="2404644797149173758">"Une seule fois"</string> <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Paramètres"</string> <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s ne prend pas en charge le profil professionnel"</string> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index c1cac17bbb74..35553c459b5b 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -1361,8 +1361,8 @@ <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Rétablissez la configuration d\'usine pour désactiver le mode Atelier de test."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Présence de liquide ou de saletés dans le port USB"</string> <string name="usb_contaminant_detected_message" msgid="832337061059487250">"Le port USB est désactivé automatiquement. Appuyez sur cette notification pour en savoir plus."</string> - <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Autoriser l\'utilisation du port USB"</string> - <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Le téléphone ne détecte plus les liquides ni les saletés."</string> + <string name="usb_contaminant_not_detected_title" msgid="7708281124088684821">"Le port USB peut être utilisé"</string> + <string name="usb_contaminant_not_detected_message" msgid="2415791798244545292">"Aucun liquide ni corps étranger à signaler"</string> <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Création du rapport de bug…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Partager le rapport de bug ?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Partage du rapport de bug…"</string> @@ -1586,7 +1586,7 @@ <string name="launchBrowserDefault" msgid="2057951947297614725">"Lancer le navigateur ?"</string> <string name="SetupCallDefault" msgid="5834948469253758575">"Prendre l\'appel ?"</string> <string name="activity_resolver_use_always" msgid="8017770747801494933">"Toujours"</string> - <string name="activity_resolver_set_always" msgid="1422574191056490585">"Définir cette activité comme toujours ouverte"</string> + <string name="activity_resolver_set_always" msgid="1422574191056490585">"Toujours ouvrir avec cette application"</string> <string name="activity_resolver_use_once" msgid="2404644797149173758">"Une seule fois"</string> <string name="activity_resolver_app_settings" msgid="8965806928986509855">"Paramètres"</string> <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s n\'est pas compatible avec le profil professionnel."</string> diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index b2a9e781e2aa..c86c9e604c0e 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -1344,7 +1344,7 @@ <string name="no_permissions" msgid="7283357728219338112">"કોઈ પરવાનગીઓ જરૂરી નથી"</string> <string name="perm_costs_money" msgid="4902470324142151116">"આનાથી તમારા પૈસા ખર્ચ થઈ શકે છે"</string> <string name="dlg_ok" msgid="7376953167039865701">"ઓકે"</string> - <string name="usb_charging_notification_title" msgid="1595122345358177163">"આ ઉપકરણને USB મારફતે ચાર્જ કરી રહ્યાં છીએ"</string> + <string name="usb_charging_notification_title" msgid="1595122345358177163">"આ ડિવાઇસને USB મારફતે ચાર્જ કરી રહ્યાં છીએ"</string> <string name="usb_supplying_notification_title" msgid="4631045789893086181">"કનેક્ટેડ ઉપકરણને USB મારફતે ચાર્જ કરી રહ્યાં છીએ"</string> <string name="usb_mtp_notification_title" msgid="4238227258391151029">"USB ફાઇલ ટ્રાન્સફર ચાલુ છે"</string> <string name="usb_ptp_notification_title" msgid="5425857879922006878">"USB મારફતે PTP ચાલુ કર્યું"</string> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index ff91dcf7a466..6d81d02a2aa9 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -1354,7 +1354,7 @@ <string name="usb_power_notification_message" msgid="4647527153291917218">"Folyamatban van a csatlakoztatott eszköz töltése. Koppintson a további lehetőségekhez."</string> <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Analóg audiotartozék észlelve"</string> <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"A csatlakoztatott eszköz nem kompatibilis ezzel a telefonnal. További információért koppintson ide."</string> - <string name="adb_active_notification_title" msgid="6729044778949189918">"USB hibakereső csatlakoztatva"</string> + <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-hibakereső csatlakoztatva"</string> <string name="adb_active_notification_message" msgid="7463062450474107752">"Koppintson az USB-hibakeresés kikapcsolásához"</string> <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Válassza ezt az USB hibakeresés kikapcsolásához."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Tesztelési alapkörnyezet mód engedélyezve"</string> diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index 7ee4fb609b47..4e07d8811273 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -1355,7 +1355,7 @@ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Հայտնաբերված է անալոգային աուդիո լրասարք"</string> <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Կցված սարքը համատեղելի չէ այս հեռախոսի հետ: Հպեք` ավելին իմանալու համար:"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB վրիպազերծումը միացված է"</string> - <string name="adb_active_notification_message" msgid="7463062450474107752">"Հպեք՝ USB-ի վրիպազերծումն անջատելու համար"</string> + <string name="adb_active_notification_message" msgid="7463062450474107752">"Հպեք՝ USB վրիպազերծումն անջատելու համար"</string> <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Ընտրել` USB կարգաբերումը կասեցնելու համար:"</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Թեստային ռեժիմը միացված է"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Թեստային ռեժիմն անջատելու համար զրոյացրեք կարգավորումները։"</string> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index 7b1d8a5f9845..bc0b67d73f6c 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -299,8 +299,8 @@ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"音声の録音"</string> <string name="permgrouprequest_microphone" msgid="9167492350681916038">"音声の録音を「<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>」に許可しますか?"</string> <string name="permgrouplab_activityRecognition" msgid="1565108047054378642">"身体活動"</string> - <string name="permgroupdesc_activityRecognition" msgid="6949472038320473478">"運動データにアクセス"</string> - <string name="permgrouprequest_activityRecognition" msgid="7626438016904799383">"運動データへのアクセスを「<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>」に許可しますか?"</string> + <string name="permgroupdesc_activityRecognition" msgid="6949472038320473478">"身体活動にアクセス"</string> + <string name="permgrouprequest_activityRecognition" msgid="7626438016904799383">"身体活動へのアクセスを「<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>」に許可しますか?"</string> <string name="permgrouplab_camera" msgid="4820372495894586615">"カメラ"</string> <string name="permgroupdesc_camera" msgid="3250611594678347720">"写真と動画の撮影"</string> <string name="permgrouprequest_camera" msgid="1299833592069671756">"写真と動画の撮影を「<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>」に許可しますか?"</string> @@ -429,8 +429,8 @@ <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> - <string name="permlab_activityRecognition" msgid="3634590230567608356">"運動の認識"</string> - <string name="permdesc_activityRecognition" msgid="3143453925156552894">"このアプリで運動が認識されるようにします。"</string> + <string name="permlab_activityRecognition" msgid="3634590230567608356">"身体活動の認識"</string> + <string name="permdesc_activityRecognition" msgid="3143453925156552894">"このアプリで身体活動が認識されるようにします。"</string> <string name="permlab_camera" msgid="3616391919559751192">"写真と動画の撮影"</string> <string name="permdesc_camera" msgid="5392231870049240670">"このアプリは、いつでもカメラを使用して写真や動画を撮影できます。"</string> <string name="permlab_vibrate" msgid="7696427026057705834">"バイブレーションの制御"</string> @@ -1355,7 +1355,7 @@ <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"アナログのオーディオ アクセサリを検出"</string> <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"接続したデバイスはこのスマートフォンと互換性がありません。タップすると、詳細を確認できます。"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USBデバッグが接続されました"</string> - <string name="adb_active_notification_message" msgid="7463062450474107752">"タップして USB デバッグを無効にしてください"</string> + <string name="adb_active_notification_message" msgid="7463062450474107752">"USB デバッグを無効にするにはここをタップしてください"</string> <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USBデバッグを無効にする場合に選択します。"</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"テストハーネス モード有効"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"出荷時設定にリセットしてテストハーネス モードを無効にしてください。"</string> diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml index 8e5ea6af10d0..46e743bd469f 100644 --- a/core/res/res/values-kn/strings.xml +++ b/core/res/res/values-kn/strings.xml @@ -269,7 +269,7 @@ <string name="notification_channel_usb" msgid="9006850475328924681">"USB ಸಂಪರ್ಕ"</string> <string name="notification_channel_heavy_weight_app" msgid="6218742927792852607">"App ರನ್ ಆಗುತ್ತಿದೆ"</string> <string name="notification_channel_foreground_service" msgid="3931987440602669158">"ಅಪ್ಲಿಕೇಶನ್ಗಳು ಬ್ಯಾಟರಿಯನ್ನು ಉಪಯೋಗಿಸುತ್ತಿವೆ"</string> - <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಬ್ಯಾಟರಿ ಬಳಸುತ್ತಿದೆ"</string> + <string name="foreground_service_app_in_background" msgid="1060198778219731292">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಆ್ಯಪ್, ಬ್ಯಾಟರಿಯನ್ನು ಬಳಸುತ್ತಿದೆ"</string> <string name="foreground_service_apps_in_background" msgid="7175032677643332242">"<xliff:g id="NUMBER">%1$d</xliff:g> ಅಪ್ಲಿಕೇಶನ್ಗಳು ಬ್ಯಾಟರಿ ಬಳಸುತ್ತಿವೆ"</string> <string name="foreground_service_tap_for_details" msgid="372046743534354644">"ಬ್ಯಾಟರಿ,ಡೇಟಾ ಬಳಕೆಯ ವಿವರಗಳಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</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> diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index d3d1cd0f2953..9da12409fd3d 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -1899,7 +1899,7 @@ <string name="language_picker_section_all" msgid="3097279199511617537">"Бардык тилдер"</string> <string name="region_picker_section_all" msgid="8966316787153001779">"Бардык аймактар"</string> <string name="locale_search_menu" msgid="2560710726687249178">"Издөө"</string> - <string name="app_suspended_title" msgid="2075071241147969611">"Колдонмо жеткиликтсиз"</string> + <string name="app_suspended_title" msgid="2075071241147969611">"Колдонмо жеткиликсиз"</string> <string name="app_suspended_default_message" msgid="123166680425711887">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> колдонмосу учурда жеткиликсиз. Анын жеткиликтүүлүгү <xliff:g id="APP_NAME_1">%2$s</xliff:g> тарабынан башкарылат."</string> <string name="app_suspended_more_details" msgid="1131804827776778187">"Кеңири маалымат"</string> <string name="work_mode_off_title" msgid="1118691887588435530">"Жумуш профили күйгүзүлсүнбү?"</string> diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml index 530b0237e822..357764caab7c 100644 --- a/core/res/res/values-mk/strings.xml +++ b/core/res/res/values-mk/strings.xml @@ -71,10 +71,10 @@ <string name="RuacMmi" msgid="7827887459138308886">"Одбивање несакани вознемирувачки повици"</string> <string name="CndMmi" msgid="3116446237081575808">"Испорака на повикувачки број"</string> <string name="DndMmi" msgid="1265478932418334331">"Не вознемирувај"</string> - <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"Стандардно, повикувачот со овој ID е ограничен. Следен повик: ограничен"</string> - <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"Стандардно, повикувачот со овој ID е ограничен. Следен повик: не е ограничен"</string> - <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"Стандардно, повикувачот со овој ID не е ограничен. Следен повик: ограничен"</string> - <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"Стандардно, повикувачот со овој ID не е ограничен. Следен повик: не е ограничен"</string> + <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"Стандардно, ID на повикувач е скриен. Следен повик: скриен"</string> + <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"Стандардно, ID на повикувач е скриен. Следен повик: не е скриен"</string> + <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"Стандардно, ID на повикувач не е скриен. Следен повик: скриен"</string> + <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"Стандардно, ID на повикувач не е скриен. Следен повик: не е скриен"</string> <string name="serviceNotProvisioned" msgid="8614830180508686666">"Услугата не е предвидена."</string> <string name="CLIRPermanent" msgid="3377371145926835671">"Не може да го промените поставувањето за ID на повикувач."</string> <string name="RestrictedOnDataTitle" msgid="5221736429761078014">"Нема услуга за мобилен интернет"</string> diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index faafeb70df32..65ead3ba765c 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -1355,7 +1355,7 @@ <string name="usb_power_notification_message" msgid="4647527153291917218">"चार्जर लावलेले डिव्हाइस. आणखी पर्यायांसाठी टॅप करा"</string> <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"अॅनालॉग ऑडिओ अॅक्सेसरी आढळली"</string> <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"या फोनसह संलग्न केलेले डीव्हाइस सुसंगत नाही. अधिक जाणून घेण्यासाठी टॅप करा."</string> - <string name="adb_active_notification_title" msgid="6729044778949189918">"USB डीबग करणे कनेक्ट केले"</string> + <string name="adb_active_notification_title" msgid="6729044778949189918">"USB डीबगिंग कनेक्ट केले"</string> <string name="adb_active_notification_message" msgid="7463062450474107752">"USB डीबगिंग बंद करण्यासाठी टॅप करा"</string> <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"USB डीबगिंग बंद करण्यासाठी निवडा."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"टेस्ट हार्नेस मोड सुरू केला आहे"</string> diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml index ad5aaca1a2b9..25f8545723b4 100644 --- a/core/res/res/values-my/strings.xml +++ b/core/res/res/values-my/strings.xml @@ -1344,7 +1344,7 @@ <string name="no_permissions" msgid="7283357728219338112">"ခွင့်ပြုချက်မလိုအပ်ပါ"</string> <string name="perm_costs_money" msgid="4902470324142151116">"သင့်အတွက် ပိုက်ဆံကုန်ကျနိုင်ပါသည်"</string> <string name="dlg_ok" msgid="7376953167039865701">"OK"</string> - <string name="usb_charging_notification_title" msgid="1595122345358177163">"ဤစက်ပစ္စည်းကို USB မှတစ်ဆင့် အားသွင်းနေသည်"</string> + <string name="usb_charging_notification_title" msgid="1595122345358177163">"ဤစက်ကို USB ဖြင့် အားသွင်းနေသည်"</string> <string name="usb_supplying_notification_title" msgid="4631045789893086181">"USB မှတစ်ဆင့် ချိတ်ဆက်ထားသည့် စက်ပစ္စည်းကို အားသွင်းနေသည်"</string> <string name="usb_mtp_notification_title" msgid="4238227258391151029">"USB ဖြင့် ဖိုင်လွှဲပြောင်းခြင်းကို ဖွင့်ထားသည်"</string> <string name="usb_ptp_notification_title" msgid="5425857879922006878">"USB မှတစ်ဆင့် PTP ကို အသုံးပြုရန် ဖွင့်ထားသည်"</string> diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml index ce40db3e71a8..949de6e385e8 100644 --- a/core/res/res/values-or/strings.xml +++ b/core/res/res/values-or/strings.xml @@ -1343,7 +1343,7 @@ <string name="no_permissions" msgid="7283357728219338112">"କୌଣସି ଅନୁମତିର ଆବଶ୍ୟକତା ନାହିଁ"</string> <string name="perm_costs_money" msgid="4902470324142151116">"ଶୁଳ୍କ ଲାଗୁ ହୋଇପାରେ"</string> <string name="dlg_ok" msgid="7376953167039865701">"ଠିକ୍ ଅଛି"</string> - <string name="usb_charging_notification_title" msgid="1595122345358177163">"USB ମାଧ୍ୟମରେ ଏହି ଡିଭାଇସ୍କୁ ଚାର୍ଜ କରନ୍ତୁ"</string> + <string name="usb_charging_notification_title" msgid="1595122345358177163">"USB ମାଧ୍ୟମରେ ଏହି ଡିଭାଇସ୍ ଚାର୍ଜ ହେଉଛି"</string> <string name="usb_supplying_notification_title" msgid="4631045789893086181">"USB ମାଧ୍ୟମରେ ଯୋଡ଼ାଯାଇଥିବା ଡିଭାଇସ୍ ଚାର୍ଜ ହେଉଛି"</string> <string name="usb_mtp_notification_title" msgid="4238227258391151029">"USB ଫାଇଲ୍ ଟ୍ରାନ୍ସଫର୍ ଚାଲୁ କରାଗଲା"</string> <string name="usb_ptp_notification_title" msgid="5425857879922006878">"USB ମାଧ୍ୟମରେ PTPକୁ ଚାଲୁ କରାଗଲା"</string> diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml index 591ba0a9fcc3..4fc980b583b6 100644 --- a/core/res/res/values-pa/strings.xml +++ b/core/res/res/values-pa/strings.xml @@ -1344,7 +1344,7 @@ <string name="no_permissions" msgid="7283357728219338112">"ਕੋਈ ਅਨੁਮਤੀਆਂ ਲੁੜੀਂਦੀਆਂ ਨਹੀਂ"</string> <string name="perm_costs_money" msgid="4902470324142151116">"ਇਸ ਨਾਲ ਤੁਹਾਨੂੰ ਖਰਚਾ ਪੈ ਸਕਦਾ ਹੈ"</string> <string name="dlg_ok" msgid="7376953167039865701">"ਠੀਕ"</string> - <string name="usb_charging_notification_title" msgid="1595122345358177163">"USB ਰਾਹੀਂ ਇਸ ਡੀਵਾਈਸ ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੈ"</string> + <string name="usb_charging_notification_title" msgid="1595122345358177163">"ਇਹ ਡੀਵਾਈਸ USB ਰਾਹੀਂ ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੈ"</string> <string name="usb_supplying_notification_title" msgid="4631045789893086181">"ਕਨੈਕਟ ਕੀਤਾ ਡੀਵਾਈਸ USB ਰਾਹੀਂ ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੈ"</string> <string name="usb_mtp_notification_title" msgid="4238227258391151029">"USB ਫ਼ਾਈਲ ਟ੍ਰਾਂਸਫ਼ਰ ਚਾਲੂ ਹੈ"</string> <string name="usb_ptp_notification_title" msgid="5425857879922006878">"USB ਰਾਹੀਂ PTP ਚਾਲੂ ਹੈ"</string> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index cded9f1097af..eb9ab2f76d38 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -1193,7 +1193,7 @@ <string name="android_upgrading_title" product="tablet" msgid="4503169817302593560">"Kompyuta kibao inasasishwa…"</string> <string name="android_upgrading_title" product="device" msgid="7009520271220804517">"Kifaa kinasasishwa…"</string> <string name="android_start_title" product="default" msgid="4536778526365907780">"Simu inawaka…"</string> - <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Inaanzisha Android..."</string> + <string name="android_start_title" product="automotive" msgid="8418054686415318207">"Inawasha Android..."</string> <string name="android_start_title" product="tablet" msgid="4929837533850340472">"Kompyuta kibao inawaka…"</string> <string name="android_start_title" product="device" msgid="7467484093260449437">"Kifaa kiwaka…"</string> <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Inaboresha hifadhi."</string> diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index 776d39e1156e..a9ba0ed1c0f9 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -1665,7 +1665,7 @@ <string name="accessibility_shortcut_toogle_warning" msgid="7256507885737444807">"షార్ట్కట్ ఆన్లో ఉన్నప్పుడు, రెండు వాల్యూమ్ బటన్లను 3 సెకన్ల పాటు నొక్కితే యాక్సెస్ సామర్థ్య ఫీచర్ ప్రారంభం అవుతుంది.\n\n ప్రస్తుత యాక్సెస్ సామర్థ్య ఫీచర్:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n సెట్టింగ్లు > యాక్సెస్ సామర్థ్యంలో మీరు ఫీచర్ను మార్చవచ్చు."</string> <string name="disable_accessibility_shortcut" msgid="627625354248453445">"సత్వరమార్గాన్ని ఆఫ్ చేయి"</string> <string name="leave_accessibility_shortcut_on" msgid="7653111894438512680">"సత్వరమార్గాన్ని ఉపయోగించు"</string> - <string name="color_inversion_feature_name" msgid="4231186527799958644">"వర్ణ విలోమం"</string> + <string name="color_inversion_feature_name" msgid="4231186527799958644">"రంగుల మార్పిడి"</string> <string name="color_correction_feature_name" msgid="6779391426096954933">"రంగు సవరణ"</string> <string name="accessibility_shortcut_enabling_service" msgid="7771852911861522636">"యాక్సెస్ సామర్థ్య షార్ట్కట్ ద్వారా <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ఆన్ చేయబడింది"</string> <string name="accessibility_shortcut_disabling_service" msgid="2747243438223109821">"యాక్సెస్ సామర్థ్య షార్ట్కట్ ద్వారా <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ఆఫ్ చేయబడింది"</string> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index c5bd7cc026c0..f7da3ed3f41c 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -1354,9 +1354,9 @@ <string name="usb_power_notification_message" msgid="4647527153291917218">"Đang sạc thiết bị được kết nối. Hãy nhấn để biết thêm các tùy chọn."</string> <string name="usb_unsupported_audio_accessory_title" msgid="3529881374464628084">"Đã phát hiện phụ kiện âm thanh analog"</string> <string name="usb_unsupported_audio_accessory_message" msgid="6309553946441565215">"Thiết bị được kết nối không tương thích với điện thoại này. Nhấn để tìm hiểu thêm."</string> - <string name="adb_active_notification_title" msgid="6729044778949189918">"Đã kết nối gỡ lỗi USB"</string> - <string name="adb_active_notification_message" msgid="7463062450474107752">"Nhấn để tắt tính năng gỡ lỗi USB"</string> - <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Chọn để vô hiệu hóa gỡ lỗi USB."</string> + <string name="adb_active_notification_title" msgid="6729044778949189918">"Đã kết nối chế độ gỡ lỗi qua USB"</string> + <string name="adb_active_notification_message" msgid="7463062450474107752">"Nhấn để tắt chế độ gỡ lỗi qua USB"</string> + <string name="adb_active_notification_message" product="tv" msgid="8470296818270110396">"Chọn để tắt chế độ gỡ lỗi qua USB."</string> <string name="test_harness_mode_notification_title" msgid="2216359742631914387">"Đã bật Chế độ khai thác kiểm thử"</string> <string name="test_harness_mode_notification_message" msgid="1343197173054407119">"Khôi phục cài đặt gốc để tắt Chế độ khai thác kiểm thử."</string> <string name="usb_contaminant_detected_title" msgid="7136400633704058349">"Có chất lỏng hoặc mảnh vỡ trong cổng USB"</string> @@ -1928,7 +1928,7 @@ <string name="app_category_maps" msgid="5878491404538024367">"Bản đồ và dẫn đường"</string> <string name="app_category_productivity" msgid="3742083261781538852">"Sản xuất"</string> <string name="device_storage_monitor_notification_channel" msgid="3295871267414816228">"Bộ nhớ của thiết bị"</string> - <string name="adb_debugging_notification_channel_tv" msgid="5537766997350092316">"Gỡ lỗi USB"</string> + <string name="adb_debugging_notification_channel_tv" msgid="5537766997350092316">"Gỡ lỗi qua USB"</string> <string name="time_picker_hour_label" msgid="2979075098868106450">"giờ"</string> <string name="time_picker_minute_label" msgid="5168864173796598399">"phút"</string> <string name="time_picker_header_text" msgid="143536825321922567">"Đặt giờ"</string> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index 483d42fb4327..70fcd0cbf4eb 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -625,7 +625,7 @@ <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"修改網路使用量計算方式"</string> <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"允許應用程式修改應用程式網路使用量的計算方式 (不建議一般應用程式使用)。"</string> <string name="permlab_accessNotifications" msgid="7673416487873432268">"存取通知"</string> - <string name="permdesc_accessNotifications" msgid="458457742683431387">"允許應用程式擷取、檢查及清除通知 (包括由其他應用程式發佈的通知)。"</string> + <string name="permdesc_accessNotifications" msgid="458457742683431387">"允許應用程式擷取、檢查及清除通知 (包括由其他應用程式發布的通知)。"</string> <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"繫結至通知接聽器服務"</string> <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"允許應用程式繫結至通知接聽器服務的頂層介面 (一般應用程式不需使用)。"</string> <string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"繫結至條件提供者服務"</string> @@ -1567,13 +1567,13 @@ <string name="data_usage_rapid_app_body" msgid="5396680996784142544">"「<xliff:g id="APP">%s</xliff:g>」的數據用量比平常多"</string> <string name="ssl_certificate" msgid="6510040486049237639">"安全性憑證"</string> <string name="ssl_certificate_is_valid" msgid="6825263250774569373">"憑證有效。"</string> - <string name="issued_to" msgid="454239480274921032">"發佈至:"</string> + <string name="issued_to" msgid="454239480274921032">"發布至:"</string> <string name="common_name" msgid="2233209299434172646">"常用名稱:"</string> <string name="org_name" msgid="6973561190762085236">"機構:"</string> <string name="org_unit" msgid="7265981890422070383">"機構單位:"</string> - <string name="issued_by" msgid="2647584988057481566">"發佈者:"</string> + <string name="issued_by" msgid="2647584988057481566">"發布者:"</string> <string name="validity_period" msgid="8818886137545983110">"有效期間:"</string> - <string name="issued_on" msgid="5895017404361397232">"發佈日期:"</string> + <string name="issued_on" msgid="5895017404361397232">"發布日期:"</string> <string name="expires_on" msgid="3676242949915959821">"到期日:"</string> <string name="serial_number" msgid="758814067660862493">"序號:"</string> <string name="fingerprints" msgid="4516019619850763049">"指紋"</string> diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java index 88bda9d64084..aee178a9a01e 100644 --- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java +++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java @@ -720,8 +720,7 @@ public class SettingsBackupTest { Settings.Secure.LOCATION_ACCESS_CHECK_DELAY_MILLIS, Settings.Secure.BIOMETRIC_DEBUG_ENABLED, Settings.Secure.FACE_UNLOCK_ATTENTION_REQUIRED, - Settings.Secure.FACE_UNLOCK_DIVERSITY_REQUIRED, - Settings.Secure.FACE_UNLOCK_EDUCATION_INFO_DISPLAYED); + Settings.Secure.FACE_UNLOCK_DIVERSITY_REQUIRED); @Test public void systemSettingsBackedUpOrBlacklisted() { diff --git a/packages/SettingsLib/HelpUtils/AndroidManifest.xml b/packages/SettingsLib/HelpUtils/AndroidManifest.xml index 5240ce44c9d9..ccad6e49ff8c 100644 --- a/packages/SettingsLib/HelpUtils/AndroidManifest.xml +++ b/packages/SettingsLib/HelpUtils/AndroidManifest.xml @@ -16,6 +16,6 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.settingslib.helputils"> + package="com.android.settingslib.widget"> </manifest> diff --git a/packages/SettingsLib/HelpUtils/src/com/android/settingslib/HelpUtils.java b/packages/SettingsLib/HelpUtils/src/com/android/settingslib/HelpUtils.java index e407d7239546..2d13b73d3d1f 100644 --- a/packages/SettingsLib/HelpUtils/src/com/android/settingslib/HelpUtils.java +++ b/packages/SettingsLib/HelpUtils/src/com/android/settingslib/HelpUtils.java @@ -33,11 +33,11 @@ import android.view.Menu; import android.view.MenuItem; import android.view.MenuItem.OnMenuItemClickListener; +import com.android.settingslib.widget.R; + import java.net.URISyntaxException; import java.util.Locale; -import com.android.settingslib.helputils.R; - /** * Functions to easily prepare contextual help menu option items with an intent that opens up the * browser to a particular URL, while taking into account the preferred language and app version. diff --git a/packages/SettingsLib/RestrictedLockUtils/AndroidManifest.xml b/packages/SettingsLib/RestrictedLockUtils/AndroidManifest.xml index d19a02238628..09756400b736 100644 --- a/packages/SettingsLib/RestrictedLockUtils/AndroidManifest.xml +++ b/packages/SettingsLib/RestrictedLockUtils/AndroidManifest.xml @@ -16,6 +16,6 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.settingslib.restrictedlockutils"> + package="com.android.settingslib.widget"> </manifest>
\ No newline at end of file diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp index 4c52b1324781..636b90af80a2 100644 --- a/packages/SystemUI/Android.bp +++ b/packages/SystemUI/Android.bp @@ -71,10 +71,6 @@ android_library { "telephony-common", ], - aaptflags: [ - "--extra-packages", - "com.android.keyguard", - ], kotlincflags: ["-Xjvm-default=enable"], plugins: ["dagger2-compiler-2.19"], @@ -132,7 +128,7 @@ android_library { kotlincflags: ["-Xjvm-default=enable"], aaptflags: [ "--extra-packages", - "com.android.keyguard:com.android.systemui", + "com.android.systemui", ], plugins: ["dagger2-compiler-2.19"], } @@ -160,10 +156,6 @@ android_app { kotlincflags: ["-Xjvm-default=enable"], dxflags: ["--multi-dex"], - aaptflags: [ - "--extra-packages", - "com.android.keyguard", - ], required: ["privapp_whitelist_com.android.systemui"], } @@ -180,10 +172,6 @@ android_app { privileged: true, dxflags: ["--multi-dex"], - aaptflags: [ - "--extra-packages", - "com.android.keyguard", - ], optimize: { proguard_flags_files: ["proguard.flags", "legacy/recents/proguard.flags"], }, diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index 6e8e8236a99a..78318cb7e858 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -273,7 +273,6 @@ <!-- SystemUI Services: The classes of the stuff to start. --> <string-array name="config_systemUIServiceComponents" translatable="false"> - <item>com.android.systemui.Dependency$DependencyCreator</item> <item>com.android.systemui.util.NotificationChannels</item> <item>com.android.systemui.statusbar.CommandQueue$CommandQueueStart</item> <item>com.android.systemui.keyguard.KeyguardViewMediator</item> @@ -304,7 +303,6 @@ <!-- SystemUI Services (per user): The classes of the stuff to start for each user. This is a subset of the config_systemUIServiceComponents --> <string-array name="config_systemUIServiceComponentsPerUser" translatable="false"> - <item>com.android.systemui.Dependency$DependencyCreator</item> <item>com.android.systemui.util.NotificationChannels</item> </string-array> diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierText.java b/packages/SystemUI/src/com/android/keyguard/CarrierText.java index adcb7a125e80..b70d8341799a 100644 --- a/packages/SystemUI/src/com/android/keyguard/CarrierText.java +++ b/packages/SystemUI/src/com/android/keyguard/CarrierText.java @@ -24,6 +24,8 @@ import android.util.AttributeSet; import android.view.View; import android.widget.TextView; +import com.android.systemui.R; + import java.util.Locale; public class CarrierText extends TextView { diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java index 10d132ad2763..2b8e3ee0dfc0 100644 --- a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java +++ b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java @@ -44,6 +44,7 @@ import com.android.internal.telephony.TelephonyIntents; import com.android.internal.telephony.TelephonyProperties; import com.android.settingslib.WirelessUtils; import com.android.systemui.Dependency; +import com.android.systemui.R; import com.android.systemui.keyguard.WakefulnessLifecycle; import java.util.ArrayList; diff --git a/packages/SystemUI/src/com/android/keyguard/EmergencyCarrierArea.java b/packages/SystemUI/src/com/android/keyguard/EmergencyCarrierArea.java index e98ef0607951..225bebe57128 100644 --- a/packages/SystemUI/src/com/android/keyguard/EmergencyCarrierArea.java +++ b/packages/SystemUI/src/com/android/keyguard/EmergencyCarrierArea.java @@ -21,6 +21,8 @@ import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; +import com.android.systemui.R; + public class EmergencyCarrierArea extends AlphaOptimizedLinearLayout { private CarrierText mCarrierText; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java index 517abac671b5..d45603fd23ff 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java @@ -33,6 +33,7 @@ import android.widget.LinearLayout; import com.android.internal.util.LatencyTracker; import com.android.internal.widget.LockPatternChecker; import com.android.internal.widget.LockPatternUtils; +import com.android.systemui.R; import java.util.Arrays; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockAccessibilityDelegate.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockAccessibilityDelegate.java index 6a83c719b38f..a78c293a65ac 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockAccessibilityDelegate.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockAccessibilityDelegate.java @@ -23,6 +23,8 @@ import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; import android.widget.TextView; +import com.android.systemui.R; + /** * Replaces fancy colons with regular colons. Only works on TextViews. */ diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java index 5097216a7405..df0dc467f87e 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java @@ -30,6 +30,7 @@ import com.android.internal.colorextraction.ColorExtractor; import com.android.internal.colorextraction.ColorExtractor.OnColorsChangedListener; import com.android.keyguard.clock.ClockManager; import com.android.systemui.Interpolators; +import com.android.systemui.R; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.plugins.ClockPlugin; import com.android.systemui.plugins.statusbar.StatusBarStateController; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java index 0ec60e5dff7d..9380eb4b03f0 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java @@ -35,6 +35,7 @@ import android.view.WindowManager; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.Dependency; +import com.android.systemui.R; import com.android.systemui.statusbar.NavigationBarController; import com.android.systemui.statusbar.phone.NavigationBarView; import com.android.systemui.util.InjectionInflationController; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardEsimArea.java b/packages/SystemUI/src/com/android/keyguard/KeyguardEsimArea.java index c2bbfbf73bb6..fe641427cb31 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardEsimArea.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardEsimArea.java @@ -32,6 +32,8 @@ import android.view.View; import android.view.WindowManager; import android.widget.Button; +import com.android.systemui.R; + /*** * This button is used by the device with embedded SIM card to disable current carrier to unlock * the device with no cellular service. diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java index 14ead0427478..8e1f6d384d1d 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java @@ -35,6 +35,7 @@ import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardSecurityContainer.SecurityCallback; import com.android.keyguard.KeyguardSecurityModel.SecurityMode; import com.android.settingslib.Utils; +import com.android.systemui.R; import com.android.systemui.plugins.ActivityStarter.OnDismissAction; import java.io.File; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardMessageArea.java b/packages/SystemUI/src/com/android/keyguard/KeyguardMessageArea.java index 037a8d3146d2..1ff98ddf2267 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardMessageArea.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardMessageArea.java @@ -31,6 +31,7 @@ import android.util.TypedValue; import android.view.View; import android.widget.TextView; +import com.android.systemui.R; import com.android.systemui.statusbar.policy.ConfigurationController; import java.lang.ref.WeakReference; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java index 6808c0f73998..15d2ea7c3280 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java @@ -24,6 +24,7 @@ import android.view.animation.AnimationUtils; import com.android.settingslib.animation.AppearAnimationUtils; import com.android.settingslib.animation.DisappearAnimationUtils; +import com.android.systemui.R; /** * Displays a PIN pad for unlocking. diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java index 963921561f67..eaaa3ed78654 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java @@ -37,6 +37,7 @@ import android.widget.TextView; import android.widget.TextView.OnEditorActionListener; import com.android.internal.widget.TextViewInputDisabler; +import com.android.systemui.R; import java.util.List; /** diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java index 56b38f7382fa..34c15e64ff54 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java @@ -42,6 +42,7 @@ import com.android.internal.widget.LockPatternView; import com.android.settingslib.animation.AppearAnimationCreator; import com.android.settingslib.animation.AppearAnimationUtils; import com.android.settingslib.animation.DisappearAnimationUtils; +import com.android.systemui.R; import java.util.List; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java index ecafc3408224..274f739d8c29 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java @@ -23,6 +23,8 @@ import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; +import com.android.systemui.R; + /** * A Pin based Keyguard input view */ diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java index 169c97b1ce22..ca7cd0d666ad 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java @@ -45,6 +45,7 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardSecurityModel.SecurityMode; import com.android.systemui.Dependency; +import com.android.systemui.R; import com.android.systemui.SystemUIFactory; import com.android.systemui.statusbar.phone.UnlockMethodCache; import com.android.systemui.util.InjectionInflationController; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipper.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipper.java index e6a02506b4a3..24da3ad46f23 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipper.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipper.java @@ -32,6 +32,7 @@ import android.widget.FrameLayout; import android.widget.ViewFlipper; import com.android.internal.widget.LockPatternUtils; +import com.android.systemui.R; /** * Subclass of the current view flipper that allows us to overload dispatchTouchEvent() so diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java index 69da990a0a73..367a7bd4aed7 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java @@ -41,6 +41,7 @@ import com.android.internal.telephony.ITelephony; import com.android.internal.telephony.IccCardConstants; import com.android.internal.telephony.IccCardConstants.State; import com.android.internal.telephony.PhoneConstants; +import com.android.systemui.R; /** * Displays a PIN pad for unlocking. diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java index 27f71d1ae2be..81f8c67605fe 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java @@ -40,6 +40,7 @@ import com.android.internal.telephony.ITelephony; import com.android.internal.telephony.IccCardConstants; import com.android.internal.telephony.IccCardConstants.State; import com.android.internal.telephony.PhoneConstants; +import com.android.systemui.R; /** diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java index 37e89c095575..1dfc5f25955b 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java @@ -40,6 +40,7 @@ import androidx.core.graphics.ColorUtils; import com.android.internal.widget.LockPatternUtils; import com.android.systemui.Dependency; +import com.android.systemui.R; import com.android.systemui.statusbar.policy.ConfigurationController; import java.io.FileDescriptor; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index 72ad99378eb0..0d456ff29914 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -94,6 +94,7 @@ import com.android.internal.telephony.TelephonyIntents; import com.android.internal.util.Preconditions; import com.android.internal.widget.LockPatternUtils; import com.android.settingslib.WirelessUtils; +import com.android.systemui.R; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.TaskStackChangeListener; import com.android.systemui.statusbar.phone.KeyguardBypassController; @@ -1403,6 +1404,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { } protected void handleStartedGoingToSleep(int arg1) { + mLockIconPressed = false; clearBiometricRecognized(); final int count = mCallbacks.size(); for (int i = 0; i < count; i++) { @@ -1438,7 +1440,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { } private void handleScreenTurnedOff() { - mLockIconPressed = false; mHardwareFingerprintUnavailableRetryCount = 0; mHardwareFaceUnavailableRetryCount = 0; final int count = mCallbacks.size(); diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java index 08691ec10d6a..ebdd8c653dce 100644 --- a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java +++ b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java @@ -29,6 +29,7 @@ import android.view.ViewGroup; import android.widget.TextView; import com.android.internal.widget.LockPatternUtils; +import com.android.systemui.R; public class NumPadKey extends ViewGroup { // list of "ABC", etc per digit, starting with '0' diff --git a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java index b21bcc98ae68..409ae3f3c7d6 100644 --- a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java +++ b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java @@ -42,6 +42,8 @@ import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; import android.widget.EditText; +import com.android.systemui.R; + import java.util.ArrayList; import java.util.Stack; diff --git a/packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java index 9c5242ce1a3e..eba24004e387 100644 --- a/packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java +++ b/packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java @@ -26,7 +26,7 @@ import android.view.View; import android.widget.TextClock; import com.android.internal.colorextraction.ColorExtractor; -import com.android.keyguard.R; +import com.android.systemui.R; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.plugins.ClockPlugin; diff --git a/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java index 8e81327a9325..3a2fbe5a9653 100644 --- a/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java +++ b/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java @@ -26,7 +26,7 @@ import android.view.View; import android.widget.TextClock; import com.android.internal.colorextraction.ColorExtractor; -import com.android.keyguard.R; +import com.android.systemui.R; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.plugins.ClockPlugin; diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java b/packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java index 7485d336174c..d44d89e63e8f 100644 --- a/packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java +++ b/packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java @@ -24,7 +24,7 @@ import android.util.MathUtils; import android.view.View; import android.widget.FrameLayout; -import com.android.keyguard.R; +import com.android.systemui.R; /** * Positions clock faces (analog, digital, typographic) and handles pixel shifting diff --git a/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockController.java index 98679ade1022..c81935a15a15 100644 --- a/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockController.java +++ b/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockController.java @@ -26,7 +26,7 @@ import android.view.View; import android.widget.TextView; import com.android.internal.colorextraction.ColorExtractor; -import com.android.keyguard.R; +import com.android.systemui.R; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.plugins.ClockPlugin; diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ImageClock.java b/packages/SystemUI/src/com/android/keyguard/clock/ImageClock.java index 95f100433137..34c041bbb2dc 100644 --- a/packages/SystemUI/src/com/android/keyguard/clock/ImageClock.java +++ b/packages/SystemUI/src/com/android/keyguard/clock/ImageClock.java @@ -21,7 +21,7 @@ import android.util.AttributeSet; import android.widget.FrameLayout; import android.widget.ImageView; -import com.android.keyguard.R; +import com.android.systemui.R; import java.text.SimpleDateFormat; import java.util.Calendar; diff --git a/packages/SystemUI/src/com/android/keyguard/clock/SmallClockPosition.java b/packages/SystemUI/src/com/android/keyguard/clock/SmallClockPosition.java index 60ca945278f6..b3040744ce7a 100644 --- a/packages/SystemUI/src/com/android/keyguard/clock/SmallClockPosition.java +++ b/packages/SystemUI/src/com/android/keyguard/clock/SmallClockPosition.java @@ -20,6 +20,7 @@ import android.content.res.Resources; import android.util.MathUtils; import com.android.internal.annotations.VisibleForTesting; +import com.android.systemui.R; /** * Computes preferred position of clock by considering height of status bar and lock icon. @@ -40,10 +41,10 @@ class SmallClockPosition { private float mDarkAmount; SmallClockPosition(Resources res) { - this(res.getDimensionPixelSize(com.android.keyguard.R.dimen.status_bar_height), - res.getDimensionPixelSize(com.android.keyguard.R.dimen.keyguard_lock_padding), - res.getDimensionPixelSize(com.android.keyguard.R.dimen.keyguard_lock_height), - res.getDimensionPixelSize(com.android.keyguard.R.dimen.burn_in_prevention_offset_y) + this(res.getDimensionPixelSize(R.dimen.status_bar_height), + res.getDimensionPixelSize(R.dimen.keyguard_lock_padding), + res.getDimensionPixelSize(R.dimen.keyguard_lock_height), + res.getDimensionPixelSize(R.dimen.burn_in_prevention_offset_y) ); } diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java index 6c36bc98996b..15bea2484d7f 100644 --- a/packages/SystemUI/src/com/android/systemui/Dependency.java +++ b/packages/SystemUI/src/com/android/systemui/Dependency.java @@ -16,7 +16,6 @@ package com.android.systemui; import android.annotation.Nullable; import android.app.INotificationManager; -import android.content.Context; import android.content.res.Configuration; import android.hardware.SensorPrivacyManager; import android.hardware.display.NightDisplayListener; @@ -114,7 +113,6 @@ import com.android.systemui.util.leak.LeakReporter; import java.io.FileDescriptor; import java.io.PrintWriter; -import java.util.HashMap; import java.util.function.Consumer; import javax.inject.Inject; @@ -138,9 +136,7 @@ import dagger.Subcomponent; * they have no clients they should not have any registered resources like bound * services, registered receivers, etc. */ -public class Dependency extends SystemUI { - private static final String TAG = "Dependency"; - +public class Dependency { /** * Key for getting a background Looper for background work. */ @@ -305,8 +301,20 @@ public class Dependency extends SystemUI { public Dependency() { } - @Override - public void start() { + + /** + * Initialize Depenency. + */ + public static void initDependencies(SystemUIRootComponent rootComponent) { + if (sDependency != null) { + return; + } + sDependency = new Dependency(); + rootComponent.createDependency().createSystemUI(sDependency); + sDependency.start(); + } + + protected void start() { // TODO: Think about ways to push these creation rules out of Dependency to cut down // on imports. mProviders.put(TIME_TICK_HANDLER, mTimeTickHandler::get); @@ -486,10 +494,14 @@ public class Dependency extends SystemUI { sDependency = this; } - @Override - public synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - super.dump(fd, pw, args); + static void staticDump(FileDescriptor fd, PrintWriter pw, String[] args) { + sDependency.dump(fd, pw, args); + } + /** + * {@see SystemUI.dump} + */ + public synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) { // Make sure that the DumpController gets added to mDependencies, as they are only added // with Dependency#get. getDependency(DumpController.class); @@ -509,9 +521,11 @@ public class Dependency extends SystemUI { .forEach(o -> ((Dumpable) o).dump(fd, pw, args)); } - @Override + protected static void staticOnConfigurationChanged(Configuration newConfig) { + sDependency.onConfigurationChanged(newConfig); + } + protected synchronized void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); mDependencies.values().stream().filter(obj -> obj instanceof ConfigurationChangedReceiver) .forEach(o -> ((ConfigurationChangedReceiver) o).onConfigurationChanged(newConfig)); } @@ -565,20 +579,6 @@ public class Dependency extends SystemUI { } /** - * Used in separate processes (like tuner settings) to init the dependencies. - */ - public static void initDependencies(Context context) { - if (sDependency != null) return; - Dependency d = new Dependency(); - SystemUIFactory.getInstance().getRootComponent() - .createDependency() - .createSystemUI(d); - d.mContext = context; - d.mComponents = new HashMap<>(); - d.start(); - } - - /** * Used in separate process teardown to ensure the context isn't leaked. * * TODO: Remove once PreferenceFragment doesn't reference getActivity() @@ -629,15 +629,4 @@ public class Dependency extends SystemUI { public interface DependencyInjector { void createSystemUI(Dependency dependency); } - - public static class DependencyCreator implements Injector { - @Override - public SystemUI apply(Context context) { - Dependency dependency = new Dependency(); - SystemUIFactory.getInstance().getRootComponent() - .createDependency() - .createSystemUI(dependency); - return dependency; - } - } } diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServicesDialog.java b/packages/SystemUI/src/com/android/systemui/ForegroundServicesDialog.java index cb9523fcaed1..6fec92c84fec 100644 --- a/packages/SystemUI/src/com/android/systemui/ForegroundServicesDialog.java +++ b/packages/SystemUI/src/com/android/systemui/ForegroundServicesDialog.java @@ -75,7 +75,7 @@ public final class ForegroundServicesDialog extends AlertActivity implements @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - Dependency.initDependencies(getApplicationContext()); + Dependency.initDependencies(SystemUIFactory.getInstance().getRootComponent()); mMetricsLogger = Dependency.get(MetricsLogger.class); diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java index f8449add6dce..48127a75b86e 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java @@ -62,19 +62,28 @@ public class SystemUIApplication extends Application implements SysUiServiceProv private final Map<Class<?>, Object> mComponents = new HashMap<>(); private ContextAvailableCallback mContextAvailableCallback; + public SystemUIApplication() { + super(); + Log.v(TAG, "SystemUIApplication constructed."); + } + @Override public void onCreate() { super.onCreate(); + Log.v(TAG, "SystemUIApplication created."); // This line is used to setup Dagger's dependency injection and should be kept at the // top of this method. + TimingsTraceLog log = new TimingsTraceLog("SystemUIBootTiming", + Trace.TRACE_TAG_APP); + log.traceBegin("DependencyInjection"); mContextAvailableCallback.onContextAvailable(this); + log.traceEnd(); // Set the application theme that is inherited by all services. Note that setting the // application theme in the manifest does only work for activities. Keep this in sync with // the theme set there. setTheme(R.style.Theme_SystemUI); - if (Process.myUserHandle().equals(UserHandle.SYSTEM)) { IntentFilter bootCompletedFilter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED); bootCompletedFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); @@ -138,7 +147,7 @@ public class SystemUIApplication extends Application implements SysUiServiceProv /** * Ensures that all the Secondary user SystemUI services are running. If they are already - * running, this is a no-op. This is needed to conditinally start all the services, as we only + * running, this is a no-op. This is needed to conditionally start all the services, as we only * need to have it in the main process. * <p>This method must only be called from the main thread.</p> */ @@ -159,7 +168,9 @@ public class SystemUIApplication extends Application implements SysUiServiceProv // see ActivityManagerService.finishBooting() if ("1".equals(SystemProperties.get("sys.boot_completed"))) { mBootCompleted = true; - if (DEBUG) Log.v(TAG, "BOOT_COMPLETED was already sent"); + if (DEBUG) { + Log.v(TAG, "BOOT_COMPLETED was already sent"); + } } } @@ -273,6 +284,7 @@ public class SystemUIApplication extends Application implements SysUiServiceProv @Override public void onConfigurationChanged(Configuration newConfig) { if (mServicesStarted) { + Dependency.staticOnConfigurationChanged(newConfig); int len = mServices.length; for (int i = 0; i < len; i++) { if (mServices[i] != null) { diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIDefaultModule.java b/packages/SystemUI/src/com/android/systemui/SystemUIDefaultModule.java new file mode 100644 index 000000000000..7f3159131f96 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/SystemUIDefaultModule.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui; + +import static com.android.systemui.Dependency.LEAK_REPORT_EMAIL_NAME; + +import android.content.Context; + +import androidx.annotation.Nullable; + +import com.android.systemui.dock.DockManager; +import com.android.systemui.dock.DockManagerImpl; +import com.android.systemui.power.EnhancedEstimates; +import com.android.systemui.power.EnhancedEstimatesImpl; +import com.android.systemui.statusbar.NotificationLockscreenUserManager; +import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl; +import com.android.systemui.statusbar.notification.collection.NotificationData; +import com.android.systemui.statusbar.phone.KeyguardEnvironmentImpl; +import com.android.systemui.statusbar.phone.ShadeController; +import com.android.systemui.statusbar.phone.StatusBar; + +import javax.inject.Named; +import javax.inject.Singleton; + +import dagger.Binds; +import dagger.Module; +import dagger.Provides; + +/** + * A dagger module for injecting default implementations of components of System UI that may be + * overridden by the System UI implementation. + */ +@Module +abstract class SystemUIDefaultModule { + + @Singleton + @Provides + @Named(LEAK_REPORT_EMAIL_NAME) + @Nullable + static String provideLeakReportEmail() { + return null; + } + + @Binds + abstract EnhancedEstimates bindEnhancedEstimates(EnhancedEstimatesImpl enhancedEstimates); + + @Binds + abstract NotificationLockscreenUserManager bindNotificationLockscreenUserManager( + NotificationLockscreenUserManagerImpl notificationLockscreenUserManager); + + @Binds + abstract DockManager bindDockManager(DockManagerImpl dockManager); + + @Binds + abstract NotificationData.KeyguardEnvironment bindKeyguardEnvironment( + KeyguardEnvironmentImpl keyguardEnvironment); + + @Singleton + @Provides + static ShadeController provideShadeController(Context context) { + return SysUiServiceProvider.getComponent(context, StatusBar.class); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java index 5d8ecc5bfabf..0899d955a1ac 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java @@ -16,13 +16,8 @@ package com.android.systemui; -import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME; -import static com.android.systemui.Dependency.LEAK_REPORT_EMAIL_NAME; - -import android.annotation.Nullable; import android.app.AlarmManager; import android.content.Context; -import android.content.pm.PackageManager; import android.os.Handler; import android.os.Looper; import android.util.Log; @@ -33,59 +28,40 @@ import com.android.internal.util.function.TriConsumer; import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.ViewMediatorCallback; -import com.android.systemui.assist.AssistManager; -import com.android.systemui.dock.DockManager; import com.android.systemui.keyguard.DismissCallbackRegistry; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.statusbar.StatusBarStateController; -import com.android.systemui.power.EnhancedEstimates; -import com.android.systemui.power.EnhancedEstimatesImpl; import com.android.systemui.statusbar.KeyguardIndicationController; -import com.android.systemui.statusbar.NotificationListener; -import com.android.systemui.statusbar.NotificationLockscreenUserManager; -import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl; import com.android.systemui.statusbar.NotificationMediaManager; import com.android.systemui.statusbar.ScrimView; -import com.android.systemui.statusbar.notification.NotificationEntryManager; -import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider; import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator; -import com.android.systemui.statusbar.notification.collection.NotificationData; import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.statusbar.phone.KeyguardBouncer; import com.android.systemui.statusbar.phone.KeyguardBypassController; -import com.android.systemui.statusbar.phone.KeyguardEnvironmentImpl; -import com.android.systemui.statusbar.phone.KeyguardLiftController; import com.android.systemui.statusbar.phone.LockIcon; import com.android.systemui.statusbar.phone.LockscreenWallpaper; import com.android.systemui.statusbar.phone.NotificationIconAreaController; import com.android.systemui.statusbar.phone.ScrimController; import com.android.systemui.statusbar.phone.ScrimState; -import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; import com.android.systemui.statusbar.phone.UnlockMethodCache; -import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.KeyguardMonitor; -import com.android.systemui.util.AsyncSensorManager; import com.android.systemui.volume.VolumeDialogComponent; import java.util.function.Consumer; -import javax.inject.Named; -import javax.inject.Singleton; - import dagger.Module; import dagger.Provides; /** * Class factory to provide customizable SystemUI components. */ -@Module public class SystemUIFactory { private static final String TAG = "SystemUIFactory"; static SystemUIFactory mFactory; - private SystemUIRootComponent mRootComponent; + protected SystemUIRootComponent mRootComponent; public static <T extends SystemUIFactory> T getInstance() { return (T) mFactory; @@ -110,9 +86,16 @@ public class SystemUIFactory { public SystemUIFactory() {} - protected void init(Context context) { - mRootComponent = DaggerSystemUIRootComponent.builder() - .systemUIFactory(this) + private void init(Context context) { + mRootComponent = buildSystemUIRootComponent(context); + + // Every other part of our codebase currently relies on Dependency, so we + // really need to ensure the Dependency gets initialized early on. + Dependency.initDependencies(mRootComponent); + } + + protected SystemUIRootComponent buildSystemUIRootComponent(Context context) { + return DaggerSystemUIRootComponent.builder() .dependencyProvider(new com.android.systemui.DependencyProvider()) .contextHolder(new ContextHolder(context)) .build(); @@ -128,14 +111,15 @@ public class SystemUIFactory { } public KeyguardBouncer createKeyguardBouncer(Context context, ViewMediatorCallback callback, - LockPatternUtils lockPatternUtils, ViewGroup container, + LockPatternUtils lockPatternUtils, ViewGroup container, DismissCallbackRegistry dismissCallbackRegistry, KeyguardBouncer.BouncerExpansionCallback expansionCallback, - FalsingManager falsingManager) { + FalsingManager falsingManager, KeyguardBypassController bypassController) { return new KeyguardBouncer(context, callback, lockPatternUtils, container, dismissCallbackRegistry, falsingManager, expansionCallback, UnlockMethodCache.getInstance(context), - KeyguardUpdateMonitor.getInstance(context), new Handler(Looper.getMainLooper())); + KeyguardUpdateMonitor.getInstance(context), bypassController, + new Handler(Looper.getMainLooper())); } public ScrimController createScrimController(ScrimView scrimBehind, ScrimView scrimInFront, @@ -166,93 +150,8 @@ public class SystemUIFactory { return new VolumeDialogComponent(systemUi, context); } - @Singleton - @Provides - public NotificationData.KeyguardEnvironment provideKeyguardEnvironment(Context context) { - return new KeyguardEnvironmentImpl(); - } - - @Singleton - @Provides - public NotificationLockscreenUserManager provideNotificationLockscreenUserManager( - Context context) { - return new NotificationLockscreenUserManagerImpl(context); - } - - @Singleton - @Provides - public AssistManager provideAssistManager(DeviceProvisionedController controller, - Context context) { - return new AssistManager(controller, context); - } - - @Singleton - @Provides - @Nullable - public DockManager provideDockManager(Context context) { - return null; - } - - @Singleton - @Provides - public NotificationEntryManager provideNotificationEntryManager(Context context) { - return new NotificationEntryManager(context); - } - - @Singleton - @Provides - public EnhancedEstimates provideEnhancedEstimates(Context context) { - return new EnhancedEstimatesImpl(); - } - - @Singleton - @Provides - @Named(LEAK_REPORT_EMAIL_NAME) - @Nullable - public String provideLeakReportEmail() { - return null; - } - - @Singleton - @Provides - @Nullable - public KeyguardLiftController provideKeyguardLiftController(Context context, - StatusBarStateController statusBarStateController, - AsyncSensorManager asyncSensorManager) { - if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE)) { - return null; - } - return new KeyguardLiftController(context, statusBarStateController, asyncSensorManager); - } - - @Singleton - @Provides - public NotificationListener provideNotificationListener(Context context) { - return new NotificationListener(context); - } - - @Singleton - @Provides - public NotificationInterruptionStateProvider provideNotificationInterruptionStateProvider( - Context context) { - return new NotificationInterruptionStateProvider(context); - } - - @Singleton - @Provides - @Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME) - public boolean provideAllowNotificationLongPress() { - return true; - } - - @Singleton - @Provides - public ShadeController provideShadeController(Context context) { - return SysUiServiceProvider.getComponent(context, StatusBar.class); - } - @Module - protected static class ContextHolder { + public static class ContextHolder { private Context mContext; public ContextHolder(Context context) { diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/SystemUIModule.java new file mode 100644 index 000000000000..e1baf9fcf9bc --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/SystemUIModule.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui; + +import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME; + +import android.annotation.Nullable; +import android.content.Context; +import android.content.pm.PackageManager; + +import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.statusbar.phone.KeyguardLiftController; +import com.android.systemui.util.AsyncSensorManager; + +import javax.inject.Named; +import javax.inject.Singleton; + +import dagger.Module; +import dagger.Provides; + +/** + * A dagger module for injecting components of System UI that are not overridden by the System UI + * implementation. + */ +@Module +public abstract class SystemUIModule { + + @Singleton + @Provides + @Nullable + static KeyguardLiftController provideKeyguardLiftController(Context context, + StatusBarStateController statusBarStateController, + AsyncSensorManager asyncSensorManager) { + if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE)) { + return null; + } + return new KeyguardLiftController(context, statusBarStateController, asyncSensorManager); + } + + @Singleton + @Provides + @Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME) + static boolean provideAllowNotificationLongPress() { + return true; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIRootComponent.java b/packages/SystemUI/src/com/android/systemui/SystemUIRootComponent.java index c732df3fdb9f..f18c8b2c3da6 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIRootComponent.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIRootComponent.java @@ -16,11 +16,14 @@ package com.android.systemui; +import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME; + import com.android.systemui.fragments.FragmentService; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.util.InjectionInflationController; import com.android.systemui.util.leak.GarbageMonitor; +import javax.inject.Named; import javax.inject.Singleton; import dagger.Component; @@ -29,8 +32,13 @@ import dagger.Component; * Root component for Dagger injection. */ @Singleton -@Component(modules = {SystemUIFactory.class, DependencyProvider.class, DependencyBinder.class, - ServiceBinder.class, SystemUIFactory.ContextHolder.class}) +@Component(modules = { + DependencyProvider.class, + DependencyBinder.class, + ServiceBinder.class, + SystemUIFactory.ContextHolder.class, + SystemUIModule.class, + SystemUIDefaultModule.class}) public interface SystemUIRootComponent { /** * Main dependency providing module. @@ -62,6 +70,12 @@ public interface SystemUIRootComponent { GarbageMonitor createGarbageMonitor(); /** + * Whether notification long press is allowed. + */ + @Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME) + boolean allowNotificationLongPressName(); + + /** * Injects into the supplied argument. */ void inject(SystemUIAppComponentFactory factory); diff --git a/packages/SystemUI/src/com/android/systemui/SystemUISecondaryUserService.java b/packages/SystemUI/src/com/android/systemui/SystemUISecondaryUserService.java index c8a2e1758ad1..2d2d91db4fe1 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUISecondaryUserService.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUISecondaryUserService.java @@ -38,25 +38,8 @@ public class SystemUISecondaryUserService extends Service { @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - SystemUI[] services = ((SystemUIApplication) getApplication()).getServices(); - if (args == null || args.length == 0) { - for (SystemUI ui: services) { - if (ui != null) { - pw.println("dumping service: " + ui.getClass().getName()); - ui.dump(fd, pw, args); - } - } - } else { - String svc = args[0]; - for (SystemUI ui: services) { - if (ui != null) { - String name = ui.getClass().getName(); - if (name.endsWith(svc)) { - ui.dump(fd, pw, args); - } - } - } - } + SystemUIService.dumpServices( + ((SystemUIApplication) getApplication()).getServices(), fd, pw, args); } } diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIService.java b/packages/SystemUI/src/com/android/systemui/SystemUIService.java index dc1218d33498..1c5e80005d84 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIService.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIService.java @@ -66,8 +66,14 @@ public class SystemUIService extends Service { @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - SystemUI[] services = ((SystemUIApplication) getApplication()).getServices(); + dumpServices(((SystemUIApplication) getApplication()).getServices(), fd, pw, args); + } + + static void dumpServices( + SystemUI[] services, FileDescriptor fd, PrintWriter pw, String[] args) { if (args == null || args.length == 0) { + pw.println("dumping service: " + Dependency.class.getName()); + Dependency.staticDump(fd, pw, args); for (SystemUI ui: services) { pw.println("dumping service: " + ui.getClass().getName()); ui.dump(fd, pw, args); @@ -78,6 +84,9 @@ public class SystemUIService extends Service { } } else { String svc = args[0].toLowerCase(); + if (Dependency.class.getName().endsWith(svc)) { + Dependency.staticDump(fd, pw, args); + } for (SystemUI ui: services) { String name = ui.getClass().getName().toLowerCase(); if (name.endsWith(svc)) { diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java index 6da3818c5d05..25d16455a164 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java +++ b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java @@ -177,6 +177,12 @@ public final class AssistHandleBehaviorController implements AssistHandleCallbac mBehaviorMap.get(mCurrentBehavior).onAssistantGesturePerformed(); } + void onAssistHandlesRequested() { + if (mInGesturalMode) { + mBehaviorMap.get(mCurrentBehavior).onAssistHandlesRequested(); + } + } + void setBehavior(AssistHandleBehavior behavior) { if (mCurrentBehavior == behavior) { return; @@ -316,6 +322,7 @@ public final class AssistHandleBehaviorController implements AssistHandleCallbac void onModeActivated(Context context, AssistHandleCallbacks callbacks); default void onModeDeactivated() {} default void onAssistantGesturePerformed() {} + default void onAssistHandlesRequested() {} default void dump(PrintWriter pw, String prefix) {} } } diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java index f9ddeaef3e86..c5064b7e0422 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java +++ b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java @@ -211,6 +211,13 @@ final class AssistHandleReminderExpBehavior implements BehaviorController { mContext.getContentResolver(), LEARNING_EVENT_COUNT_KEY, ++mLearningCount); } + @Override + public void onAssistHandlesRequested() { + if (mAssistHandleCallbacks != null && !mIsDozing && !mIsNavBarHidden && !mOnLockscreen) { + mAssistHandleCallbacks.showAndGo(); + } + } + private static boolean isNavBarHidden(int sysuiStateFlags) { return (sysuiStateFlags & QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN) != 0; } diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java index 4a4feada3c65..aafffe2fe9d3 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java +++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java @@ -48,9 +48,13 @@ import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.policy.DeviceProvisionedController; +import javax.inject.Inject; +import javax.inject.Singleton; + /** * Class to manage everything related to assist in SystemUI. */ +@Singleton public class AssistManager implements ConfigurationChangedReceiver { /** @@ -97,6 +101,8 @@ public class AssistManager implements ConfigurationChangedReceiver { private static final String INVOCATION_TIME_MS_KEY = "invocation_time_ms"; private static final String INVOCATION_PHONE_STATE_KEY = "invocation_phone_state"; public static final String INVOCATION_TYPE_KEY = "invocation_type"; + protected static final String ACTION_KEY = "action"; + protected static final String SHOW_ASSIST_HANDLES_ACTION = "show_assist_handles"; public static final int INVOCATION_TYPE_GESTURE = 1; public static final int INVOCATION_TYPE_ACTIVE_EDGE = 2; @@ -147,6 +153,7 @@ public class AssistManager implements ConfigurationChangedReceiver { } }; + @Inject public AssistManager(DeviceProvisionedController controller, Context context) { mContext = context; mDeviceProvisionedController = controller; @@ -204,6 +211,9 @@ public class AssistManager implements ConfigurationChangedReceiver { if (VERBOSE) { Log.v(TAG, "UI hints received"); } + if (SHOW_ASSIST_HANDLES_ACTION.equals(hints.getString(ACTION_KEY))) { + requestAssistHandles(); + } } }); } @@ -277,6 +287,10 @@ public class AssistManager implements ConfigurationChangedReceiver { mUiController.onGestureCompletion(velocity); } + protected void requestAssistHandles() { + mHandleController.onAssistHandlesRequested(); + } + public void hideAssist() { mAssistUtils.hideCurrentSession(); } diff --git a/packages/SystemUI/src/com/android/systemui/dock/DockManagerImpl.java b/packages/SystemUI/src/com/android/systemui/dock/DockManagerImpl.java new file mode 100644 index 000000000000..fa7f5032ca16 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/dock/DockManagerImpl.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.dock; + +import javax.inject.Inject; +import javax.inject.Singleton; + +@Singleton +public class DockManagerImpl implements DockManager { + + @Inject + public DockManagerImpl() { + } + + @Override + public void addListener(DockEventListener callback) { + } + + @Override + public void removeListener(DockEventListener callback) { + } + + @Override + public boolean isDocked() { + return false; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/EglHelper.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/EglHelper.java index d74112608491..aac721e3cb56 100644 --- a/packages/SystemUI/src/com/android/systemui/glwallpaper/EglHelper.java +++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/EglHelper.java @@ -146,7 +146,13 @@ public class EglHelper { * @return true if EglSurface is ready. */ public boolean createEglSurface(SurfaceHolder surfaceHolder) { - mEglSurface = eglCreateWindowSurface(mEglDisplay, mEglConfig, surfaceHolder, null, 0); + if (hasEglDisplay()) { + mEglSurface = eglCreateWindowSurface(mEglDisplay, mEglConfig, surfaceHolder, null, 0); + } else { + Log.w(TAG, "mEglDisplay is null"); + return false; + } + if (mEglSurface == null || mEglSurface == EGL_NO_SURFACE) { Log.w(TAG, "createWindowSurface failed: " + GLUtils.getEGLErrorString(eglGetError())); return false; @@ -186,7 +192,13 @@ public class EglHelper { public boolean createEglContext() { int[] attrib_list = new int[] {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_LOW_IMG, EGL_NONE}; - mEglContext = eglCreateContext(mEglDisplay, mEglConfig, EGL_NO_CONTEXT, attrib_list, 0); + if (hasEglDisplay()) { + mEglContext = eglCreateContext(mEglDisplay, mEglConfig, EGL_NO_CONTEXT, attrib_list, 0); + } else { + Log.w(TAG, "mEglDisplay is null"); + return false; + } + if (mEglContext == EGL_NO_CONTEXT) { Log.w(TAG, "eglCreateContext failed: " + GLUtils.getEGLErrorString(eglGetError())); return false; @@ -213,6 +225,14 @@ public class EglHelper { } /** + * Check if we have EglDisplay. + * @return true if EglDisplay is ready. + */ + public boolean hasEglDisplay() { + return mEglDisplay != null; + } + + /** * Swap buffer to display. * @return true if swap successfully. */ @@ -235,7 +255,9 @@ public class EglHelper { if (hasEglContext()) { destroyEglContext(); } - eglTerminate(mEglDisplay); + if (hasEglDisplay()) { + eglTerminate(mEglDisplay); + } mEglReady = false; } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 36c3cc68be85..f424a8e5d71f 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -81,6 +81,7 @@ import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.keyguard.ViewMediatorCallback; import com.android.systemui.Dependency; +import com.android.systemui.R; import com.android.systemui.SystemUI; import com.android.systemui.SystemUIFactory; import com.android.systemui.UiOffloadThread; @@ -713,8 +714,7 @@ public class KeyguardViewMediator extends SystemUI { // Assume keyguard is showing (unless it's disabled) until we know for sure, unless Keyguard // is disabled. - if (mContext.getResources().getBoolean( - com.android.keyguard.R.bool.config_enableKeyguardService)) { + if (mContext.getResources().getBoolean(R.bool.config_enableKeyguardService)) { setShowingLocked(!shouldWaitForProvisioning() && !mLockPatternUtils.isLockScreenDisabled( KeyguardUpdateMonitor.getCurrentUser()), true /* forceCallbacks */); diff --git a/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimatesImpl.java b/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimatesImpl.java index 9b1f23aa0d0c..78f53501d100 100644 --- a/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimatesImpl.java +++ b/packages/SystemUI/src/com/android/systemui/power/EnhancedEstimatesImpl.java @@ -2,8 +2,16 @@ package com.android.systemui.power; import com.android.settingslib.fuelgauge.Estimate; +import javax.inject.Inject; +import javax.inject.Singleton; + +@Singleton public class EnhancedEstimatesImpl implements EnhancedEstimates { + @Inject + public EnhancedEstimatesImpl() { + } + @Override public boolean isHybridNotificationEnabled() { return false; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java index c375574f023d..14009214bdc5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java @@ -37,11 +37,15 @@ import com.android.systemui.statusbar.phone.NotificationListenerWithPlugins; import java.util.ArrayList; +import javax.inject.Inject; +import javax.inject.Singleton; + /** * This class handles listening to notification updates and passing them along to * NotificationPresenter to be displayed to the user. */ @SuppressLint("OverrideAbstract") +@Singleton public class NotificationListener extends NotificationListenerWithPlugins { private static final String TAG = "NotificationListener"; @@ -56,6 +60,7 @@ public class NotificationListener extends NotificationListenerWithPlugins { private final ArrayList<NotificationSettingsListener> mSettingsListeners = new ArrayList<>(); private final Context mContext; + @Inject public NotificationListener(Context context) { mContext = context; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java index e08a5ae07bd8..802a7d29a7a5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java @@ -58,10 +58,14 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; +import javax.inject.Inject; +import javax.inject.Singleton; + /** * Handles keeping track of the current user, profiles, and various things related to hiding * contents, redacting notifications, and the lockscreen. */ +@Singleton public class NotificationLockscreenUserManagerImpl implements Dumpable, NotificationLockscreenUserManager, StateListener { private static final String TAG = "LockscreenUserManager"; @@ -171,6 +175,7 @@ public class NotificationLockscreenUserManagerImpl implements return mEntryManager; } + @Inject public NotificationLockscreenUserManagerImpl(Context context) { mContext = context; mDevicePolicyManager = (DevicePolicyManager) mContext.getSystemService( diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/DynamicPrivacyController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/DynamicPrivacyController.java index d9328fa3affd..e4bd4fa1ae75 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/DynamicPrivacyController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/DynamicPrivacyController.java @@ -107,7 +107,7 @@ public class DynamicPrivacyController implements UnlockMethodCache.OnUnlockMetho */ public boolean isInLockedDownShade() { if (!mStatusBarKeyguardViewManager.isShowing() - || !mStatusBarKeyguardViewManager.isSecure()) { + || !mUnlockMethodCache.isMethodSecure()) { return false; } int state = mStateController.getState(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java index 879a8dfa2875..f8fef7d4778c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java @@ -54,11 +54,15 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import javax.inject.Inject; +import javax.inject.Singleton; + /** * NotificationEntryManager is responsible for the adding, removing, and updating of notifications. * It also handles tasks such as their inflation and their interaction with other * Notification.*Manager objects. */ +@Singleton public class NotificationEntryManager implements Dumpable, NotificationContentInflater.InflationCallback, @@ -118,6 +122,7 @@ public class NotificationEntryManager implements } } + @Inject public NotificationEntryManager(Context context) { mNotificationData = new NotificationData(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java index 4fc646119261..68d95463bd3a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java @@ -42,9 +42,13 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.policy.HeadsUpManager; +import javax.inject.Inject; +import javax.inject.Singleton; + /** * Provides heads-up and pulsing state for notification entries. */ +@Singleton public class NotificationInterruptionStateProvider { private static final String TAG = "InterruptionStateProvider"; @@ -72,6 +76,7 @@ public class NotificationInterruptionStateProvider { protected boolean mUseHeadsUp = false; private boolean mDisableNotificationAlerts; + @Inject public NotificationInterruptionStateProvider(Context context) { this(context, (PowerManager) context.getSystemService(Context.POWER_SERVICE), diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java index c4d346ccaefb..0854e84a6888 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java @@ -40,9 +40,9 @@ import com.android.keyguard.KeyguardHostView; import com.android.keyguard.KeyguardSecurityView; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; -import com.android.keyguard.R; import com.android.keyguard.ViewMediatorCallback; import com.android.systemui.DejankUtils; +import com.android.systemui.R; import com.android.systemui.keyguard.DismissCallbackRegistry; import com.android.systemui.plugins.FalsingManager; @@ -77,6 +77,7 @@ public class KeyguardBouncer { } }; private final Runnable mRemoveViewRunnable = this::removeView; + private final KeyguardBypassController mKeyguardBypassController; protected KeyguardHostView mKeyguardView; private final Runnable mResetRunnable = ()-> { if (mKeyguardView != null) { @@ -97,7 +98,8 @@ public class KeyguardBouncer { LockPatternUtils lockPatternUtils, ViewGroup container, DismissCallbackRegistry dismissCallbackRegistry, FalsingManager falsingManager, BouncerExpansionCallback expansionCallback, UnlockMethodCache unlockMethodCache, - KeyguardUpdateMonitor keyguardUpdateMonitor, Handler handler) { + KeyguardUpdateMonitor keyguardUpdateMonitor, + KeyguardBypassController keyguardBypassController, Handler handler) { mContext = context; mCallback = callback; mLockPatternUtils = lockPatternUtils; @@ -109,6 +111,7 @@ public class KeyguardBouncer { mHandler = handler; mUnlockMethodCache = unlockMethodCache; mKeyguardUpdateMonitor.registerCallback(mUpdateMonitorCallback); + mKeyguardBypassController = keyguardBypassController; } public void show(boolean resetSecuritySelection) { @@ -171,7 +174,8 @@ public class KeyguardBouncer { // Split up the work over multiple frames. DejankUtils.removeCallbacks(mResetRunnable); if (mUnlockMethodCache.isFaceAuthEnabled() && !needsFullscreenBouncer() - && !mKeyguardUpdateMonitor.userNeedsStrongAuth()) { + && !mKeyguardUpdateMonitor.userNeedsStrongAuth() + && !mKeyguardBypassController.getBypassEnabled()) { mHandler.postDelayed(mShowRunnable, BOUNCER_FACE_DELAY); } else { DejankUtils.postAfterTraversal(mShowRunnable); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardEnvironmentImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardEnvironmentImpl.java index 925a19d6f5eb..2c931ae1c8ef 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardEnvironmentImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardEnvironmentImpl.java @@ -25,6 +25,10 @@ import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.notification.collection.NotificationData.KeyguardEnvironment; import com.android.systemui.statusbar.policy.DeviceProvisionedController; +import javax.inject.Inject; +import javax.inject.Singleton; + +@Singleton public class KeyguardEnvironmentImpl implements KeyguardEnvironment { private static final String TAG = "KeyguardEnvironmentImpl"; @@ -34,6 +38,7 @@ public class KeyguardEnvironmentImpl implements KeyguardEnvironment { private final DeviceProvisionedController mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class); + @Inject public KeyguardEnvironmentImpl() { } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index 97f069274f78..5d5cbe984859 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -25,6 +25,7 @@ import static android.app.StatusBarManager.WindowVisibleState; import static android.app.StatusBarManager.windowStateToString; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY; +import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME; import static com.android.systemui.Dependency.BG_HANDLER; import static com.android.systemui.Dependency.MAIN_HANDLER; import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP; @@ -238,6 +239,7 @@ import java.util.ArrayList; import java.util.Map; import javax.inject.Inject; +import javax.inject.Named; import dagger.Subcomponent; @@ -382,6 +384,9 @@ public class StatusBar extends SystemUI implements DemoMode, @Nullable @Inject protected KeyguardLiftController mKeyguardLiftController; + @Inject + @Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME) + boolean mAllowNotificationLongPress; // expanded notifications protected NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window @@ -1064,7 +1069,7 @@ public class StatusBar extends SystemUI implements DemoMode, final NotificationRowBinderImpl rowBinder = new NotificationRowBinderImpl( mContext, - SystemUIFactory.getInstance().provideAllowNotificationLongPress(), + mAllowNotificationLongPress, mKeyguardBypassController, mStatusBarStateController); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index d47adbe180c8..0c47d1468a7f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -221,7 +221,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb mBiometricUnlockController = biometricUnlockController; mBouncer = SystemUIFactory.getInstance().createKeyguardBouncer(mContext, mViewMediatorCallback, mLockPatternUtils, container, dismissCallbackRegistry, - mExpansionCallback, falsingManager); + mExpansionCallback, falsingManager, bypassController); mNotificationPanelView = notificationPanelView; notificationPanelView.addExpansionListener(this); mBypassController = bypassController; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java index 0ef981bdb3de..946fe0b3a2f8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java @@ -39,9 +39,9 @@ import android.view.WindowManager; import android.view.WindowManager.LayoutParams; import com.android.internal.annotations.VisibleForTesting; -import com.android.keyguard.R; import com.android.systemui.Dependency; import com.android.systemui.Dumpable; +import com.android.systemui.R; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.plugins.statusbar.StatusBarStateController; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java index e75365e66f81..7acf4fd27ced 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java @@ -537,8 +537,14 @@ public class MobileSignalController extends SignalController< return mConfig.nr5GIconMap.get(Config.NR_CONNECTED); } } else if (nrState == NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED) { - if (mConfig.nr5GIconMap.containsKey(Config.NR_NOT_RESTRICTED)) { - return mConfig.nr5GIconMap.get(Config.NR_NOT_RESTRICTED); + if (mCurrentState.activityDormant) { + if (mConfig.nr5GIconMap.containsKey(Config.NR_NOT_RESTRICTED_RRC_IDLE)) { + return mConfig.nr5GIconMap.get(Config.NR_NOT_RESTRICTED_RRC_IDLE); + } + } else { + if (mConfig.nr5GIconMap.containsKey(Config.NR_NOT_RESTRICTED_RRC_CON)) { + return mConfig.nr5GIconMap.get(Config.NR_NOT_RESTRICTED_RRC_CON); + } } } else if (nrState == NetworkRegistrationInfo.NR_STATE_RESTRICTED) { if (mConfig.nr5GIconMap.containsKey(Config.NR_RESTRICTED)) { @@ -559,6 +565,8 @@ public class MobileSignalController extends SignalController< || activity == TelephonyManager.DATA_ACTIVITY_IN; mCurrentState.activityOut = activity == TelephonyManager.DATA_ACTIVITY_INOUT || activity == TelephonyManager.DATA_ACTIVITY_OUT; + mCurrentState.activityDormant = activity == TelephonyManager.DATA_ACTIVITY_DORMANT; + notifyListenersIfNecessary(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java index 1c24bb9e88d1..621b16ab9f41 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java @@ -1108,8 +1108,9 @@ public class NetworkControllerImpl extends BroadcastReceiver static class Config { static final int NR_CONNECTED_MMWAVE = 1; static final int NR_CONNECTED = 2; - static final int NR_NOT_RESTRICTED = 3; - static final int NR_RESTRICTED = 4; + static final int NR_NOT_RESTRICTED_RRC_IDLE = 3; + static final int NR_NOT_RESTRICTED_RRC_CON = 4; + static final int NR_RESTRICTED = 5; Map<Integer, MobileIconGroup> nr5GIconMap = new HashMap<>(); @@ -1129,10 +1130,11 @@ public class NetworkControllerImpl extends BroadcastReceiver */ private static final Map<String, Integer> NR_STATUS_STRING_TO_INDEX; static { - NR_STATUS_STRING_TO_INDEX = new HashMap<>(4); + NR_STATUS_STRING_TO_INDEX = new HashMap<>(5); NR_STATUS_STRING_TO_INDEX.put("connected_mmwave", NR_CONNECTED_MMWAVE); NR_STATUS_STRING_TO_INDEX.put("connected", NR_CONNECTED); - NR_STATUS_STRING_TO_INDEX.put("not_restricted", NR_NOT_RESTRICTED); + NR_STATUS_STRING_TO_INDEX.put("not_restricted_rrc_idle", NR_NOT_RESTRICTED_RRC_IDLE); + NR_STATUS_STRING_TO_INDEX.put("not_restricted_rrc_con", NR_NOT_RESTRICTED_RRC_CON); NR_STATUS_STRING_TO_INDEX.put("restricted", NR_RESTRICTED); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalController.java index 9ec30d43ac75..abe3f2c18891 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalController.java @@ -258,6 +258,7 @@ public abstract class SignalController<T extends SignalController.State, boolean enabled; boolean activityIn; boolean activityOut; + public boolean activityDormant; int level; IconGroup iconGroup; int inetCondition; @@ -274,6 +275,7 @@ public abstract class SignalController<T extends SignalController.State, inetCondition = state.inetCondition; activityIn = state.activityIn; activityOut = state.activityOut; + activityDormant = state.activityDormant; rssi = state.rssi; time = state.time; } @@ -297,6 +299,7 @@ public abstract class SignalController<T extends SignalController.State, .append("iconGroup=").append(iconGroup).append(',') .append("activityIn=").append(activityIn).append(',') .append("activityOut=").append(activityOut).append(',') + .append("activityDormant=").append(activityDormant).append(',') .append("rssi=").append(rssi).append(',') .append("lastModified=").append(DateFormat.format("MM-dd HH:mm:ss", time)); } @@ -314,6 +317,7 @@ public abstract class SignalController<T extends SignalController.State, && other.iconGroup == iconGroup && other.activityIn == activityIn && other.activityOut == activityOut + && other.activityDormant == activityDormant && other.rssi == rssi; } } diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java index 1d4f9b33b0bc..97507900e269 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java @@ -31,6 +31,7 @@ import androidx.preference.PreferenceScreen; import com.android.systemui.Dependency; import com.android.systemui.R; +import com.android.systemui.SystemUIFactory; import com.android.systemui.fragments.FragmentService; public class TunerActivity extends Activity implements @@ -50,7 +51,7 @@ public class TunerActivity extends Activity implements setActionBar(toolbar); } - Dependency.initDependencies(this); + Dependency.initDependencies(SystemUIFactory.getInstance().getRootComponent()); if (getFragmentManager().findFragmentByTag(TAG_TUNER) == null) { final String action = getIntent().getAction(); diff --git a/packages/SystemUI/tests/Android.mk b/packages/SystemUI/tests/Android.mk index 5412cde0df55..81e2c22d5c4f 100644 --- a/packages/SystemUI/tests/Android.mk +++ b/packages/SystemUI/tests/Android.mk @@ -39,7 +39,7 @@ LOCAL_JAVA_LIBRARIES := \ telephony-common \ android.test.base \ -LOCAL_AAPT_FLAGS := --extra-packages com.android.systemui:com.android.keyguard +LOCAL_AAPT_FLAGS := --extra-packages com.android.systemui # sign this with platform cert, so this test is allowed to inject key events into # UI it doesn't own. This is necessary to allow screenshots to be taken diff --git a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java index 0044ca7c0409..1421b06be621 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java @@ -46,6 +46,7 @@ import android.testing.TestableLooper; import com.android.internal.telephony.IccCardConstants; import com.android.systemui.Dependency; +import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.keyguard.WakefulnessLifecycle; diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockAccessibilityDelegateTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockAccessibilityDelegateTest.java index dcafa7203ce9..00f88bfa2abb 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockAccessibilityDelegateTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockAccessibilityDelegateTest.java @@ -27,6 +27,7 @@ import android.widget.TextView; import androidx.test.filters.SmallTest; +import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import org.junit.Before; diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java index f01c0b421ef7..de7664c769e6 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java @@ -39,6 +39,7 @@ import android.widget.FrameLayout; import android.widget.TextClock; import com.android.keyguard.clock.ClockManager; +import com.android.systemui.R; import com.android.systemui.SystemUIFactory; import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.ClockPlugin; diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewTest.kt index 5f03bdba40b4..42a89509975d 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewTest.kt @@ -21,6 +21,7 @@ import android.testing.AndroidTestingRunner import android.testing.TestableLooper import android.view.LayoutInflater +import com.android.systemui.R import com.android.systemui.SysuiTestCase import com.android.systemui.statusbar.policy.ConfigurationController import com.google.common.truth.Truth.assertThat diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewTest.java index eadb1b63df90..202fbd71a0c4 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewTest.java @@ -28,6 +28,7 @@ import android.view.LayoutInflater; import androidx.test.filters.SmallTest; +import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import org.junit.Before; diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java index 8db195a23a15..d47fceea9724 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java @@ -23,6 +23,7 @@ import android.view.LayoutInflater; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; +import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import org.junit.Test; diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java index b3accbc3b4bb..116f8fc7d3eb 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java @@ -27,6 +27,7 @@ import androidx.slice.SliceProvider; import androidx.slice.SliceSpecs; import androidx.slice.builders.ListBuilder; +import com.android.systemui.R; import com.android.systemui.SystemUIFactory; import com.android.systemui.SysuiTestCase; import com.android.systemui.keyguard.KeyguardSliceProvider; diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java index 31ea39cedf3b..87f2ef5a9636 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java @@ -24,6 +24,7 @@ import android.testing.TestableLooper; import android.testing.TestableLooper.RunWithLooper; import android.view.LayoutInflater; +import com.android.systemui.R; import com.android.systemui.SystemUIFactory; import com.android.systemui.SysuiTestCase; import com.android.systemui.util.Assert; diff --git a/packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java b/packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java index b1ca169eac0c..b9d09ce91c1a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java @@ -74,6 +74,6 @@ public class DependencyTest extends SysuiTestCase { @Test public void testInitDependency() { Dependency.clearDependencies(); - Dependency.initDependencies(mContext); + Dependency.initDependencies(SystemUIFactory.getInstance().getRootComponent()); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/IconPackOverlayTest.java b/packages/SystemUI/tests/src/com/android/systemui/IconPackOverlayTest.java index ccc9afcd4296..0fa7443da394 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/IconPackOverlayTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/IconPackOverlayTest.java @@ -32,6 +32,7 @@ import androidx.test.filters.MediumTest; import androidx.test.runner.AndroidJUnit4; import com.android.internal.util.XmlUtils; +import com.android.systemui.tests.R; import org.junit.After; import org.junit.Before; diff --git a/packages/SystemUI/tests/src/com/android/systemui/TestableDependency.java b/packages/SystemUI/tests/src/com/android/systemui/TestableDependency.java index 18bf75e3cfb1..0c53b03de4d2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/TestableDependency.java +++ b/packages/SystemUI/tests/src/com/android/systemui/TestableDependency.java @@ -25,10 +25,6 @@ public class TestableDependency extends Dependency { private final ArraySet<Object> mInstantiatedObjects = new ArraySet<>(); public TestableDependency(Context context) { - if (context instanceof SysuiTestableContext) { - mComponents = ((SysuiTestableContext) context).getComponents(); - } - mContext = context; SystemUIFactory.createFromConfig(context); SystemUIFactory.getInstance().getRootComponent() .createDependency() diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubblesTestActivity.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubblesTestActivity.java index 43d2ad1dfe0a..8bc2e2bc77b6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubblesTestActivity.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubblesTestActivity.java @@ -20,7 +20,7 @@ import android.app.Activity; import android.content.Intent; import android.os.Bundle; -import com.android.systemui.R; +import com.android.systemui.tests.R; /** * Referenced by NotificationTestHelper#makeBubbleMetadata diff --git a/packages/SystemUI/tests/src/com/android/systemui/glwallpaper/EglHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/glwallpaper/EglHelperTest.java new file mode 100644 index 000000000000..b4a60d642cb0 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/glwallpaper/EglHelperTest.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.glwallpaper; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.RETURNS_DEFAULTS; +import static org.mockito.Mockito.mock; + +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; +import android.view.SurfaceHolder; + +import androidx.test.filters.SmallTest; + +import com.android.systemui.SysuiTestCase; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; + + +@SmallTest +@RunWith(AndroidTestingRunner.class) +@TestableLooper.RunWithLooper +public class EglHelperTest extends SysuiTestCase { + + @Mock + private EglHelper mEglHelper; + @Mock + private SurfaceHolder mSurfaceHolder; + + @Before + public void setUp() throws Exception { + mEglHelper = mock(EglHelper.class, RETURNS_DEFAULTS); + mSurfaceHolder = mock(SurfaceHolder.class, RETURNS_DEFAULTS); + } + + @Test + public void testInit_finish() { + mEglHelper.init(mSurfaceHolder); + mEglHelper.finish(); + } + + @Test + public void testFinish_shouldNotCrash() { + assertFalse(mEglHelper.hasEglDisplay()); + assertFalse(mEglHelper.hasEglSurface()); + assertFalse(mEglHelper.hasEglContext()); + + mEglHelper.finish(); + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotStubActivity.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotStubActivity.java index 784d0352c679..0b871e433f5b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotStubActivity.java +++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotStubActivity.java @@ -15,11 +15,11 @@ */ package com.android.systemui.screenshot; -import com.android.systemui.R; - import android.app.Activity; import android.os.Bundle; +import com.android.systemui.tests.R; + /** * A stub activity used in {@link ScreenshotTest}. */ diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java index 7063ddf3e653..ab207f83a709 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java @@ -40,7 +40,6 @@ import android.widget.RemoteViews; import androidx.test.InstrumentationRegistry; -import com.android.systemui.R; import com.android.systemui.bubbles.BubblesTestActivity; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.notification.collection.NotificationEntry; @@ -50,7 +49,7 @@ import com.android.systemui.statusbar.notification.row.NotificationContentInflat import com.android.systemui.statusbar.phone.HeadsUpManagerPhone; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.NotificationGroupManager; -import com.android.systemui.statusbar.policy.HeadsUpManager; +import com.android.systemui.tests.R; /** * A helper class to create {@link ExpandableNotificationRow} (for both individual and group diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/MediaNotificationProcessorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/MediaNotificationProcessorTest.java index 7eeae67c9fdf..e6287e7063d3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/MediaNotificationProcessorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/MediaNotificationProcessorTest.java @@ -38,8 +38,8 @@ import android.widget.RemoteViews; import androidx.palette.graphics.Palette; import androidx.test.runner.AndroidJUnit4; -import com.android.systemui.R; import com.android.systemui.SysuiTestCase; +import com.android.systemui.tests.R; import org.junit.After; import org.junit.Before; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java index 2ec125e8a43b..ccadcc35f37a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java @@ -23,7 +23,6 @@ import static com.android.systemui.statusbar.notification.row.NotificationConten import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; @@ -44,12 +43,12 @@ import android.widget.RemoteViews; import androidx.test.filters.SmallTest; -import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.statusbar.InflationTask; import com.android.systemui.statusbar.NotificationTestHelper; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.row.NotificationContentInflater.InflationCallback; +import com.android.systemui.tests.R; import org.junit.Assert; import org.junit.Before; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCustomViewWrapperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCustomViewWrapperTest.java index 63e18ce722c3..49a64101eb84 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCustomViewWrapperTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCustomViewWrapperTest.java @@ -24,10 +24,10 @@ import android.widget.RemoteViews; import androidx.test.filters.SmallTest; -import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.statusbar.NotificationTestHelper; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; +import com.android.systemui.tests.R; import org.junit.Assert; import org.junit.Before; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java index 907e695f2513..cd60e47eef50 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java @@ -21,6 +21,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyFloat; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.never; @@ -84,6 +85,8 @@ public class KeyguardBouncerTest extends SysuiTestCase { @Mock private UnlockMethodCache mUnlockMethodCache; @Mock + private KeyguardBypassController mKeyguardBypassController; + @Mock private Handler mHandler; private KeyguardBouncer mBouncer; @@ -98,7 +101,8 @@ public class KeyguardBouncerTest extends SysuiTestCase { when(mKeyguardHostView.getHeight()).thenReturn(500); mBouncer = new KeyguardBouncer(getContext(), mViewMediatorCallback, mLockPatternUtils, container, mDismissCallbackRegistry, mFalsingManager, - mExpansionCallback, mUnlockMethodCache, mKeyguardUpdateMonitor, mHandler) { + mExpansionCallback, mUnlockMethodCache, mKeyguardUpdateMonitor, + mKeyguardBypassController, mHandler) { @Override protected void inflateView() { super.inflateView(); @@ -391,6 +395,15 @@ public class KeyguardBouncerTest extends SysuiTestCase { } @Test + public void testShow_delaysIfFaceAuthIsRunning_unlessBypass() { + when(mUnlockMethodCache.isFaceAuthEnabled()).thenReturn(true); + when(mKeyguardBypassController.getBypassEnabled()).thenReturn(true); + mBouncer.show(true /* reset */); + + verify(mHandler, never()).postDelayed(any(), anyLong()); + } + + @Test public void testRegisterUpdateMonitorCallback() { verify(mKeyguardUpdateMonitor).registerCallback(any()); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java index a97832f94924..4b6ca56fc8e3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java @@ -68,7 +68,7 @@ public class StatusBarRemoteInputCallbackTest extends SysuiTestCase { mDependency.injectTestDependency(ShadeController.class, mShadeController); mDependency.injectTestDependency(NotificationLockscreenUserManager.class, mNotificationLockscreenUserManager); - mDependency.putComponent(CommandQueue.class, mock(CommandQueue.class)); + mContext.putComponent(CommandQueue.class, mock(CommandQueue.class)); mRemoteInputCallback = spy(new StatusBarRemoteInputCallback(mContext, mock(NotificationGroupManager.class))); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java index 9ae9ceb2629f..e691b7dec0d9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java @@ -228,6 +228,18 @@ public class NetworkControllerBaseTest extends SysuiTestCase { NetworkControllerImpl.Config.add5GIconMapping("connected:5g", mConfig); } + public void setupNr5GIconConfigurationForNotRestrictedRrcCon() { + NetworkControllerImpl.Config.add5GIconMapping("connected_mmwave:5g_plus", mConfig); + NetworkControllerImpl.Config.add5GIconMapping("connected:5g_plus", mConfig); + NetworkControllerImpl.Config.add5GIconMapping("not_restricted_rrc_con:5g", mConfig); + } + + public void setupNr5GIconConfigurationForNotRestrictedRrcIdle() { + NetworkControllerImpl.Config.add5GIconMapping("connected_mmwave:5g_plus", mConfig); + NetworkControllerImpl.Config.add5GIconMapping("connected:5g_plus", mConfig); + NetworkControllerImpl.Config.add5GIconMapping("not_restricted_rrc_idle:5g", mConfig); + } + public void setConnectivityViaBroadcast( int networkType, boolean validated, boolean isConnected) { setConnectivityCommon(networkType, validated, isConnected); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java index 5128675e2723..f0394da6f479 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java @@ -175,6 +175,35 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { } @Test + public void testNr5GIcon_NrNotRestrictedRrcCon_show5GIcon() { + setupNr5GIconConfigurationForNotRestrictedRrcCon(); + setupDefaultSignal(); + updateDataConnectionState(TelephonyManager.DATA_CONNECTED, + TelephonyManager.NETWORK_TYPE_LTE); + updateDataActivity(TelephonyManager.DATA_ACTIVITY_INOUT); + ServiceState ss = Mockito.mock(ServiceState.class); + doReturn(NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED).when(ss).getNrState(); + mPhoneStateListener.onServiceStateChanged(ss); + + verifyLastMobileDataIndicators(true, DEFAULT_SIGNAL_STRENGTH, TelephonyIcons.ICON_5G, + true, DEFAULT_QS_SIGNAL_STRENGTH, TelephonyIcons.ICON_5G, true, true); + } + + @Test + public void testNr5GIcon_NrNotRestrictedRrcIdle_show5GIcon() { + setupNr5GIconConfigurationForNotRestrictedRrcIdle(); + setupDefaultSignal(); + updateDataConnectionState(TelephonyManager.DATA_CONNECTED, + TelephonyManager.NETWORK_TYPE_LTE); + updateDataActivity(TelephonyManager.DATA_ACTIVITY_DORMANT); + ServiceState ss = Mockito.mock(ServiceState.class); + doReturn(NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED).when(ss).getNrState(); + mPhoneStateListener.onServiceStateChanged(ss); + + verifyDataIndicators(TelephonyIcons.ICON_5G); + } + + @Test public void testNr5GIcon_NrConnectedWithoutMMWave_show5GIcon() { setupDefaultNr5GIconConfiguration(); setupDefaultSignal(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java index 6e3d9067f63c..34511831247e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java @@ -1,5 +1,12 @@ package com.android.systemui.statusbar.policy; +import static junit.framework.Assert.assertEquals; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + import android.content.Intent; import android.net.NetworkCapabilities; import android.net.NetworkInfo; @@ -16,13 +23,6 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; -import static junit.framework.Assert.assertEquals; - -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyBoolean; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - @SmallTest @RunWith(AndroidTestingRunner.class) @RunWithLooper diff --git a/services/core/java/com/android/server/BluetoothService.java b/services/core/java/com/android/server/BluetoothService.java index 5c5b477352b1..6a6ddc84be49 100644 --- a/services/core/java/com/android/server/BluetoothService.java +++ b/services/core/java/com/android/server/BluetoothService.java @@ -54,8 +54,11 @@ class BluetoothService extends SystemService { @Override public void onSwitchUser(int userHandle) { - initialize(); - mBluetoothManagerService.handleOnSwitchUser(userHandle); + if (!mInitialized) { + initialize(); + } else { + mBluetoothManagerService.handleOnSwitchUser(userHandle); + } } @Override diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index e66e596d5038..f7e825eecc12 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -1027,7 +1027,12 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { log(str); } mLocalLog.log(str); - if (validatePhoneId(phoneId)) { + // for service state updates, don't notify clients when subId is invalid. This prevents + // us from sending incorrect notifications like b/133140128 + // In the future, we can remove this logic for every notification here and add a + // callback so listeners know when their PhoneStateListener's subId becomes invalid, but + // for now we use the simplest fix. + if (validatePhoneId(phoneId) && SubscriptionManager.isValidSubscriptionId(subId)) { mServiceState[phoneId] = state; for (Record r : mRecords) { @@ -1059,7 +1064,8 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } } else { - log("notifyServiceStateForSubscriber: INVALID phoneId=" + phoneId); + log("notifyServiceStateForSubscriber: INVALID phoneId=" + phoneId + + " or subId=" + subId); } handleRemoveListLocked(); } diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java index 30a356325ada..6b038979a98d 100644 --- a/services/core/java/com/android/server/UiModeManagerService.java +++ b/services/core/java/com/android/server/UiModeManagerService.java @@ -48,7 +48,6 @@ import android.os.ShellCallback; import android.os.ShellCommand; import android.os.SystemProperties; import android.os.UserHandle; -import android.os.UserManager; import android.provider.Settings.Secure; import android.service.dreams.Sandman; import android.service.vr.IVrManager; @@ -218,6 +217,15 @@ final class UiModeManagerService extends SystemService { } }; + private final ContentObserver mDarkThemeObserver = new ContentObserver(mHandler) { + @Override + public void onChange(boolean selfChange, Uri uri) { + final int mode = Secure.getIntForUser(getContext().getContentResolver(), + Secure.UI_NIGHT_MODE, mNightMode, 0); + SystemProperties.set(SYSTEM_PROPERTY_DEVICE_THEME, Integer.toString(mode)); + } + }; + @Override public void onSwitchUser(int userHandle) { super.onSwitchUser(userHandle); @@ -293,6 +301,9 @@ final class UiModeManagerService extends SystemService { IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_USER_SWITCHED); context.registerReceiver(new UserSwitchedReceiver(), filter, null, mHandler); + + context.getContentResolver().registerContentObserver(Secure.getUriFor(Secure.UI_NIGHT_MODE), + false, mDarkThemeObserver, 0); } // Records whether setup wizard has happened or not and adds an observer for this user if not. @@ -417,11 +428,6 @@ final class UiModeManagerService extends SystemService { if (!mCarModeEnabled) { Secure.putIntForUser(getContext().getContentResolver(), Secure.UI_NIGHT_MODE, mode, user); - - if (UserManager.get(getContext()).isPrimaryUser()) { - SystemProperties.set(SYSTEM_PROPERTY_DEVICE_THEME, - Integer.toString(mode)); - } } mNightMode = mode; diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java index 07482796b027..9936d73fb800 100644 --- a/services/core/java/com/android/server/VibratorService.java +++ b/services/core/java/com/android/server/VibratorService.java @@ -1188,6 +1188,7 @@ public class VibratorService extends IVibratorService.Stub private static boolean isNotification(int usageHint) { switch (usageHint) { case AudioAttributes.USAGE_NOTIFICATION: + case AudioAttributes.USAGE_NOTIFICATION_EVENT: case AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_REQUEST: case AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_INSTANT: case AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_DELAYED: diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index c2f452932775..81824dc2cca1 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -756,7 +756,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub } public void noteStartAudio(int uid) { - enforceSelfOrCallingPermission(uid); + enforceCallingPermission(); synchronized (mStats) { mStats.noteAudioOnLocked(uid); StatsLog.write_non_chained(StatsLog.AUDIO_STATE_CHANGED, uid, null, @@ -765,7 +765,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub } public void noteStopAudio(int uid) { - enforceSelfOrCallingPermission(uid); + enforceCallingPermission(); synchronized (mStats) { mStats.noteAudioOffLocked(uid); StatsLog.write_non_chained(StatsLog.AUDIO_STATE_CHANGED, uid, null, @@ -774,7 +774,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub } public void noteStartVideo(int uid) { - enforceSelfOrCallingPermission(uid); + enforceCallingPermission(); synchronized (mStats) { mStats.noteVideoOnLocked(uid); StatsLog.write_non_chained(StatsLog.MEDIA_CODEC_STATE_CHANGED, uid, null, @@ -783,7 +783,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub } public void noteStopVideo(int uid) { - enforceSelfOrCallingPermission(uid); + enforceCallingPermission(); synchronized (mStats) { mStats.noteVideoOffLocked(uid); StatsLog.write_non_chained(StatsLog.MEDIA_CODEC_STATE_CHANGED, uid, @@ -1184,13 +1184,6 @@ public final class BatteryStatsService extends IBatteryStats.Stub Binder.getCallingPid(), Binder.getCallingUid(), null); } - private void enforceSelfOrCallingPermission(int uid) { - if (Binder.getCallingUid() == uid) { - return; - } - enforceCallingPermission(); - } - final class WakeupReasonThread extends Thread { private static final int MAX_REASON_SIZE = 512; private CharsetDecoder mDecoder; diff --git a/services/core/java/com/android/server/biometrics/face/FaceService.java b/services/core/java/com/android/server/biometrics/face/FaceService.java index a7065216f6a3..ee49f5885e4a 100644 --- a/services/core/java/com/android/server/biometrics/face/FaceService.java +++ b/services/core/java/com/android/server/biometrics/face/FaceService.java @@ -223,7 +223,8 @@ public class FaceService extends BiometricServiceBase { @Override public boolean wasUserDetected() { - return mLastAcquire != FaceManager.FACE_ACQUIRED_NOT_DETECTED; + return mLastAcquire != FaceManager.FACE_ACQUIRED_NOT_DETECTED + && mLastAcquire != FaceManager.FACE_ACQUIRED_SENSOR_DIRTY; } @Override diff --git a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java index acb0207ff11f..85ca627e3b02 100644 --- a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java +++ b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java @@ -35,6 +35,8 @@ import android.hardware.broadcastradio.V2_0.Result; import android.hardware.broadcastradio.V2_0.VendorKeyValue; import android.hardware.radio.RadioManager; import android.os.DeadObjectException; +import android.os.Handler; +import android.os.Looper; import android.os.RemoteException; import android.util.MutableInt; import android.util.Slog; @@ -44,6 +46,7 @@ import com.android.internal.annotations.GuardedBy; import java.util.ArrayList; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; @@ -55,6 +58,7 @@ class RadioModule { @NonNull public final RadioManager.ModuleProperties mProperties; private final Object mLock = new Object(); + @NonNull private final Handler mHandler; @GuardedBy("mLock") private ITunerSession mHalTunerSession; @@ -70,38 +74,46 @@ class RadioModule { private final ITunerCallback mHalTunerCallback = new ITunerCallback.Stub() { @Override public void onTuneFailed(int result, ProgramSelector programSelector) { - fanoutAidlCallback(cb -> cb.onTuneFailed(result, Convert.programSelectorFromHal( - programSelector))); + lockAndFireLater(() -> { + android.hardware.radio.ProgramSelector csel = + Convert.programSelectorFromHal(programSelector); + fanoutAidlCallbackLocked(cb -> cb.onTuneFailed(result, csel)); + }); } @Override public void onCurrentProgramInfoChanged(ProgramInfo halProgramInfo) { - RadioManager.ProgramInfo programInfo = Convert.programInfoFromHal(halProgramInfo); - synchronized (mLock) { - mProgramInfo = programInfo; - fanoutAidlCallbackLocked(cb -> cb.onCurrentProgramInfoChanged(programInfo)); - } + lockAndFireLater(() -> { + mProgramInfo = Convert.programInfoFromHal(halProgramInfo); + fanoutAidlCallbackLocked(cb -> cb.onCurrentProgramInfoChanged(mProgramInfo)); + }); } @Override public void onProgramListUpdated(ProgramListChunk programListChunk) { // TODO: Cache per-AIDL client filters, send union of filters to HAL, use filters to fan // back out to clients. - fanoutAidlCallback(cb -> cb.onProgramListUpdated(Convert.programListChunkFromHal( - programListChunk))); + lockAndFireLater(() -> { + android.hardware.radio.ProgramList.Chunk chunk = + Convert.programListChunkFromHal(programListChunk); + fanoutAidlCallbackLocked(cb -> cb.onProgramListUpdated(chunk)); + }); } @Override public void onAntennaStateChange(boolean connected) { - synchronized (mLock) { + lockAndFireLater(() -> { mAntennaConnected = connected; fanoutAidlCallbackLocked(cb -> cb.onAntennaState(connected)); - } + }); } @Override public void onParametersUpdated(ArrayList<VendorKeyValue> parameters) { - fanoutAidlCallback(cb -> cb.onParametersUpdated(Convert.vendorInfoFromHal(parameters))); + lockAndFireLater(() -> { + Map<String, String> cparam = Convert.vendorInfoFromHal(parameters); + fanoutAidlCallbackLocked(cb -> cb.onParametersUpdated(cparam)); + }); } }; @@ -113,6 +125,7 @@ class RadioModule { @NonNull RadioManager.ModuleProperties properties) throws RemoteException { mProperties = Objects.requireNonNull(properties); mService = Objects.requireNonNull(service); + mHandler = new Handler(Looper.getMainLooper()); } public static @Nullable RadioModule tryLoadingModule(int idx, @NonNull String fqName) { @@ -201,15 +214,22 @@ class RadioModule { } } + // add to mHandler queue, but ensure the runnable holds mLock when it gets executed + private void lockAndFireLater(Runnable r) { + mHandler.post(() -> { + synchronized (mLock) { + r.run(); + } + }); + } + interface AidlCallbackRunnable { void run(android.hardware.radio.ITunerCallback callback) throws RemoteException; } // Invokes runnable with each TunerSession currently open. void fanoutAidlCallback(AidlCallbackRunnable runnable) { - synchronized (mLock) { - fanoutAidlCallbackLocked(runnable); - } + lockAndFireLater(() -> fanoutAidlCallbackLocked(runnable)); } private void fanoutAidlCallbackLocked(AidlCallbackRunnable runnable) { diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java index 7b45a1b1997c..669dce7160cd 100644 --- a/services/core/java/com/android/server/notification/PreferencesHelper.java +++ b/services/core/java/com/android/server/notification/PreferencesHelper.java @@ -73,6 +73,9 @@ public class PreferencesHelper implements RankingConfig { private static final String NON_BLOCKABLE_CHANNEL_DELIM = ":"; @VisibleForTesting + static final int NOTIFICATION_CHANNEL_COUNT_LIMIT = 5000; + + @VisibleForTesting static final String TAG_RANKING = "ranking"; private static final String TAG_PACKAGE = "package"; private static final String TAG_CHANNEL = "channel"; @@ -179,6 +182,7 @@ public class PreferencesHelper implements RankingConfig { // noop } } + boolean skipWarningLogged = false; PackagePreferences r = getOrCreatePackagePreferencesLocked(name, uid, XmlUtils.readIntAttribute( @@ -225,6 +229,14 @@ public class PreferencesHelper implements RankingConfig { } // Channels if (TAG_CHANNEL.equals(tagName)) { + if (r.channels.size() >= NOTIFICATION_CHANNEL_COUNT_LIMIT) { + if (!skipWarningLogged) { + Slog.w(TAG, "Skipping further channels for " + r.pkg + + "; app has too many"); + skipWarningLogged = true; + } + continue; + } String id = parser.getAttributeValue(null, ATT_ID); String channelName = parser.getAttributeValue(null, ATT_NAME); int channelImportance = XmlUtils.readIntAttribute( @@ -690,6 +702,10 @@ public class PreferencesHelper implements RankingConfig { return needsPolicyFileChange; } + if (r.channels.size() >= NOTIFICATION_CHANNEL_COUNT_LIMIT) { + throw new IllegalStateException("Limit exceed; cannot create more channels"); + } + needsPolicyFileChange = true; if (channel.getImportance() < IMPORTANCE_NONE diff --git a/services/core/java/com/android/server/policy/role/LegacyRoleResolutionPolicy.java b/services/core/java/com/android/server/policy/role/LegacyRoleResolutionPolicy.java index 77bf930fb4d7..712012d9e621 100644 --- a/services/core/java/com/android/server/policy/role/LegacyRoleResolutionPolicy.java +++ b/services/core/java/com/android/server/policy/role/LegacyRoleResolutionPolicy.java @@ -24,20 +24,17 @@ import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; import android.content.pm.ResolveInfo; -import android.os.Debug; import android.provider.Settings; -import android.telecom.TelecomManager; import android.text.TextUtils; -import android.util.Log; import android.util.Slog; +import com.android.internal.R; import com.android.internal.telephony.SmsApplication; import com.android.internal.util.CollectionUtils; import com.android.server.LocalServices; import com.android.server.role.RoleManagerService; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.List; @@ -67,14 +64,25 @@ public class LegacyRoleResolutionPolicy implements RoleManagerService.RoleHolder public List<String> getRoleHolders(@NonNull String roleName, @UserIdInt int userId) { switch (roleName) { case RoleManager.ROLE_ASSISTANT: { - String legacyAssistant = Settings.Secure.getStringForUser( - mContext.getContentResolver(), Settings.Secure.ASSISTANT, userId); - if (legacyAssistant == null || legacyAssistant.isEmpty()) { - return Collections.emptyList(); + String packageName; + String setting = Settings.Secure.getStringForUser(mContext.getContentResolver(), + Settings.Secure.ASSISTANT, userId); + // AssistUtils was using the default assistant app if Settings.Secure.ASSISTANT is + // null, while only an empty string means user selected "None". + if (setting != null) { + if (!setting.isEmpty()) { + ComponentName componentName = ComponentName.unflattenFromString(setting); + packageName = componentName != null ? componentName.getPackageName() : null; + } else { + packageName = null; + } + } else if (mContext.getPackageManager().isDeviceUpgrading()) { + String defaultAssistant = mContext.getString(R.string.config_defaultAssistant); + packageName = !TextUtils.isEmpty(defaultAssistant) ? defaultAssistant : null; } else { - return Collections.singletonList( - ComponentName.unflattenFromString(legacyAssistant).getPackageName()); + packageName = null; } + return CollectionUtils.singletonOrEmpty(packageName); } case RoleManager.ROLE_BROWSER: { PackageManagerInternal packageManagerInternal = LocalServices.getService( @@ -84,44 +92,36 @@ public class LegacyRoleResolutionPolicy implements RoleManagerService.RoleHolder return CollectionUtils.singletonOrEmpty(packageName); } case RoleManager.ROLE_DIALER: { - String setting = Settings.Secure.getStringForUser( - mContext.getContentResolver(), + String setting = Settings.Secure.getStringForUser(mContext.getContentResolver(), Settings.Secure.DIALER_DEFAULT_APPLICATION, userId); - return CollectionUtils.singletonOrEmpty(!TextUtils.isEmpty(setting) - ? setting - : mContext.getSystemService(TelecomManager.class).getSystemDialerPackage()); + String packageName; + if (!TextUtils.isEmpty(setting)) { + packageName = setting; + } else if (mContext.getPackageManager().isDeviceUpgrading()) { + // DefaultDialerManager was using the default dialer app if + // Settings.Secure.DIALER_DEFAULT_APPLICATION is invalid. + // TelecomManager.getSystemDialerPackage() won't work because it might not + // be ready. + packageName = mContext.getString(R.string.config_defaultDialer); + } else { + packageName = null; + } + return CollectionUtils.singletonOrEmpty(packageName); } case RoleManager.ROLE_SMS: { - // Moved over from SmsApplication#getApplication - String result = Settings.Secure.getStringForUser( - mContext.getContentResolver(), + String setting = Settings.Secure.getStringForUser(mContext.getContentResolver(), Settings.Secure.SMS_DEFAULT_APPLICATION, userId); - // TODO: STOPSHIP: Remove the following code once we read the value of - // config_defaultSms in RoleControllerService. - if (result == null) { - Collection<SmsApplication.SmsApplicationData> applications = - SmsApplication.getApplicationCollectionAsUser(mContext, userId); - SmsApplication.SmsApplicationData applicationData; - String defaultPackage = mContext.getResources() - .getString(com.android.internal.R.string.default_sms_application); - applicationData = - SmsApplication.getApplicationForPackage(applications, defaultPackage); - - if (applicationData == null) { - // Are there any applications? - if (applications.size() != 0) { - applicationData = - (SmsApplication.SmsApplicationData) applications.toArray()[0]; - } - } - if (DEBUG) { - Log.i(LOG_TAG, "Found default sms app: " + applicationData - + " among: " + applications + " from " + Debug.getCallers(4)); - } - SmsApplication.SmsApplicationData app = applicationData; - result = app == null ? null : app.mPackageName; + String packageName; + if (!TextUtils.isEmpty(setting)) { + packageName = setting; + } else if (mContext.getPackageManager().isDeviceUpgrading()) { + // SmsApplication was using the default SMS app if + // Settings.Secure.DIALER_DEFAULT_APPLICATION is invalid. + packageName = mContext.getString(R.string.config_defaultSms); + } else { + packageName = null; } - return CollectionUtils.singletonOrEmpty(result); + return CollectionUtils.singletonOrEmpty(packageName); } case RoleManager.ROLE_HOME: { PackageManager packageManager = mContext.getPackageManager(); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java index 8f8b746b59d4..365cd80c88c7 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java @@ -22,6 +22,8 @@ import static android.app.NotificationManager.IMPORTANCE_MAX; import static android.app.NotificationManager.IMPORTANCE_NONE; import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED; +import static com.android.server.notification.PreferencesHelper.NOTIFICATION_CHANNEL_COUNT_LIMIT; + import static junit.framework.Assert.assertNull; import static junit.framework.Assert.fail; @@ -2690,4 +2692,51 @@ public class PreferencesHelperTest extends UiServiceTestCase { assertFalse(mHelper.areBubblesAllowed(PKG_O, UID_O)); verify(mHandler, times(1)).requestSort(); } + + @Test + public void testTooManyChannels() { + for (int i = 0; i < NOTIFICATION_CHANNEL_COUNT_LIMIT; i++) { + NotificationChannel channel = new NotificationChannel(String.valueOf(i), + String.valueOf(i), NotificationManager.IMPORTANCE_HIGH); + mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true); + } + try { + NotificationChannel channel = new NotificationChannel( + String.valueOf(NOTIFICATION_CHANNEL_COUNT_LIMIT), + String.valueOf(NOTIFICATION_CHANNEL_COUNT_LIMIT), + NotificationManager.IMPORTANCE_HIGH); + mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true); + fail("Allowed to create too many notification channels"); + } catch (IllegalStateException e) { + // great + } + } + + @Test + public void testTooManyChannels_xml() throws Exception { + String extraChannel = "EXTRA"; + String extraChannel1 = "EXTRA1"; + + // create first... many... directly so we don't need a big xml blob in this test + for (int i = 0; i < NOTIFICATION_CHANNEL_COUNT_LIMIT; i++) { + NotificationChannel channel = new NotificationChannel(String.valueOf(i), + String.valueOf(i), NotificationManager.IMPORTANCE_HIGH); + mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true); + } + + final String xml = "<ranking version=\"1\">\n" + + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n" + + "<channel id=\"" + extraChannel + "\" name=\"hi\" importance=\"3\"/>" + + "<channel id=\"" + extraChannel1 + "\" name=\"hi\" importance=\"3\"/>" + + "</package>" + + "</ranking>"; + XmlPullParser parser = Xml.newPullParser(); + parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())), + null); + parser.nextTag(); + mHelper.readXml(parser, false, UserHandle.USER_ALL); + + assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, extraChannel, true)); + assertNull(mHelper.getNotificationChannel(PKG_O, UID_O, extraChannel1, true)); + } } diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java index e1ffb0f179f8..46d7509b43ca 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java @@ -1281,9 +1281,12 @@ public class VoiceInteractionManagerService extends SystemService { RoleObserver(@NonNull @CallbackExecutor Executor executor) { mRm.addOnRoleHoldersChangedListenerAsUser(executor, this, UserHandle.ALL); - UserHandle currentUser = UserHandle.of(LocalServices.getService( - ActivityManagerInternal.class).getCurrentUserId()); - onRoleHoldersChanged(RoleManager.ROLE_ASSISTANT, currentUser); + // Sync only if assistant role has been initialized. + if (mRm.isRoleAvailable(RoleManager.ROLE_ASSISTANT)) { + UserHandle currentUser = UserHandle.of(LocalServices.getService( + ActivityManagerInternal.class).getCurrentUserId()); + onRoleHoldersChanged(RoleManager.ROLE_ASSISTANT, currentUser); + } } private @NonNull String getDefaultRecognizer(@NonNull UserHandle user) { diff --git a/telephony/java/android/provider/Telephony.java b/telephony/java/android/provider/Telephony.java index 8e56fe72e152..38c81d394e11 100644 --- a/telephony/java/android/provider/Telephony.java +++ b/telephony/java/android/provider/Telephony.java @@ -4049,6 +4049,53 @@ public final class Telephony { public static final String DEFAULT_SORT_ORDER = DELIVERY_TIME + " DESC"; /** + * The Epoch Unix timestamp when the device received the message. + * <P>Type: INTEGER</P> + */ + public static final String RECEIVED_TIME = "received_time"; + + /** + * Indicates that whether the message has been broadcasted to the application. + * <P>Type: BOOLEAN</P> + */ + public static final String MESSAGE_BROADCASTED = "message_broadcasted"; + + /** + * The Warning Area Coordinates Elements. This element is used for geo-fencing purpose. + * + * The geometry and its coordinates are separated vertical bar, the first item is the + * geometry type and the remaining items are the parameter of this geometry. + * + * Only circle and polygon are supported. The coordinates are represented in Horizontal + * coordinates format. + * + * Coordinate encoding: + * "latitude, longitude" + * where -90.00000 <= latitude <= 90.00000 and -180.00000 <= longitude <= 180.00000 + * + * Polygon encoding: + * "polygon|lat1,lng1|lat2,lng2|...|latn,lngn" + * lat1,lng1 ... latn,lngn are the vertices coordinate of the polygon. + * + * Circle encoding: + * "circle|lat,lng|radius". + * lat,lng is the center of the circle. The unit of circle's radius is meter. + * + * Example: + * "circle|0,0|100" mean a circle which center located at (0,0) and its radius is 100 meter. + * "polygon|0,1.5|0,1|1,1|1,0" mean a polygon has vertices (0,1.5),(0,1),(1,1),(1,0). + * + * There could be more than one geometry store in this field, they are separated by a + * semicolon. + * + * Example: + * "circle|0,0|100;polygon|0,0|0,1.5|1,1|1,0;circle|100.123,100|200.123" + * + * <P>Type: TEXT</P> + */ + public static final String GEOMETRIES = "geometries"; + + /** * Query columns for instantiating {@link android.telephony.CellBroadcastMessage} objects. */ public static final String[] QUERY_COLUMNS = { diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index cb7014e56a87..67f346ff5597 100755 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -1010,6 +1010,18 @@ public class CarrierConfigManager { "call_forwarding_map_non_number_to_voicemail_bool"; /** + * When {@code true}, the phone will always tell the IMS stack to keep RTT enabled and + * determine on a per-call basis (based on extras from the dialer app) whether a call should be + * an RTT call or not. + * + * When {@code false}, the old behavior is used, where the toggle in accessibility settings is + * used to set the IMS stack's RTT enabled state. + * @hide + */ + public static final String KEY_IGNORE_RTT_MODE_SETTING_BOOL = + "ignore_rtt_mode_setting_bool"; + + /** * Determines whether conference calls are supported by a carrier. When {@code true}, * conference calling is supported, {@code false otherwise}. */ @@ -1375,6 +1387,13 @@ public class CarrierConfigManager { "read_only_apn_fields_string_array"; /** + * Default value of APN types field if not specified by user when adding/modifying an APN. + * @hide + */ + public static final String KEY_APN_SETTINGS_DEFAULT_APN_TYPES_STRING_ARRAY = + "apn_settings_default_apn_types_string_array"; + + /** * Boolean indicating if intent for emergency call state changes should be broadcast * @hide */ @@ -2616,25 +2635,34 @@ public class CarrierConfigManager { "call_waiting_service_class_int"; /** - * This configuration allow the system UI to display different 5G icon for different 5G status. + * This configuration allow the system UI to display different 5G icon for different 5G + * scenario. * - * There are four 5G status: + * There are five 5G scenarios: * 1. connected_mmwave: device currently connected to 5G cell as the secondary cell and using * millimeter wave. * 2. connected: device currently connected to 5G cell as the secondary cell but not using * millimeter wave. - * 3. not_restricted: device camped on a network that has 5G capability(not necessary to connect - * a 5G cell as a secondary cell) and the use of 5G is not restricted. - * 4. restricted: device camped on a network that has 5G capability(not necessary to connect a + * 3. not_restricted_rrc_idle: device camped on a network that has 5G capability(not necessary + * to connect a 5G cell as a secondary cell) and the use of 5G is not restricted and RRC + * currently in IDLE state. + * 4. not_restricted_rrc_con: device camped on a network that has 5G capability(not necessary + * to connect a 5G cell as a secondary cell) and the use of 5G is not restricted and RRC + * currently in CONNECTED state. + * 5. restricted: device camped on a network that has 5G capability(not necessary to connect a * 5G cell as a secondary cell) but the use of 5G is restricted. * * The configured string contains multiple key-value pairs separated by comma. For each pair, * the key and value is separated by a colon. The key is corresponded to a 5G status above and * the value is the icon name. Use "None" as the icon name if no icon should be shown in a - * specific 5G status. + * specific 5G scenario. If the scenario is "None", config can skip this key and value. * - * Here is an example of the configuration: - * "connected_mmwave:5GPlus,connected:5G,not_restricted:None,restricted:None" + * Icon name options: "5G_Plus", "5G". + * + * Here is an example: + * UE want to display 5G_Plus icon for scenario#1, and 5G icon for scenario#2; otherwise no + * define. + * The configuration is: "connected_mmwave:5G_Plus,connected:5G" * * @hide */ @@ -3075,6 +3103,13 @@ public class CarrierConfigManager { public static final String KEY_SUPPORT_WPS_OVER_IMS_BOOL = "support_wps_over_ims_bool"; + /** + * Holds the list of carrier certificate hashes. Note that each carrier has its own certificates + * @hide + */ + public static final String KEY_CARRIER_CERTIFICATE_STRING_ARRAY = + "carrier_certificate_string_array"; + /** The default value for every variable. */ private final static PersistableBundle sDefaults; @@ -3191,6 +3226,7 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_ALLOW_ADDING_APNS_BOOL, true); sDefaults.putStringArray(KEY_READ_ONLY_APN_TYPES_STRING_ARRAY, new String[] {"dun"}); sDefaults.putStringArray(KEY_READ_ONLY_APN_FIELDS_STRING_ARRAY, null); + sDefaults.putStringArray(KEY_APN_SETTINGS_DEFAULT_APN_TYPES_STRING_ARRAY, null); sDefaults.putBoolean(KEY_BROADCAST_EMERGENCY_CALL_STATE_CHANGES_BOOL, false); sDefaults.putBoolean(KEY_ALWAYS_SHOW_EMERGENCY_ALERT_ONOFF_BOOL, false); sDefaults.putBoolean(KEY_DISABLE_SEVERE_WHEN_EXTREME_DISABLED_BOOL, true); @@ -3234,6 +3270,7 @@ public class CarrierConfigManager { sDefaults.putInt(KEY_IMS_DTMF_TONE_DELAY_INT, 0); sDefaults.putInt(KEY_CDMA_DTMF_TONE_DELAY_INT, 100); sDefaults.putBoolean(KEY_CALL_FORWARDING_MAP_NON_NUMBER_TO_VOICEMAIL_BOOL, false); + sDefaults.putBoolean(KEY_IGNORE_RTT_MODE_SETTING_BOOL, false); sDefaults.putInt(KEY_CDMA_3WAYCALL_FLASH_DELAY_INT , 0); sDefaults.putBoolean(KEY_SUPPORT_CONFERENCE_CALL_BOOL, true); sDefaults.putBoolean(KEY_SUPPORT_IMS_CONFERENCE_CALL_BOOL, true); @@ -3453,7 +3490,7 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_USE_CALLER_ID_USSD_BOOL, false); sDefaults.putInt(KEY_CALL_WAITING_SERVICE_CLASS_INT, 1 /* SERVICE_CLASS_VOICE */); sDefaults.putString(KEY_5G_ICON_CONFIGURATION_STRING, - "connected_mmwave:None,connected:5G,not_restricted:None,restricted:None"); + "connected_mmwave:5G,connected:5G"); sDefaults.putInt(KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT, 0); sDefaults.putBoolean(KEY_ASCII_7_BIT_SUPPORT_FOR_LONG_MESSAGE_BOOL, false); /* Default value is minimum RSRP level needed for SIGNAL_STRENGTH_GOOD */ @@ -3481,7 +3518,7 @@ public class CarrierConfigManager { sDefaults.putStringArray(KEY_EMERGENCY_NUMBER_PREFIX_STRING_ARRAY, new String[0]); sDefaults.putBoolean(KEY_USE_USIM_BOOL, false); sDefaults.putBoolean(KEY_SHOW_WFC_LOCATION_PRIVACY_POLICY_BOOL, false); - sDefaults.putBoolean(KEY_AUTO_CANCEL_CS_REJECT_NOTIFICATION, false); + sDefaults.putBoolean(KEY_AUTO_CANCEL_CS_REJECT_NOTIFICATION, true); sDefaults.putString(KEY_SMART_FORWARDING_CONFIG_COMPONENT_NAME_STRING, ""); sDefaults.putBoolean(KEY_ALWAYS_SHOW_PRIMARY_SIGNAL_BAR_IN_OPPORTUNISTIC_NETWORK_BOOLEAN, false); @@ -3495,6 +3532,7 @@ public class CarrierConfigManager { -89, /* SIGNAL_STRENGTH_GREAT */ }); sDefaults.putBoolean(KEY_SUPPORT_WPS_OVER_IMS_BOOL, true); + sDefaults.putStringArray(KEY_CARRIER_CERTIFICATE_STRING_ARRAY, null); } /** diff --git a/telephony/java/android/telephony/CellIdentity.java b/telephony/java/android/telephony/CellIdentity.java index 258a873c3ac5..432978d1c866 100644 --- a/telephony/java/android/telephony/CellIdentity.java +++ b/telephony/java/android/telephony/CellIdentity.java @@ -17,6 +17,7 @@ package android.telephony; import android.annotation.CallSuper; +import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Parcel; import android.os.Parcelable; @@ -61,7 +62,7 @@ public abstract class CellIdentity implements Parcelable { mType = type; // Only allow INT_MAX if unknown string mcc/mnc - if (mcc == null || mcc.matches("^[0-9]{3}$")) { + if (mcc == null || isMcc(mcc)) { mMccStr = mcc; } else if (mcc.isEmpty() || mcc.equals(String.valueOf(Integer.MAX_VALUE))) { // If the mccStr is empty or unknown, set it as null. @@ -73,7 +74,7 @@ public abstract class CellIdentity implements Parcelable { log("invalid MCC format: " + mcc); } - if (mnc == null || mnc.matches("^[0-9]{2,3}$")) { + if (mnc == null || isMnc(mnc)) { mMncStr = mnc; } else if (mnc.isEmpty() || mnc.equals(String.valueOf(Integer.MAX_VALUE))) { // If the mncStr is empty or unknown, set it as null. @@ -262,4 +263,30 @@ public abstract class CellIdentity implements Parcelable { if ((value < rangeMin || value > rangeMax) && value != special) return CellInfo.UNAVAILABLE; return value; } + + /** @hide */ + private static boolean isMcc(@NonNull String mcc) { + // ensure no out of bounds indexing + if (mcc.length() != 3) return false; + + // Character.isDigit allows all unicode digits, not just [0-9] + for (int i = 0; i < 3; i++) { + if (mcc.charAt(i) < '0' || mcc.charAt(i) > '9') return false; + } + + return true; + } + + /** @hide */ + private static boolean isMnc(@NonNull String mnc) { + // ensure no out of bounds indexing + if (mnc.length() < 2 || mnc.length() > 3) return false; + + // Character.isDigit allows all unicode digits, not just [0-9] + for (int i = 0; i < mnc.length(); i++) { + if (mnc.charAt(i) < '0' || mnc.charAt(i) > '9') return false; + } + + return true; + } } diff --git a/telephony/java/android/telephony/NetworkServiceCallback.java b/telephony/java/android/telephony/NetworkServiceCallback.java index 1c64bcd28966..89b96654451e 100644 --- a/telephony/java/android/telephony/NetworkServiceCallback.java +++ b/telephony/java/android/telephony/NetworkServiceCallback.java @@ -24,7 +24,6 @@ import android.telephony.NetworkService.NetworkServiceProvider; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import java.lang.ref.WeakReference; /** * Network service callback. Object of this class is passed to NetworkServiceProvider upon @@ -61,11 +60,11 @@ public class NetworkServiceCallback { /** Request failed */ public static final int RESULT_ERROR_FAILED = 5; - private final WeakReference<INetworkServiceCallback> mCallback; + private final INetworkServiceCallback mCallback; /** @hide */ public NetworkServiceCallback(INetworkServiceCallback callback) { - mCallback = new WeakReference<>(callback); + mCallback = callback; } /** @@ -78,15 +77,14 @@ public class NetworkServiceCallback { */ public void onRequestNetworkRegistrationInfoComplete(int result, @Nullable NetworkRegistrationInfo state) { - INetworkServiceCallback callback = mCallback.get(); - if (callback != null) { + if (mCallback != null) { try { - callback.onRequestNetworkRegistrationInfoComplete(result, state); + mCallback.onRequestNetworkRegistrationInfoComplete(result, state); } catch (RemoteException e) { Rlog.e(mTag, "Failed to onRequestNetworkRegistrationInfoComplete on the remote"); } } else { - Rlog.e(mTag, "Weak reference of callback is null."); + Rlog.e(mTag, "onRequestNetworkRegistrationInfoComplete callback is null."); } } }
\ No newline at end of file diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java index 1e6cd474d13b..a94b101d6b42 100644 --- a/telephony/java/android/telephony/SubscriptionInfo.java +++ b/telephony/java/android/telephony/SubscriptionInfo.java @@ -38,6 +38,7 @@ import android.text.TextUtils; import android.util.DisplayMetrics; import android.util.Log; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -147,7 +148,14 @@ public class SubscriptionInfo implements Parcelable { * The access rules for this subscription, if it is embedded and defines any. */ @Nullable - private UiccAccessRule[] mAccessRules; + private UiccAccessRule[] mNativeAccessRules; + + /** + * The carrier certificates for this subscription that are saved in carrier configs. + * The other carrier certificates are embedded on Uicc and stored as part of mNativeAccessRules. + */ + @Nullable + private UiccAccessRule[] mCarrierConfigAccessRules; /** * The string ID of the SIM card. It is the ICCID of the active profile for a UICC card and the @@ -206,12 +214,12 @@ public class SubscriptionInfo implements Parcelable { public SubscriptionInfo(int id, String iccId, int simSlotIndex, CharSequence displayName, CharSequence carrierName, int nameSource, int iconTint, String number, int roaming, Bitmap icon, String mcc, String mnc, String countryIso, boolean isEmbedded, - @Nullable UiccAccessRule[] accessRules, String cardString) { + @Nullable UiccAccessRule[] nativeAccessRules, String cardString) { this(id, iccId, simSlotIndex, displayName, carrierName, nameSource, iconTint, number, - roaming, icon, mcc, mnc, countryIso, isEmbedded, accessRules, cardString, -1, + roaming, icon, mcc, mnc, countryIso, isEmbedded, nativeAccessRules, cardString, -1, false, null, false, TelephonyManager.UNKNOWN_CARRIER_ID, SubscriptionManager.PROFILE_CLASS_DEFAULT, - SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM, null); + SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM, null, null); } /** @@ -220,12 +228,12 @@ public class SubscriptionInfo implements Parcelable { public SubscriptionInfo(int id, String iccId, int simSlotIndex, CharSequence displayName, CharSequence carrierName, int nameSource, int iconTint, String number, int roaming, Bitmap icon, String mcc, String mnc, String countryIso, boolean isEmbedded, - @Nullable UiccAccessRule[] accessRules, String cardString, boolean isOpportunistic, - @Nullable String groupUUID, int carrierId, int profileClass) { + @Nullable UiccAccessRule[] nativeAccessRules, String cardString, + boolean isOpportunistic, @Nullable String groupUUID, int carrierId, int profileClass) { this(id, iccId, simSlotIndex, displayName, carrierName, nameSource, iconTint, number, - roaming, icon, mcc, mnc, countryIso, isEmbedded, accessRules, cardString, -1, + roaming, icon, mcc, mnc, countryIso, isEmbedded, nativeAccessRules, cardString, -1, isOpportunistic, groupUUID, false, carrierId, profileClass, - SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM, null); + SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM, null, null); } /** @@ -234,9 +242,10 @@ public class SubscriptionInfo implements Parcelable { public SubscriptionInfo(int id, String iccId, int simSlotIndex, CharSequence displayName, CharSequence carrierName, int nameSource, int iconTint, String number, int roaming, Bitmap icon, String mcc, String mnc, String countryIso, boolean isEmbedded, - @Nullable UiccAccessRule[] accessRules, String cardString, int cardId, + @Nullable UiccAccessRule[] nativeAccessRules, String cardString, int cardId, boolean isOpportunistic, @Nullable String groupUUID, boolean isGroupDisabled, - int carrierId, int profileClass, int subType, @Nullable String groupOwner) { + int carrierId, int profileClass, int subType, @Nullable String groupOwner, + @Nullable UiccAccessRule[] carrierConfigAccessRules) { this.mId = id; this.mIccId = iccId; this.mSimSlotIndex = simSlotIndex; @@ -251,7 +260,7 @@ public class SubscriptionInfo implements Parcelable { this.mMnc = mnc; this.mCountryIso = countryIso; this.mIsEmbedded = isEmbedded; - this.mAccessRules = accessRules; + this.mNativeAccessRules = nativeAccessRules; this.mCardString = cardString; this.mCardId = cardId; this.mIsOpportunistic = isOpportunistic; @@ -261,6 +270,7 @@ public class SubscriptionInfo implements Parcelable { this.mProfileClass = profileClass; this.mSubscriptionType = subType; this.mGroupOwner = groupOwner; + this.mCarrierConfigAccessRules = carrierConfigAccessRules; } /** @@ -541,7 +551,6 @@ public class SubscriptionInfo implements Parcelable { * * @param context Context of the application to check. * @return whether the app is authorized to manage this subscription per its metadata. - * @throws UnsupportedOperationException if this subscription is not embedded. * @hide * @deprecated - Do not use. */ @@ -557,16 +566,13 @@ public class SubscriptionInfo implements Parcelable { * @param context Any context. * @param packageName Package name of the app to check. * @return whether the app is authorized to manage this subscription per its metadata. - * @throws UnsupportedOperationException if this subscription is not embedded. * @hide * @deprecated - Do not use. */ @Deprecated public boolean canManageSubscription(Context context, String packageName) { - if (!isEmbedded()) { - throw new UnsupportedOperationException("Not an embedded subscription"); - } - if (mAccessRules == null) { + List<UiccAccessRule> allAccessRules = getAllAccessRules(); + if (allAccessRules == null) { return false; } PackageManager packageManager = context.getPackageManager(); @@ -576,7 +582,7 @@ public class SubscriptionInfo implements Parcelable { } catch (PackageManager.NameNotFoundException e) { throw new IllegalArgumentException("Unknown package: " + packageName, e); } - for (UiccAccessRule rule : mAccessRules) { + for (UiccAccessRule rule : allAccessRules) { if (rule.getCarrierPrivilegeStatus(packageInfo) == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { return true; @@ -586,17 +592,31 @@ public class SubscriptionInfo implements Parcelable { } /** - * @return the {@link UiccAccessRule}s dictating who is authorized to manage this subscription. + * @return the {@link UiccAccessRule}s that are stored in Uicc, dictating who + * is authorized to manage this subscription. + * TODO and fix it properly in R / master: either deprecate this and have 3 APIs + * native + carrier + all, or have this return all by default. * @throws UnsupportedOperationException if this subscription is not embedded. * @hide */ @SystemApi public @Nullable List<UiccAccessRule> getAccessRules() { - if (!isEmbedded()) { - throw new UnsupportedOperationException("Not an embedded subscription"); + if (mNativeAccessRules == null) return null; + return Arrays.asList(mNativeAccessRules); + } + + /** + * @return the {@link UiccAccessRule}s that are both stored on Uicc and in carrierConfigs + * dictating who is authorized to manage this subscription. + * @hide + */ + public @Nullable List<UiccAccessRule> getAllAccessRules() { + List<UiccAccessRule> merged = new ArrayList<>(); + if (mNativeAccessRules != null) merged.addAll(getAccessRules()); + if (mCarrierConfigAccessRules != null) { + merged.addAll(Arrays.asList(mCarrierConfigAccessRules)); } - if (mAccessRules == null) return null; - return Arrays.asList(mAccessRules); + return merged.isEmpty() ? null : merged; } /** @@ -651,7 +671,7 @@ public class SubscriptionInfo implements Parcelable { String countryIso = source.readString(); Bitmap iconBitmap = source.readParcelable(Bitmap.class.getClassLoader()); boolean isEmbedded = source.readBoolean(); - UiccAccessRule[] accessRules = source.createTypedArray(UiccAccessRule.CREATOR); + UiccAccessRule[] nativeAccessRules = source.createTypedArray(UiccAccessRule.CREATOR); String cardString = source.readString(); int cardId = source.readInt(); boolean isOpportunistic = source.readBoolean(); @@ -663,11 +683,14 @@ public class SubscriptionInfo implements Parcelable { String[] ehplmns = source.readStringArray(); String[] hplmns = source.readStringArray(); String groupOwner = source.readString(); + UiccAccessRule[] carrierConfigAccessRules = source.createTypedArray( + UiccAccessRule.CREATOR); SubscriptionInfo info = new SubscriptionInfo(id, iccId, simSlotIndex, displayName, carrierName, nameSource, iconTint, number, dataRoaming, iconBitmap, mcc, mnc, - countryIso, isEmbedded, accessRules, cardString, cardId, isOpportunistic, - groupUUID, isGroupDisabled, carrierid, profileClass, subType, groupOwner); + countryIso, isEmbedded, nativeAccessRules, cardString, cardId, isOpportunistic, + groupUUID, isGroupDisabled, carrierid, profileClass, subType, groupOwner, + carrierConfigAccessRules); info.setAssociatedPlmns(ehplmns, hplmns); return info; } @@ -694,7 +717,7 @@ public class SubscriptionInfo implements Parcelable { dest.writeString(mCountryIso); dest.writeParcelable(mIconBitmap, flags); dest.writeBoolean(mIsEmbedded); - dest.writeTypedArray(mAccessRules, flags); + dest.writeTypedArray(mNativeAccessRules, flags); dest.writeString(mCardString); dest.writeInt(mCardId); dest.writeBoolean(mIsOpportunistic); @@ -706,6 +729,7 @@ public class SubscriptionInfo implements Parcelable { dest.writeStringArray(mEhplmns); dest.writeStringArray(mHplmns); dest.writeString(mGroupOwner); + dest.writeTypedArray(mCarrierConfigAccessRules, flags); } @Override @@ -738,7 +762,7 @@ public class SubscriptionInfo implements Parcelable { + " iconTint=" + mIconTint + " mNumber=" + Rlog.pii(Build.IS_DEBUGGABLE, mNumber) + " dataRoaming=" + mDataRoaming + " iconBitmap=" + mIconBitmap + " mcc " + mMcc + " mnc " + mMnc + "mCountryIso=" + mCountryIso + " isEmbedded " + mIsEmbedded - + " accessRules " + Arrays.toString(mAccessRules) + + " nativeAccessRules " + Arrays.toString(mNativeAccessRules) + " cardString=" + cardStringToPrint + " cardId=" + mCardId + " isOpportunistic " + mIsOpportunistic + " mGroupUUID=" + mGroupUUID + " mIsGroupDisabled=" + mIsGroupDisabled @@ -746,14 +770,15 @@ public class SubscriptionInfo implements Parcelable { + " ehplmns = " + Arrays.toString(mEhplmns) + " hplmns = " + Arrays.toString(mHplmns) + " subscriptionType=" + mSubscriptionType - + " mGroupOwner=" + mGroupOwner + "}"; + + " mGroupOwner=" + mGroupOwner + + " carrierConfigAccessRules=" + mCarrierConfigAccessRules + "}"; } @Override public int hashCode() { return Objects.hash(mId, mSimSlotIndex, mNameSource, mIconTint, mDataRoaming, mIsEmbedded, mIsOpportunistic, mGroupUUID, mIccId, mNumber, mMcc, mMnc, - mCountryIso, mCardString, mCardId, mDisplayName, mCarrierName, mAccessRules, + mCountryIso, mCardString, mCardId, mDisplayName, mCarrierName, mNativeAccessRules, mIsGroupDisabled, mCarrierId, mProfileClass, mGroupOwner); } @@ -789,7 +814,7 @@ public class SubscriptionInfo implements Parcelable { && Objects.equals(mGroupOwner, toCompare.mGroupOwner) && TextUtils.equals(mDisplayName, toCompare.mDisplayName) && TextUtils.equals(mCarrierName, toCompare.mCarrierName) - && Arrays.equals(mAccessRules, toCompare.mAccessRules) + && Arrays.equals(mNativeAccessRules, toCompare.mNativeAccessRules) && mProfileClass == toCompare.mProfileClass && Arrays.equals(mEhplmns, toCompare.mEhplmns) && Arrays.equals(mHplmns, toCompare.mHplmns); diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index 2822fccdb398..036d1ec75a24 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -571,6 +571,16 @@ public class SubscriptionManager { public static final String ACCESS_RULES = "access_rules"; /** + * TelephonyProvider column name for the encoded {@link UiccAccessRule}s from + * {@link UiccAccessRule#encodeRules} but for the rules that come from CarrierConfigs. + * Only present if there are access rules in CarrierConfigs + * <p>TYPE: BLOB + * @hide + */ + public static final String ACCESS_RULES_FROM_CARRIER_CONFIGS = + "access_rules_from_carrier_configs"; + + /** * TelephonyProvider column name identifying whether an embedded subscription is on a removable * card. Such subscriptions are marked inaccessible as soon as the current card is removed. * Otherwise, they will remain accessible unless explicitly deleted. Only present if @@ -2578,7 +2588,6 @@ public class SubscriptionManager { * * @param info The subscription to check. * @return whether the app is authorized to manage this subscription per its metadata. - * @throws IllegalArgumentException if this subscription is not embedded. */ public boolean canManageSubscription(SubscriptionInfo info) { return canManageSubscription(info, mContext.getPackageName()); @@ -2594,14 +2603,10 @@ public class SubscriptionManager { * @param info The subscription to check. * @param packageName Package name of the app to check. * @return whether the app is authorized to manage this subscription per its access rules. - * @throws IllegalArgumentException if this subscription is not embedded. * @hide */ public boolean canManageSubscription(SubscriptionInfo info, String packageName) { - if (!info.isEmbedded()) { - throw new IllegalArgumentException("Not an embedded subscription"); - } - if (info.getAccessRules() == null) { + if (info.getAllAccessRules() == null) { return false; } PackageManager packageManager = mContext.getPackageManager(); @@ -2611,7 +2616,7 @@ public class SubscriptionManager { } catch (PackageManager.NameNotFoundException e) { throw new IllegalArgumentException("Unknown package: " + packageName, e); } - for (UiccAccessRule rule : info.getAccessRules()) { + for (UiccAccessRule rule : info.getAllAccessRules()) { if (rule.getCarrierPrivilegeStatus(packageInfo) == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { return true; @@ -3002,7 +3007,7 @@ public class SubscriptionManager { // to the caller. boolean hasCarrierPrivilegePermission = TelephonyManager.from(mContext) .hasCarrierPrivileges(info.getSubscriptionId()) - || (info.isEmbedded() && canManageSubscription(info)); + || canManageSubscription(info); return hasCarrierPrivilegePermission; } diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 7477c3e29448..248415bba75b 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -11001,6 +11001,8 @@ public class TelephonyManager { * The {@link #EXTRA_NETWORK_COUNTRY} extra indicates the country code of the current * network returned by {@link #getNetworkCountryIso()}. * + * <p>There may be a delay of several minutes before reporting that no country is detected. + * * @see #EXTRA_NETWORK_COUNTRY * @see #getNetworkCountryIso() */ diff --git a/telephony/java/android/telephony/data/DataServiceCallback.java b/telephony/java/android/telephony/data/DataServiceCallback.java index 89d30c0d4373..11dc78a611ff 100644 --- a/telephony/java/android/telephony/data/DataServiceCallback.java +++ b/telephony/java/android/telephony/data/DataServiceCallback.java @@ -27,7 +27,6 @@ import android.telephony.data.DataService.DataServiceProvider; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import java.lang.ref.WeakReference; import java.util.List; /** @@ -64,11 +63,11 @@ public class DataServiceCallback { /** Request sent in illegal state */ public static final int RESULT_ERROR_ILLEGAL_STATE = 4; - private final WeakReference<IDataServiceCallback> mCallback; + private final IDataServiceCallback mCallback; /** @hide */ public DataServiceCallback(IDataServiceCallback callback) { - mCallback = new WeakReference<>(callback); + mCallback = callback; } /** @@ -80,14 +79,15 @@ public class DataServiceCallback { */ public void onSetupDataCallComplete(@ResultCode int result, @Nullable DataCallResponse response) { - IDataServiceCallback callback = mCallback.get(); - if (callback != null) { + if (mCallback != null) { try { if (DBG) Rlog.d(TAG, "onSetupDataCallComplete"); - callback.onSetupDataCallComplete(result, response); + mCallback.onSetupDataCallComplete(result, response); } catch (RemoteException e) { Rlog.e(TAG, "Failed to onSetupDataCallComplete on the remote"); } + } else { + Rlog.e(TAG, "onSetupDataCallComplete: callback is null!"); } } @@ -98,14 +98,15 @@ public class DataServiceCallback { * @param result The result code. Must be one of the {@link ResultCode}. */ public void onDeactivateDataCallComplete(@ResultCode int result) { - IDataServiceCallback callback = mCallback.get(); - if (callback != null) { + if (mCallback != null) { try { if (DBG) Rlog.d(TAG, "onDeactivateDataCallComplete"); - callback.onDeactivateDataCallComplete(result); + mCallback.onDeactivateDataCallComplete(result); } catch (RemoteException e) { Rlog.e(TAG, "Failed to onDeactivateDataCallComplete on the remote"); } + } else { + Rlog.e(TAG, "onDeactivateDataCallComplete: callback is null!"); } } @@ -116,13 +117,14 @@ public class DataServiceCallback { * @param result The result code. Must be one of the {@link ResultCode}. */ public void onSetInitialAttachApnComplete(@ResultCode int result) { - IDataServiceCallback callback = mCallback.get(); - if (callback != null) { + if (mCallback != null) { try { - callback.onSetInitialAttachApnComplete(result); + mCallback.onSetInitialAttachApnComplete(result); } catch (RemoteException e) { Rlog.e(TAG, "Failed to onSetInitialAttachApnComplete on the remote"); } + } else { + Rlog.e(TAG, "onSetInitialAttachApnComplete: callback is null!"); } } @@ -133,13 +135,14 @@ public class DataServiceCallback { * @param result The result code. Must be one of the {@link ResultCode}. */ public void onSetDataProfileComplete(@ResultCode int result) { - IDataServiceCallback callback = mCallback.get(); - if (callback != null) { + if (mCallback != null) { try { - callback.onSetDataProfileComplete(result); + mCallback.onSetDataProfileComplete(result); } catch (RemoteException e) { Rlog.e(TAG, "Failed to onSetDataProfileComplete on the remote"); } + } else { + Rlog.e(TAG, "onSetDataProfileComplete: callback is null!"); } } @@ -153,13 +156,14 @@ public class DataServiceCallback { */ public void onRequestDataCallListComplete(@ResultCode int result, @NonNull List<DataCallResponse> dataCallList) { - IDataServiceCallback callback = mCallback.get(); - if (callback != null) { + if (mCallback != null) { try { - callback.onRequestDataCallListComplete(result, dataCallList); + mCallback.onRequestDataCallListComplete(result, dataCallList); } catch (RemoteException e) { Rlog.e(TAG, "Failed to onRequestDataCallListComplete on the remote"); } + } else { + Rlog.e(TAG, "onRequestDataCallListComplete: callback is null!"); } } @@ -170,14 +174,15 @@ public class DataServiceCallback { * @param dataCallList List of the current active data connection. */ public void onDataCallListChanged(@NonNull List<DataCallResponse> dataCallList) { - IDataServiceCallback callback = mCallback.get(); - if (callback != null) { + if (mCallback != null) { try { if (DBG) Rlog.d(TAG, "onDataCallListChanged"); - callback.onDataCallListChanged(dataCallList); + mCallback.onDataCallListChanged(dataCallList); } catch (RemoteException e) { Rlog.e(TAG, "Failed to onDataCallListChanged on the remote"); } + } else { + Rlog.e(TAG, "onDataCallListChanged: callback is null!"); } } } diff --git a/telephony/java/com/android/internal/telephony/CbGeoUtils.java b/telephony/java/com/android/internal/telephony/CbGeoUtils.java new file mode 100644 index 000000000000..c973b672ae40 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/CbGeoUtils.java @@ -0,0 +1,359 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.telephony; + +import android.annotation.NonNull; +import android.telephony.Rlog; +import android.text.TextUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + + +/** + * This utils class is specifically used for geo-targeting of CellBroadcast messages. + * The coordinates used by this utils class are latitude and longitude, but some algorithms in this + * class only use them as coordinates on plane, so the calculation will be inaccurate. So don't use + * this class for anything other then geo-targeting of cellbroadcast messages. + */ +public class CbGeoUtils { + /** Geometric interface. */ + public interface Geometry { + /** + * Determines if the given point {@code p} is inside the geometry. + * @param p point in latitude, longitude format. + * @return {@code True} if the given point is inside the geometry. + */ + boolean contains(LatLng p); + } + + /** + * Tolerance for determining if the value is 0. If the absolute value of a value is less than + * this tolerance, it will be treated as 0. + */ + public static final double EPS = 1e-7; + + /** The radius of earth. */ + public static final int EARTH_RADIUS_METER = 6371 * 1000; + + private static final String TAG = "CbGeoUtils"; + + /** The identifier of geometry in the encoded string. */ + private static final String CIRCLE_SYMBOL = "circle"; + private static final String POLYGON_SYMBOL = "polygon"; + + /** Point represent by (latitude, longitude). */ + public static class LatLng { + public final double lat; + public final double lng; + + /** + * Constructor. + * @param lat latitude, range [-90, 90] + * @param lng longitude, range [-180, 180] + */ + public LatLng(double lat, double lng) { + this.lat = lat; + this.lng = lng; + } + + /** + * @param p the point use to calculate the subtraction result. + * @return the result of this point subtract the given point {@code p}. + */ + public LatLng subtract(LatLng p) { + return new LatLng(lat - p.lat, lng - p.lng); + } + + /** + * Calculate the distance in meter between this point and the given point {@code p}. + * @param p the point use to calculate the distance. + * @return the distance in meter. + */ + public double distance(LatLng p) { + double dlat = Math.sin(0.5 * Math.toRadians(lat - p.lat)); + double dlng = Math.sin(0.5 * Math.toRadians(lng - p.lng)); + double x = dlat * dlat + + dlng * dlng * Math.cos(Math.toRadians(lat)) * Math.cos(Math.toRadians(p.lat)); + return 2 * Math.atan2(Math.sqrt(x), Math.sqrt(1 - x)) * EARTH_RADIUS_METER; + } + } + + /** + * The class represents a simple polygon with at least 3 points. + */ + public static class Polygon implements Geometry { + /** + * In order to reduce the loss of precision in floating point calculations, all vertices + * of the polygon are scaled. Set the value of scale to 1000 can take into account the + * actual distance accuracy of 1 meter if the EPS is 1e-7 during the calculation. + */ + private static final double SCALE = 1000.0; + + private final List<LatLng> mVertices; + private final List<Point> mScaledVertices; + private final LatLng mOrigin; + + /** + * Constructs a simple polygon from the given vertices. The adjacent two vertices are + * connected to form an edge of the polygon. The polygon has at least 3 vertices, and the + * last vertices and the first vertices must be adjacent. + * + * The longitude difference in the vertices should be less than 180 degree. + */ + public Polygon(@NonNull List<LatLng> vertices) { + mVertices = vertices; + + // Find the point with smallest longitude as the mOrigin point. + int idx = 0; + for (int i = 1; i < vertices.size(); i++) { + if (vertices.get(i).lng < vertices.get(idx).lng) { + idx = i; + } + } + mOrigin = vertices.get(idx); + + mScaledVertices = vertices.stream() + .map(latLng -> convertAndScaleLatLng(latLng)) + .collect(Collectors.toList()); + } + + public List<LatLng> getVertices() { + return mVertices; + } + + /** + * Check if the given point {@code p} is inside the polygon. This method counts the number + * of times the polygon winds around the point P, A.K.A "winding number". The point is + * outside only when this "winding number" is 0. + * + * If a point is on the edge of the polygon, it is also considered to be inside the polygon. + */ + @Override + public boolean contains(LatLng latLng) { + Point p = convertAndScaleLatLng(latLng); + + int n = mScaledVertices.size(); + int windingNumber = 0; + for (int i = 0; i < n; i++) { + Point a = mScaledVertices.get(i); + Point b = mScaledVertices.get((i + 1) % n); + + // CCW is counterclockwise + // CCW = ab x ap + // CCW > 0 -> ap is on the left side of ab + // CCW == 0 -> ap is on the same line of ab + // CCW < 0 -> ap is on the right side of ab + int ccw = sign(crossProduct(b.subtract(a), p.subtract(a))); + + if (ccw == 0) { + if (Math.min(a.x, b.x) <= p.x && p.x <= Math.max(a.x, b.x) + && Math.min(a.y, b.y) <= p.y && p.y <= Math.max(a.y, b.y)) { + return true; + } + } else { + if (sign(a.y - p.y) <= 0) { + // upward crossing + if (ccw > 0 && sign(b.y - p.y) > 0) { + ++windingNumber; + } + } else { + // downward crossing + if (ccw < 0 && sign(b.y - p.y) <= 0) { + --windingNumber; + } + } + } + } + return windingNumber != 0; + } + + /** + * Move the given point {@code latLng} to the coordinate system with {@code mOrigin} as the + * origin and scale it. {@code mOrigin} is selected from the vertices of a polygon, it has + * the smallest longitude value among all of the polygon vertices. + * + * @param latLng the point need to be converted and scaled. + * @Return a {@link Point} object. + */ + private Point convertAndScaleLatLng(LatLng latLng) { + double x = latLng.lat - mOrigin.lat; + double y = latLng.lng - mOrigin.lng; + + // If the point is in different hemispheres(western/eastern) than the mOrigin, and the + // edge between them cross the 180th meridian, then its relative coordinates will be + // extended. + // For example, suppose the longitude of the mOrigin is -178, and the longitude of the + // point to be converted is 175, then the longitude after the conversion is -8. + // calculation: (-178 - 8) - (-178). + if (sign(mOrigin.lng) != 0 && sign(mOrigin.lng) != sign(latLng.lng)) { + double distCross0thMeridian = Math.abs(mOrigin.lng) + Math.abs(latLng.lng); + if (sign(distCross0thMeridian * 2 - 360) > 0) { + y = sign(mOrigin.lng) * (360 - distCross0thMeridian); + } + } + return new Point(x * SCALE, y * SCALE); + } + + private static double crossProduct(Point a, Point b) { + return a.x * b.y - a.y * b.x; + } + + static final class Point { + public final double x; + public final double y; + + Point(double x, double y) { + this.x = x; + this.y = y; + } + + public Point subtract(Point p) { + return new Point(x - p.x, y - p.y); + } + } + } + + /** The class represents a circle. */ + public static class Circle implements Geometry { + private final LatLng mCenter; + private final double mRadiusMeter; + + public Circle(LatLng center, double radiusMeter) { + this.mCenter = center; + this.mRadiusMeter = radiusMeter; + } + + public LatLng getCenter() { + return mCenter; + } + + public double getRadius() { + return mRadiusMeter; + } + + @Override + public boolean contains(LatLng p) { + return mCenter.distance(p) <= mRadiusMeter; + } + } + + /** + * Parse the geometries from the encoded string {@code str}. The string must follow the + * geometry encoding specified by {@link android.provider.Telephony.CellBroadcasts#GEOMETRIES}. + */ + @NonNull + public static List<Geometry> parseGeometriesFromString(@NonNull String str) { + List<Geometry> geometries = new ArrayList<>(); + for (String geometryStr : str.split("\\s*;\\s*")) { + String[] geoParameters = geometryStr.split("\\s*\\|\\s*"); + switch (geoParameters[0]) { + case CIRCLE_SYMBOL: + geometries.add(new Circle(parseLatLngFromString(geoParameters[1]), + Double.parseDouble(geoParameters[2]))); + break; + case POLYGON_SYMBOL: + List<LatLng> vertices = new ArrayList<>(geoParameters.length - 1); + for (int i = 1; i < geoParameters.length; i++) { + vertices.add(parseLatLngFromString(geoParameters[i])); + } + geometries.add(new Polygon(vertices)); + break; + default: + Rlog.e(TAG, "Invalid geometry format " + geometryStr); + } + } + return geometries; + } + + /** + * Encode a list of geometry objects to string. The encoding format is specified by + * {@link android.provider.Telephony.CellBroadcasts#GEOMETRIES}. + * + * @param geometries the list of geometry objects need to be encoded. + * @return the encoded string. + */ + @NonNull + public static String encodeGeometriesToString(@NonNull List<Geometry> geometries) { + return geometries.stream() + .map(geometry -> encodeGeometryToString(geometry)) + .filter(encodedStr -> !TextUtils.isEmpty(encodedStr)) + .collect(Collectors.joining(";")); + } + + + /** + * Encode the geometry object to string. The encoding format is specified by + * {@link android.provider.Telephony.CellBroadcasts#GEOMETRIES}. + * @param geometry the geometry object need to be encoded. + * @return the encoded string. + */ + @NonNull + private static String encodeGeometryToString(@NonNull Geometry geometry) { + StringBuilder sb = new StringBuilder(); + if (geometry instanceof Polygon) { + sb.append(POLYGON_SYMBOL); + for (LatLng latLng : ((Polygon) geometry).getVertices()) { + sb.append("|"); + sb.append(latLng.lat); + sb.append(","); + sb.append(latLng.lng); + } + } else if (geometry instanceof Circle) { + sb.append(CIRCLE_SYMBOL); + Circle circle = (Circle) geometry; + + // Center + sb.append("|"); + sb.append(circle.getCenter().lat); + sb.append(","); + sb.append(circle.getCenter().lng); + + // Radius + sb.append("|"); + sb.append(circle.getRadius()); + } else { + Rlog.e(TAG, "Unsupported geometry object " + geometry); + return null; + } + return sb.toString(); + } + + /** + * Parse {@link LatLng} from {@link String}. Latitude and longitude are separated by ",". + * Example: "13.56,-55.447". + * + * @param str encoded lat/lng string. + * @Return {@link LatLng} object. + */ + @NonNull + public static LatLng parseLatLngFromString(@NonNull String str) { + String[] latLng = str.split("\\s*,\\s*"); + return new LatLng(Double.parseDouble(latLng[0]), Double.parseDouble(latLng[1])); + } + + /** + * @Return the sign of the given value {@code value} with the specified tolerance. Return 1 + * means the sign is positive, -1 means negative, 0 means the value will be treated as 0. + */ + public static int sign(double value) { + if (value > EPS) return 1; + if (value < -EPS) return -1; + return 0; + } +} diff --git a/tests/testables/src/android/testing/DexmakerShareClassLoaderRule.java b/tests/testables/src/android/testing/DexmakerShareClassLoaderRule.java index 1b8e58c3050d..7057a90c7672 100644 --- a/tests/testables/src/android/testing/DexmakerShareClassLoaderRule.java +++ b/tests/testables/src/android/testing/DexmakerShareClassLoaderRule.java @@ -20,6 +20,8 @@ import android.util.Log; import com.android.internal.annotations.VisibleForTesting; +import libcore.util.SneakyThrow; + import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; @@ -55,7 +57,11 @@ public class DexmakerShareClassLoaderRule implements TestRule { * WARNING: This is absolutely incompatible with running tests in parallel! */ public static void runWithDexmakerShareClassLoader(Runnable r) { - apply(r::run).run(); + try { + apply(r::run).run(); + } catch (Throwable t) { + SneakyThrow.sneakyThrow(t); + } } /** diff --git a/wifi/java/android/net/wifi/rtt/ResponderLocation.java b/wifi/java/android/net/wifi/rtt/ResponderLocation.java index e1d82f8d3a09..970a75d7c418 100644 --- a/wifi/java/android/net/wifi/rtt/ResponderLocation.java +++ b/wifi/java/android/net/wifi/rtt/ResponderLocation.java @@ -605,11 +605,11 @@ public final class ResponderLocation implements Parcelable { // Negative 2's complement value // Note: The Math.pow(...) method cannot return a NaN value because the bitFieldSize // for Lat or Lng is limited to exactly 34 bits. - angle = Math.scalb(fields[offset] - Math.pow(2, bitFieldSizes[offset]), + angle = Math.scalb((double) fields[offset] - Math.pow(2, bitFieldSizes[offset]), -LATLNG_FRACTION_BITS); } else { // Positive 2's complement value - angle = Math.scalb(fields[offset], -LATLNG_FRACTION_BITS); + angle = Math.scalb((double) fields[offset], -LATLNG_FRACTION_BITS); } if (angle > limit) { angle = limit; @@ -732,10 +732,11 @@ public final class ResponderLocation implements Parcelable { int maxBssidIndicator = (int) buffer[SUBELEMENT_BSSID_MAX_INDICATOR_INDEX] & BYTE_MASK; int bssidListLength = (buffer.length - 1) / BYTES_IN_A_BSSID; - // Check the max number of BSSIDs agrees with the list length. - if (maxBssidIndicator != bssidListLength) { - return false; - } + // The maxBSSIDIndicator is ignored. Its use is still being clarified in 802.11REVmd, + // which is not published at this time. This field will be used in a future + // release of Android after 802.11REVmd is public. Here, we interpret the following + // params as an explicit list of BSSIDs. + int bssidOffset = SUBELEMENT_BSSID_LIST_INDEX; for (int i = 0; i < bssidListLength; i++) { diff --git a/wifi/tests/src/android/net/wifi/rtt/ResponderLocationTest.java b/wifi/tests/src/android/net/wifi/rtt/ResponderLocationTest.java index 47c304097372..b02eebbe9a01 100644 --- a/wifi/tests/src/android/net/wifi/rtt/ResponderLocationTest.java +++ b/wifi/tests/src/android/net/wifi/rtt/ResponderLocationTest.java @@ -37,7 +37,7 @@ import java.util.List; */ @RunWith(JUnit4.class) public class ResponderLocationTest { - private static final double LATLNG_TOLERANCE_DEGREES = 0.00001; + private static final double LATLNG_TOLERANCE_DEGREES = 0.000_000_05D; // 5E-8 = 6mm of meridian private static final double ALT_TOLERANCE_METERS = 0.01; private static final double HEIGHT_TOLERANCE_METERS = 0.01; private static final int INDEX_ELEMENT_TYPE = 2; @@ -103,7 +103,7 @@ public class ResponderLocationTest { private static final byte[] sTestBssidListSE = { (byte) 0x07, // Subelement BSSID list (byte) 13, // length dependent on number of BSSIDs in list - (byte) 0x02, // Number of BSSIDs in list + (byte) 0x00, // List is explicit; no expansion of list required (byte) 0x01, // BSSID #1 (MSB) (byte) 0x02, (byte) 0x03, @@ -266,11 +266,11 @@ public class ResponderLocationTest { assertTrue(valid); assertTrue(lciValid); assertFalse(zValid); - assertEquals(0.0009765625, responderLocation.getLatitudeUncertainty()); - assertEquals(-33.857009, responderLocation.getLatitude(), + assertEquals(0.0009765625D, responderLocation.getLatitudeUncertainty()); + assertEquals(-33.8570095D, responderLocation.getLatitude(), LATLNG_TOLERANCE_DEGREES); - assertEquals(0.0009765625, responderLocation.getLongitudeUncertainty()); - assertEquals(151.215200, responderLocation.getLongitude(), + assertEquals(0.0009765625D, responderLocation.getLongitudeUncertainty()); + assertEquals(151.2152005D, responderLocation.getLongitude(), LATLNG_TOLERANCE_DEGREES); assertEquals(1, responderLocation.getAltitudeType()); assertEquals(64.0, responderLocation.getAltitudeUncertainty()); @@ -282,11 +282,11 @@ public class ResponderLocationTest { assertEquals(1, responderLocation.getLciVersion()); // Testing Location Object - assertEquals(-33.857009, location.getLatitude(), + assertEquals(-33.8570095D, location.getLatitude(), LATLNG_TOLERANCE_DEGREES); - assertEquals(151.215200, location.getLongitude(), + assertEquals(151.2152005D, location.getLongitude(), LATLNG_TOLERANCE_DEGREES); - assertEquals((0.0009765625 + 0.0009765625) / 2, location.getAccuracy(), + assertEquals((0.0009765625D + 0.0009765625D) / 2, location.getAccuracy(), LATLNG_TOLERANCE_DEGREES); assertEquals(11.2, location.getAltitude(), ALT_TOLERANCE_METERS); assertEquals(64.0, location.getVerticalAccuracyMeters(), ALT_TOLERANCE_METERS); |