diff options
451 files changed, 6850 insertions, 2157 deletions
diff --git a/cmds/incidentd/src/WorkDirectory.cpp b/cmds/incidentd/src/WorkDirectory.cpp index 0570c3a039ae..8dcb86537487 100644 --- a/cmds/incidentd/src/WorkDirectory.cpp +++ b/cmds/incidentd/src/WorkDirectory.cpp @@ -664,7 +664,7 @@ int64_t WorkDirectory::make_timestamp_ns_locked() { nanosleep(&spec, nullptr); } clock_gettime(CLOCK_REALTIME, &spec); - timestampNs = (spec.tv_sec) * 1000 + spec.tv_nsec; + timestampNs = int64_t(spec.tv_sec) * 1000 + spec.tv_nsec; } while (file_exists_locked(timestampNs)); return timestampNs; } diff --git a/cmds/statsd/src/main.cpp b/cmds/statsd/src/main.cpp index 68082c2dc4d2..42132ee0daae 100644 --- a/cmds/statsd/src/main.cpp +++ b/cmds/statsd/src/main.cpp @@ -78,7 +78,7 @@ int main(int /*argc*/, char** /*argv*/) { ps->giveThreadPoolName(); IPCThreadState::self()->disableBackgroundScheduling(true); - ::android::hardware::configureRpcThreadpool(1 /*threads*/, false /*willJoin*/); + ::android::hardware::configureRpcThreadpool(4 /*threads*/, false /*willJoin*/); std::shared_ptr<LogEventQueue> eventQueue = std::make_shared<LogEventQueue>(2000 /*buffer limit. Buffer is NOT pre-allocated*/); diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index f5b0b592e6a7..a0d0b30e65f7 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -146,6 +146,7 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -3656,6 +3657,22 @@ public class Activity extends ContextThemeWrapper return false; } + private static final class RequestFinishCallback extends IRequestFinishCallback.Stub { + private final WeakReference<Activity> mActivityRef; + + RequestFinishCallback(WeakReference<Activity> activityRef) { + mActivityRef = activityRef; + } + + @Override + public void requestFinish() { + Activity activity = mActivityRef.get(); + if (activity != null) { + activity.mHandler.post(activity::finishAfterTransition); + } + } + } + /** * Called when the activity has detected the user's press of the back * key. The default implementation simply finishes the current activity, @@ -3681,11 +3698,7 @@ public class Activity extends ContextThemeWrapper // while at the root of the task. This call allows ActivityTaskManager // to intercept or defer finishing. ActivityTaskManager.getService().onBackPressedOnTaskRoot(mToken, - new IRequestFinishCallback.Stub() { - public void requestFinish() { - mHandler.post(() -> finishAfterTransition()); - } - }); + new RequestFinishCallback(new WeakReference<>(this))); } catch (RemoteException e) { finishAfterTransition(); } diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java index 3bf659b663b0..2b4ff0111ab3 100644 --- a/core/java/android/app/ActivityView.java +++ b/core/java/android/app/ActivityView.java @@ -120,7 +120,10 @@ public class ActivityView extends ViewGroup { mActivityTaskManager = ActivityTaskManager.getService(); mSurfaceView = new SurfaceView(context); - mSurfaceView.setAlpha(0f); + // Since ActivityView#getAlpha has been overridden, we should use parent class's alpha + // as master to synchronize surface view's alpha value. + mSurfaceView.setAlpha(super.getAlpha()); + mSurfaceView.setUseAlpha(); mSurfaceCallback = new SurfaceCallback(); mSurfaceView.getHolder().addCallback(mSurfaceCallback); addView(mSurfaceView); @@ -347,9 +350,20 @@ public class ActivityView extends ViewGroup { mSurfaceView.layout(0 /* left */, 0 /* top */, r - l /* right */, b - t /* bottom */); } + /** + * Sets the alpha value when the content of {@link SurfaceView} needs to show or hide. + * <p>Note: The surface view may ignore the alpha value in some cases. Refer to + * {@link SurfaceView#setAlpha} for more details. + * + * @param alpha The opacity of the view. + */ @Override public void setAlpha(float alpha) { - mSurfaceView.setAlpha(alpha); + super.setAlpha(alpha); + + if (mSurfaceView != null) { + mSurfaceView.setAlpha(alpha); + } } @Override diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl index e57738fbbfdd..9f51db88e7dc 100644 --- a/core/java/android/app/INotificationManager.aidl +++ b/core/java/android/app/INotificationManager.aidl @@ -108,6 +108,8 @@ interface INotificationManager ParceledListSlice getNotificationChannelsBypassingDnd(String pkg, int userId); boolean isPackagePaused(String pkg); + void silenceNotificationSound(); + // TODO: Remove this when callers have been migrated to the equivalent // INotificationListener method. @UnsupportedAppUsage diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java index dd39376f80ca..b13a34faab6b 100644 --- a/core/java/android/app/NotificationManager.java +++ b/core/java/android/app/NotificationManager.java @@ -1095,6 +1095,25 @@ public class NotificationManager { } /** + * Silences the current notification sound, if ones currently playing. + * <p> + * It is intended to handle use-cases such as silencing a ringing call + * when the user presses the volume button during ringing. + * <p> + * If this method is called prior to when the notification begins playing, the sound will not be + * silenced. As such it is not intended as a means to avoid playing of a sound. + * @hide + */ + public void silenceNotificationSound() { + INotificationManager service = getService(); + try { + service.silenceNotificationSound(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * Returns whether notifications from this package are temporarily hidden. This * could be done because the package was marked as distracting to the user via * {@code PackageManager#setDistractingPackageRestrictions(String[], int)} or because the diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index d32b6b516a7d..fe4b0d52b133 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -1162,7 +1162,8 @@ final class SystemServiceRegistry { @Override public AppPredictionManager createService(ContextImpl ctx) throws ServiceNotFoundException { - return new AppPredictionManager(ctx); + IBinder b = ServiceManager.getService(Context.APP_PREDICTION_SERVICE); + return b == null ? null : new AppPredictionManager(ctx); } }); diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 658c9b4ff43e..414cc39f5310 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -4111,6 +4111,9 @@ public abstract class Context { /** * Official published name of the app prediction service. * + * <p><b>NOTE: </b> this service is optional; callers of + * {@code Context.getSystemServiceName(APP_PREDICTION_SERVICE)} should check for {@code null}. + * * @hide * @see #getSystemService(String) */ diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index a7eecd7f4306..abcf77b64b87 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -44,6 +44,7 @@ import android.content.pm.PermissionGroupInfo; import android.content.pm.PermissionInfo; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; +import android.content.pm.permission.SplitPermissionInfoParcelable; import android.content.pm.SuspendDialogInfo; import android.content.pm.UserInfo; import android.content.pm.VerifierDeviceIdentity; @@ -772,4 +773,6 @@ interface IPackageManager { void setRuntimePermissionsVersion(int version, int userId); void notifyPackagesReplacedReceived(in String[] packages); + + List<SplitPermissionInfoParcelable> getSplitPermissions(); } diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index b3776787cc2b..535a8bc9db75 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -57,6 +57,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageParserCacheHelper.ReadHelper; import android.content.pm.PackageParserCacheHelper.WriteHelper; +import android.content.pm.permission.SplitPermissionInfoParcelable; import android.content.pm.split.DefaultSplitAssetLoader; import android.content.pm.split.SplitAssetDependencyLoader; import android.content.pm.split.SplitAssetLoader; @@ -104,6 +105,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.ClassLoaderFactory; import com.android.internal.util.ArrayUtils; import com.android.internal.util.XmlUtils; +import com.android.server.SystemConfig; import libcore.io.IoUtils; import libcore.util.EmptyArray; @@ -2482,11 +2484,10 @@ public class PackageParser { Slog.i(TAG, newPermsMsg.toString()); } - - final int NS = PermissionManager.SPLIT_PERMISSIONS.size(); - for (int is=0; is<NS; is++) { - final PermissionManager.SplitPermissionInfo spi = - PermissionManager.SPLIT_PERMISSIONS.get(is); + List<SplitPermissionInfoParcelable> splitPermissions = getSplitPermissions(); + final int listSize = splitPermissions.size(); + for (int is = 0; is < listSize; is++) { + final SplitPermissionInfoParcelable spi = splitPermissions.get(is); if (pkg.applicationInfo.targetSdkVersion >= spi.getTargetSdk() || !pkg.requestedPermissions.contains(spi.getSplitPermission())) { continue; @@ -2540,6 +2541,23 @@ public class PackageParser { return pkg; } + private List<SplitPermissionInfoParcelable> getSplitPermissions() { + // PackageManager runs this code during initialization prior to registering with + // ServiceManager, so we can't use the PackageManager API. Instead, just read from + // SystemConfig directly when in any SystemProcess and only use PackageManager when not in + // one. + if (ActivityThread.isSystem()) { + return PermissionManager.splitPermissionInfoListToParcelableList( + SystemConfig.getInstance().getSplitPermissions()); + } else { + try { + return ActivityThread.getPackageManager().getSplitPermissions(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + } + private boolean checkOverlayRequiredSystemProperty(String propName, String propValue) { if (TextUtils.isEmpty(propName) || TextUtils.isEmpty(propValue)) { diff --git a/core/java/android/content/pm/permission/SplitPermissionInfoParcelable.aidl b/core/java/android/content/pm/permission/SplitPermissionInfoParcelable.aidl new file mode 100644 index 000000000000..d84454ce744b --- /dev/null +++ b/core/java/android/content/pm/permission/SplitPermissionInfoParcelable.aidl @@ -0,0 +1,19 @@ +/** + * 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 android.content.pm.permission; + + parcelable SplitPermissionInfoParcelable;
\ No newline at end of file diff --git a/core/java/android/content/pm/permission/SplitPermissionInfoParcelable.java b/core/java/android/content/pm/permission/SplitPermissionInfoParcelable.java new file mode 100644 index 000000000000..6537fbc37398 --- /dev/null +++ b/core/java/android/content/pm/permission/SplitPermissionInfoParcelable.java @@ -0,0 +1,178 @@ +/* + * 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 android.content.pm.permission; + +import android.annotation.IntRange; +import android.annotation.NonNull; +import android.os.Parcel; +import android.os.Parcelable; + +import com.android.internal.util.Preconditions; + +import java.util.List; +import java.util.Objects; + +/** + * Parcelable version of {@link android.permission.PermissionManager.SplitPermissionInfo} + * @hide + */ +public class SplitPermissionInfoParcelable implements Parcelable { + + /** + * The permission that is split. + */ + @NonNull + private final String mSplitPermission; + + /** + * The permissions that are added. + */ + @NonNull + private final List<String> mNewPermissions; + + /** + * The target API level when the permission was split. + */ + @IntRange(from = 0) + private final int mTargetSdk; + + private void onConstructed() { + Preconditions.checkCollectionElementsNotNull(mNewPermissions, "newPermissions"); + } + + + + // Code below generated by codegen v1.0.0. + // + // DO NOT MODIFY! + // + // To regenerate run: + // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/content/pm/SplitPermissionInfoParcelable.java + // + // CHECKSTYLE:OFF Generated code + + /** + * Creates a new SplitPermissionInfoParcelable. + * + * @param splitPermission + * The permission that is split. + * @param newPermissions + * The permissions that are added. + * @param targetSdk + * The target API level when the permission was split. + */ + public SplitPermissionInfoParcelable( + @NonNull String splitPermission, + @NonNull List<String> newPermissions, + @IntRange(from = 0) int targetSdk) { + this.mSplitPermission = splitPermission; + Preconditions.checkNotNull(mSplitPermission); + this.mNewPermissions = newPermissions; + Preconditions.checkNotNull(mNewPermissions); + this.mTargetSdk = targetSdk; + Preconditions.checkArgumentNonnegative(mTargetSdk); + + onConstructed(); + } + + /** + * The permission that is split. + */ + public @NonNull String getSplitPermission() { + return mSplitPermission; + } + + /** + * The permissions that are added. + */ + public @NonNull List<String> getNewPermissions() { + return mNewPermissions; + } + + /** + * The target API level when the permission was split. + */ + public @IntRange(from = 0) int getTargetSdk() { + return mTargetSdk; + } + + @Override + public boolean equals(Object o) { + // You can override field equality logic by defining either of the methods like: + // boolean fieldNameEquals(SplitPermissionInfoParcelable other) { ... } + // boolean fieldNameEquals(FieldType otherValue) { ... } + + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + @SuppressWarnings("unchecked") + SplitPermissionInfoParcelable that = (SplitPermissionInfoParcelable) o; + //noinspection PointlessBooleanExpression + return true + && Objects.equals(mSplitPermission, that.mSplitPermission) + && Objects.equals(mNewPermissions, that.mNewPermissions) + && mTargetSdk == that.mTargetSdk; + } + + @Override + public int hashCode() { + // You can override field hashCode logic by defining methods like: + // int fieldNameHashCode() { ... } + + int _hash = 1; + _hash = 31 * _hash + Objects.hashCode(mSplitPermission); + _hash = 31 * _hash + Objects.hashCode(mNewPermissions); + _hash = 31 * _hash + mTargetSdk; + return _hash; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + // You can override field parcelling by defining methods like: + // void parcelFieldName(Parcel dest, int flags) { ... } + + dest.writeString(mSplitPermission); + dest.writeStringList(mNewPermissions); + dest.writeInt(mTargetSdk); + } + + @Override + public int describeContents() { return 0; } + + public static final @NonNull Parcelable.Creator<SplitPermissionInfoParcelable> CREATOR + = new Parcelable.Creator<SplitPermissionInfoParcelable>() { + @Override + public SplitPermissionInfoParcelable[] newArray(int size) { + return new SplitPermissionInfoParcelable[size]; + } + + @Override + @SuppressWarnings({"unchecked", "RedundantCast"}) + public SplitPermissionInfoParcelable createFromParcel(Parcel in) { + // You can override field unparcelling by defining methods like: + // static FieldType unparcelFieldName(Parcel in) { ... } + + String splitPermission = in.readString(); + List<String> newPermissions = new java.util.ArrayList<>(); + in.readStringList(newPermissions); + int targetSdk = in.readInt(); + return new SplitPermissionInfoParcelable( + splitPermission, + newPermissions, + targetSdk); + } + }; +} diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java index 5ac13d8a067d..a0170dab9f04 100644 --- a/core/java/android/hardware/camera2/CameraMetadata.java +++ b/core/java/android/hardware/camera2/CameraMetadata.java @@ -206,10 +206,16 @@ public abstract class CameraMetadata<TKey> { continue; } - if (filterTags == null || Arrays.binarySearch(filterTags, - CameraMetadataNative.getTag(keyName, vendorId)) >= 0) { + + if (filterTags != null && Arrays.binarySearch(filterTags, + CameraMetadataNative.getTag(keyName, vendorId)) < 0) { + // ignore vendor keys not in filterTags + continue; + } + if (instance == null || instance.getProtected(k) != null) { keyList.add(k); } + } } diff --git a/core/java/android/hardware/radio/TunerAdapter.java b/core/java/android/hardware/radio/TunerAdapter.java index be2846f87079..aa5480abafb4 100644 --- a/core/java/android/hardware/radio/TunerAdapter.java +++ b/core/java/android/hardware/radio/TunerAdapter.java @@ -271,6 +271,8 @@ class TunerAdapter extends RadioTuner { mCallback.setProgramListObserver(list, () -> { try { mTuner.stopProgramListUpdates(); + } catch (IllegalStateException ex) { + // it's fine to not stop updates if tuner is already closed } catch (RemoteException ex) { Log.e(TAG, "Couldn't stop program list updates", ex); } 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/inputmethodservice/SoftInputWindow.java b/core/java/android/inputmethodservice/SoftInputWindow.java index 0513feef801f..356b3448430a 100644 --- a/core/java/android/inputmethodservice/SoftInputWindow.java +++ b/core/java/android/inputmethodservice/SoftInputWindow.java @@ -21,6 +21,7 @@ import static java.lang.annotation.RetentionPolicy.SOURCE; import android.annotation.IntDef; import android.app.Dialog; import android.content.Context; +import android.content.pm.PackageManager; import android.graphics.Rect; import android.os.Debug; import android.os.IBinder; @@ -50,6 +51,7 @@ public class SoftInputWindow extends Dialog { final int mWindowType; final int mGravity; final boolean mTakesFocus; + final boolean mAutomotiveHideNavBarForKeyboard; private final Rect mBounds = new Rect(); @Retention(SOURCE) @@ -134,6 +136,8 @@ public class SoftInputWindow extends Dialog { mWindowType = windowType; mGravity = gravity; mTakesFocus = takesFocus; + mAutomotiveHideNavBarForKeyboard = context.getResources().getBoolean( + com.android.internal.R.bool.config_automotiveHideNavBarForKeyboard); initDockWindow(); } @@ -247,6 +251,11 @@ public class SoftInputWindow extends Dialog { windowModFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; } + if (isAutomotive() && mAutomotiveHideNavBarForKeyboard) { + windowSetFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; + windowModFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; + } + getWindow().setFlags(windowSetFlags, windowModFlags); } @@ -338,6 +347,10 @@ public class SoftInputWindow extends Dialog { mWindowState = newState; } + private boolean isAutomotive() { + return getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE); + } + private static String stateToString(@SoftInputWindowState int state) { switch (state) { case SoftInputWindowState.TOKEN_PENDING: diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index 00d522bae27f..ecd16dd1f612 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -266,8 +266,11 @@ public abstract class BatteryStats implements Parcelable { * - Fixed bug in min learned capacity updating process. * New in version 34: * - Deprecated STATS_SINCE_UNPLUGGED and STATS_CURRENT. + * New in version 35: + * - Fixed bug that was not reporting high cellular tx power correctly + * - Added out of service and emergency service modes to data connection types */ - static final int CHECKIN_VERSION = 34; + static final int CHECKIN_VERSION = 35; /** * Old version, we hit 9 and ran out of room, need to remove. @@ -2371,18 +2374,21 @@ public abstract class BatteryStats implements Parcelable { */ public abstract int getMobileRadioActiveUnknownCount(int which); - public static final int DATA_CONNECTION_NONE = 0; - public static final int DATA_CONNECTION_OTHER = TelephonyManager.MAX_NETWORK_TYPE + 1; + public static final int DATA_CONNECTION_OUT_OF_SERVICE = 0; + public static final int DATA_CONNECTION_EMERGENCY_SERVICE = + TelephonyManager.MAX_NETWORK_TYPE + 1; + public static final int DATA_CONNECTION_OTHER = DATA_CONNECTION_EMERGENCY_SERVICE + 1; + static final String[] DATA_CONNECTION_NAMES = { - "none", "gprs", "edge", "umts", "cdma", "evdo_0", "evdo_A", + "oos", "gprs", "edge", "umts", "cdma", "evdo_0", "evdo_A", "1xrtt", "hsdpa", "hsupa", "hspa", "iden", "evdo_b", "lte", "ehrpd", "hspap", "gsm", "td_scdma", "iwlan", "lte_ca", "nr", - "other" + "emngcy", "other" }; @UnsupportedAppUsage - public static final int NUM_DATA_CONNECTION_TYPES = DATA_CONNECTION_OTHER+1; + public static final int NUM_DATA_CONNECTION_TYPES = DATA_CONNECTION_OTHER + 1; /** * Returns the time in microseconds that the phone has been running with @@ -6564,6 +6570,10 @@ public abstract class BatteryStats implements Parcelable { } oldState = rec.states; oldState2 = rec.states2; + // Clear High Tx Power Flag for volta positioning + if ((rec.states2 & HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG) != 0) { + rec.states2 &= ~HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG; + } } return item.toString(); @@ -7865,9 +7875,9 @@ public abstract class BatteryStats implements Parcelable { // Phone data connection (DATA_CONNECTION_TIME_DATA and DATA_CONNECTION_COUNT_DATA) for (int i = 0; i < NUM_DATA_CONNECTION_TYPES; ++i) { // Map OTHER to TelephonyManager.NETWORK_TYPE_UNKNOWN and mark NONE as a boolean. - boolean isNone = (i == DATA_CONNECTION_NONE); + boolean isNone = (i == DATA_CONNECTION_OUT_OF_SERVICE); int telephonyNetworkType = i; - if (i == DATA_CONNECTION_OTHER) { + if (i == DATA_CONNECTION_OTHER || i == DATA_CONNECTION_EMERGENCY_SERVICE) { telephonyNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN; } final long pdcToken = proto.start(SystemProto.DATA_CONNECTION); 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/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java index 182a2ffa5221..2934c5dff858 100644 --- a/core/java/android/permission/PermissionManager.java +++ b/core/java/android/permission/PermissionManager.java @@ -25,14 +25,15 @@ import android.annotation.SystemService; import android.annotation.TestApi; import android.content.Context; import android.content.pm.IPackageManager; +import android.content.pm.permission.SplitPermissionInfoParcelable; import android.os.RemoteException; +import android.util.Log; import com.android.internal.annotations.Immutable; -import com.android.server.SystemConfig; import java.util.ArrayList; +import java.util.Collections; import java.util.List; -import java.util.Objects; /** * System level service for accessing the permission capabilities of the platform. @@ -43,18 +44,14 @@ import java.util.Objects; @SystemApi @SystemService(Context.PERMISSION_SERVICE) public final class PermissionManager { - /** - * {@link android.content.pm.PackageParser} needs access without having a {@link Context}. - * - * @hide - */ - public static final ArrayList<SplitPermissionInfo> SPLIT_PERMISSIONS = - SystemConfig.getInstance().getSplitPermissions(); + private static final String TAG = PermissionManager.class.getName(); private final @NonNull Context mContext; private final IPackageManager mPackageManager; + private List<SplitPermissionInfo> mSplitPermissionInfos; + /** * Creates a new instance. * @@ -122,7 +119,48 @@ public final class PermissionManager { * @return All permissions that are split. */ public @NonNull List<SplitPermissionInfo> getSplitPermissions() { - return SPLIT_PERMISSIONS; + if (mSplitPermissionInfos != null) { + return mSplitPermissionInfos; + } + + List<SplitPermissionInfoParcelable> parcelableList; + try { + parcelableList = mPackageManager.getSplitPermissions(); + } catch (RemoteException e) { + Log.w(TAG, "Error getting split permissions", e); + return Collections.emptyList(); + } + + mSplitPermissionInfos = splitPermissionInfoListToNonParcelableList(parcelableList); + + return mSplitPermissionInfos; + } + + private List<SplitPermissionInfo> splitPermissionInfoListToNonParcelableList( + List<SplitPermissionInfoParcelable> parcelableList) { + final int size = parcelableList.size(); + List<SplitPermissionInfo> list = new ArrayList<>(size); + for (int i = 0; i < size; i++) { + list.add(new SplitPermissionInfo(parcelableList.get(i))); + } + return list; + } + + /** + * Converts a {@link List} of {@link SplitPermissionInfo} into a List of + * {@link SplitPermissionInfoParcelable} and returns it. + * @hide + */ + public static List<SplitPermissionInfoParcelable> splitPermissionInfoListToParcelableList( + List<SplitPermissionInfo> splitPermissionsList) { + final int size = splitPermissionsList.size(); + List<SplitPermissionInfoParcelable> outList = new ArrayList<>(size); + for (int i = 0; i < size; i++) { + SplitPermissionInfo info = splitPermissionsList.get(i); + outList.add(new SplitPermissionInfoParcelable( + info.getSplitPermission(), info.getNewPermissions(), info.getTargetSdk())); + } + return outList; } /** @@ -131,44 +169,40 @@ public final class PermissionManager { */ @Immutable public static final class SplitPermissionInfo { - private final @NonNull String mSplitPerm; - private final @NonNull List<String> mNewPerms; - private final int mTargetSdk; + private @NonNull final SplitPermissionInfoParcelable mSplitPermissionInfoParcelable; @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; SplitPermissionInfo that = (SplitPermissionInfo) o; - return mTargetSdk == that.mTargetSdk - && mSplitPerm.equals(that.mSplitPerm) - && mNewPerms.equals(that.mNewPerms); + return mSplitPermissionInfoParcelable.equals(that.mSplitPermissionInfoParcelable); } @Override public int hashCode() { - return Objects.hash(mSplitPerm, mNewPerms, mTargetSdk); + return mSplitPermissionInfoParcelable.hashCode(); } /** * Get the permission that is split. */ public @NonNull String getSplitPermission() { - return mSplitPerm; + return mSplitPermissionInfoParcelable.getSplitPermission(); } /** * Get the permissions that are added. */ public @NonNull List<String> getNewPermissions() { - return mNewPerms; + return mSplitPermissionInfoParcelable.getNewPermissions(); } /** * Get the target API level when the permission was split. */ public int getTargetSdk() { - return mTargetSdk; + return mSplitPermissionInfoParcelable.getTargetSdk(); } /** @@ -182,9 +216,11 @@ public final class PermissionManager { */ public SplitPermissionInfo(@NonNull String splitPerm, @NonNull List<String> newPerms, int targetSdk) { - mSplitPerm = splitPerm; - mNewPerms = newPerms; - mTargetSdk = targetSdk; + this(new SplitPermissionInfoParcelable(splitPerm, newPerms, targetSdk)); + } + + private SplitPermissionInfo(@NonNull SplitPermissionInfoParcelable parcelable) { + mSplitPermissionInfoParcelable = parcelable; } } } diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java index cb7d41bdf21a..93bcdbffd133 100644 --- a/core/java/android/service/notification/ZenModeConfig.java +++ b/core/java/android/service/notification/ZenModeConfig.java @@ -1639,7 +1639,7 @@ public class ZenModeConfig implements Parcelable { @UnsupportedAppUsage public String name; // required for automatic @UnsupportedAppUsage - public int zenMode; + public int zenMode; // ie: Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS @UnsupportedAppUsage public Uri conditionId; // required for automatic public Condition condition; // optional 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/GestureExclusionTracker.java b/core/java/android/view/GestureExclusionTracker.java index 6fcdd714f827..fffb323e6d50 100644 --- a/core/java/android/view/GestureExclusionTracker.java +++ b/core/java/android/view/GestureExclusionTracker.java @@ -44,7 +44,7 @@ class GestureExclusionTracker { while (i.hasNext()) { final GestureExclusionViewInfo info = i.next(); final View v = info.getView(); - if (v == null || !v.isAttachedToWindow()) { + if (v == null || !v.isAttachedToWindow() || !v.isAggregatedVisible()) { mGestureExclusionViewsChanged = true; i.remove(); continue; @@ -122,7 +122,8 @@ class GestureExclusionTracker { public int update() { final View excludedView = getView(); - if (excludedView == null || !excludedView.isAttachedToWindow()) return GONE; + if (excludedView == null || !excludedView.isAttachedToWindow() + || !excludedView.isAggregatedVisible()) return GONE; final List<Rect> localRects = excludedView.getSystemGestureExclusionRects(); final List<Rect> newRects = new ArrayList<>(localRects.size()); for (Rect src : localRects) { diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 254d04e8715d..85ea3d334d7c 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -100,6 +100,7 @@ import java.util.concurrent.locks.ReentrantLock; public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallback { private static final String TAG = "SurfaceView"; private static final boolean DEBUG = false; + private static final boolean DEBUG_POSITION = false; @UnsupportedAppUsage final ArrayList<SurfaceHolder.Callback> mCallbacks @@ -126,6 +127,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb // we need to preserve the old one until the new one has drawn. SurfaceControl mDeferredDestroySurfaceControl; SurfaceControl mBackgroundControl; + final Object mSurfaceControlLock = new Object(); final Rect mTmpRect = new Rect(); final Configuration mConfiguration = new Configuration(); @@ -173,6 +175,9 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb @UnsupportedAppUsage int mRequestedFormat = PixelFormat.RGB_565; + boolean mUseAlpha = false; + float mSurfaceAlpha = 1f; + @UnsupportedAppUsage boolean mHaveFrame = false; boolean mSurfaceCreated = false; @@ -200,6 +205,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb private int mPendingReportDraws; private SurfaceControl.Transaction mRtTransaction = new SurfaceControl.Transaction(); + private SurfaceControl.Transaction mTmpTransaction = new SurfaceControl.Transaction(); public SurfaceView(Context context) { this(context, null); @@ -288,6 +294,152 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb updateSurface(); } + /** + * Make alpha value of this view reflect onto the surface. This can only be called from at most + * one SurfaceView within a view tree. + * + * <p class="note"><strong>Note:</strong> Alpha value of the view is ignored and the underlying + * surface is rendered opaque by default.</p> + * + * @hide + */ + public void setUseAlpha() { + if (!mUseAlpha) { + mUseAlpha = true; + updateSurfaceAlpha(); + } + } + + @Override + public void setAlpha(float alpha) { + // Sets the opacity of the view to a value, where 0 means the view is completely transparent + // and 1 means the view is completely opaque. + // + // Note: Alpha value of this view is ignored by default. To enable alpha blending, you need + // to call setUseAlpha() as well. + // This view doesn't support translucent opacity if the view is located z-below, since the + // logic to punch a hole in the view hierarchy cannot handle such case. See also + // #clearSurfaceViewPort(Canvas) + if (DEBUG) { + Log.d(TAG, System.identityHashCode(this) + + " setAlpha: mUseAlpha = " + mUseAlpha + " alpha=" + alpha); + } + super.setAlpha(alpha); + updateSurfaceAlpha(); + } + + private float getFixedAlpha() { + // Compute alpha value to be set on the underlying surface. + final float alpha = getAlpha(); + return mUseAlpha && (mSubLayer > 0 || alpha == 0f) ? alpha : 1f; + } + + private void updateSurfaceAlpha() { + if (!mUseAlpha) { + if (DEBUG) { + Log.d(TAG, System.identityHashCode(this) + + " updateSurfaceAlpha: setUseAlpha() is not called, ignored."); + } + return; + } + final float viewAlpha = getAlpha(); + if (mSubLayer < 0 && 0f < viewAlpha && viewAlpha < 1f) { + Log.w(TAG, System.identityHashCode(this) + + " updateSurfaceAlpha:" + + " translucent color is not supported for a surface placed z-below."); + } + if (!mHaveFrame) { + if (DEBUG) { + Log.d(TAG, System.identityHashCode(this) + + " updateSurfaceAlpha: has no surface."); + } + return; + } + final ViewRootImpl viewRoot = getViewRootImpl(); + if (viewRoot == null) { + if (DEBUG) { + Log.d(TAG, System.identityHashCode(this) + + " updateSurfaceAlpha: ViewRootImpl not available."); + } + return; + } + if (mSurfaceControl == null) { + if (DEBUG) { + Log.d(TAG, System.identityHashCode(this) + + "updateSurfaceAlpha:" + + " surface is not yet created, or already released."); + } + return; + } + final Surface parent = viewRoot.mSurface; + if (parent == null || !parent.isValid()) { + if (DEBUG) { + Log.d(TAG, System.identityHashCode(this) + + " updateSurfaceAlpha: ViewRootImpl has no valid surface"); + } + return; + } + final float alpha = getFixedAlpha(); + if (alpha != mSurfaceAlpha) { + if (isHardwareAccelerated()) { + /* + * Schedule a callback that reflects an alpha value onto the underlying surfaces. + * This gets called on a RenderThread worker thread, so members accessed here must + * be protected by a lock. + */ + viewRoot.registerRtFrameCallback(frame -> { + try { + final SurfaceControl.Transaction t = new SurfaceControl.Transaction(); + synchronized (mSurfaceControlLock) { + if (!parent.isValid()) { + if (DEBUG) { + Log.d(TAG, System.identityHashCode(this) + + " updateSurfaceAlpha RT:" + + " ViewRootImpl has no valid surface"); + } + return; + } + if (mSurfaceControl == null) { + if (DEBUG) { + Log.d(TAG, System.identityHashCode(this) + + "updateSurfaceAlpha RT:" + + " mSurfaceControl has already released"); + } + return; + } + if (DEBUG) { + Log.d(TAG, System.identityHashCode(this) + + " updateSurfaceAlpha RT: set alpha=" + alpha); + } + t.setAlpha(mSurfaceControl, alpha); + t.deferTransactionUntilSurface(mSurfaceControl, parent, frame); + } + // It's possible that mSurfaceControl is released in the UI thread before + // the transaction completes. If that happens, an exception is thrown, which + // must be caught immediately. + t.apply(); + } catch (Exception e) { + Log.e(TAG, System.identityHashCode(this) + + "updateSurfaceAlpha RT: Exception during surface transaction", e); + } + }); + damageInParent(); + } else { + if (DEBUG) { + Log.d(TAG, System.identityHashCode(this) + + " updateSurfaceAlpha: set alpha=" + alpha); + } + SurfaceControl.openTransaction(); + try { + mSurfaceControl.setAlpha(alpha); + } finally { + SurfaceControl.closeTransaction(); + } + } + mSurfaceAlpha = alpha; + } + } + private void performDrawFinished() { if (mPendingReportDraws > 0) { mDrawFinished = true; @@ -337,11 +489,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb mRequestedVisible = false; updateSurface(); - if (mSurfaceControl != null) { - mSurfaceControl.remove(); - } - mSurfaceControl = null; - + releaseSurfaces(); mHaveFrame = false; super.onDetachedFromWindow(); @@ -510,15 +658,6 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb } } - private Rect getParentSurfaceInsets() { - final ViewRootImpl root = getViewRootImpl(); - if (root == null) { - return null; - } else { - return root.mWindowAttributes.surfaceInsets; - } - } - private void updateBackgroundVisibilityInTransaction(SurfaceControl viewRoot) { if (mBackgroundControl == null) { return; @@ -532,23 +671,34 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb } private void releaseSurfaces() { - if (mSurfaceControl != null) { - mSurfaceControl.remove(); - mSurfaceControl = null; - } - if (mBackgroundControl != null) { - mBackgroundControl.remove(); - mBackgroundControl = null; + synchronized (mSurfaceControlLock) { + if (mSurfaceControl != null) { + mTmpTransaction.remove(mSurfaceControl); + mSurfaceControl = null; + } + if (mBackgroundControl != null) { + mTmpTransaction.remove(mBackgroundControl); + mBackgroundControl = null; + } + mTmpTransaction.apply(); } + mSurfaceAlpha = 1f; } /** @hide */ protected void updateSurface() { if (!mHaveFrame) { + if (DEBUG) { + Log.d(TAG, System.identityHashCode(this) + " updateSurface: has no frame"); + } return; } ViewRootImpl viewRoot = getViewRootImpl(); if (viewRoot == null || viewRoot.mSurface == null || !viewRoot.mSurface.isValid()) { + if (DEBUG) { + Log.d(TAG, System.identityHashCode(this) + + " updateSurface: no valid surface"); + } return; } @@ -562,20 +712,25 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb int myHeight = mRequestedHeight; if (myHeight <= 0) myHeight = getHeight(); + final float alpha = getFixedAlpha(); final boolean formatChanged = mFormat != mRequestedFormat; final boolean visibleChanged = mVisible != mRequestedVisible; + final boolean alphaChanged = mSurfaceAlpha != alpha; final boolean creating = (mSurfaceControl == null || formatChanged || visibleChanged) && mRequestedVisible; final boolean sizeChanged = mSurfaceWidth != myWidth || mSurfaceHeight != myHeight; final boolean windowVisibleChanged = mWindowVisibility != mLastWindowVisibility; boolean redrawNeeded = false; - if (creating || formatChanged || sizeChanged || visibleChanged || windowVisibleChanged) { + if (creating || formatChanged || sizeChanged || visibleChanged || (mUseAlpha + && alphaChanged) || windowVisibleChanged) { getLocationInWindow(mLocation); if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " " + "Changes: creating=" + creating + " format=" + formatChanged + " size=" + sizeChanged + + " visible=" + visibleChanged + " alpha=" + alphaChanged + + " mUseAlpha=" + mUseAlpha + " visible=" + visibleChanged + " left=" + (mWindowSpaceLeft != mLocation[0]) + " top=" + (mWindowSpaceTop != mLocation[1])); @@ -597,7 +752,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb mTranslator.translateRectInAppWindowToScreen(mScreenRect); } - final Rect surfaceInsets = getParentSurfaceInsets(); + final Rect surfaceInsets = viewRoot.mWindowAttributes.surfaceInsets; mScreenRect.offset(surfaceInsets.left, surfaceInsets.top); if (creating) { @@ -646,6 +801,10 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb mSurfaceControl.hide(); } updateBackgroundVisibilityInTransaction(viewRoot.getSurfaceControl()); + if (mUseAlpha) { + mSurfaceControl.setAlpha(alpha); + mSurfaceAlpha = alpha; + } // While creating the surface, we will set it's initial // geometry. Outside of that though, we should generally @@ -788,7 +947,6 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb mIsCreating = false; if (mSurfaceControl != null && !mSurfaceCreated) { mSurface.release(); - releaseSurfaces(); } } @@ -828,10 +986,13 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb if (!isHardwareAccelerated() || !mRtHandlingPositionUpdates) { try { - if (DEBUG) Log.d(TAG, String.format("%d updateSurfacePosition UI, " + - "postion = [%d, %d, %d, %d]", System.identityHashCode(this), - mScreenRect.left, mScreenRect.top, - mScreenRect.right, mScreenRect.bottom)); + if (DEBUG_POSITION) { + Log.d(TAG, String.format("%d updateSurfacePosition UI, " + + "position = [%d, %d, %d, %d]", + System.identityHashCode(this), + mScreenRect.left, mScreenRect.top, + mScreenRect.right, mScreenRect.bottom)); + } setParentSpaceRectangle(mScreenRect, -1); } catch (Exception ex) { Log.e(TAG, "Exception configuring surface", ex); @@ -884,7 +1045,6 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb if (mViewVisibility) { mRtTransaction.show(surface); } - } private void setParentSpaceRectangle(Rect position, long frameNumber) { @@ -925,7 +1085,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb return; } try { - if (DEBUG) { + if (DEBUG_POSITION) { Log.d(TAG, String.format( "%d updateSurfacePosition RenderWorker, frameNr = %d, " + "postion = [%d, %d, %d, %d]", diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 4e86e60fdd62..84665f78c702 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -14344,6 +14344,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** + * @return true if this view and all ancestors are visible as of the last + * {@link #onVisibilityAggregated(boolean)} call. + */ + boolean isAggregatedVisible() { + return (mPrivateFlags3 & PFLAG3_AGGREGATED_VISIBLE) != 0; + } + + /** * Internal dispatching method for {@link #onVisibilityAggregated}. Overridden by * ViewGroup. Intended to only be called when {@link #isAttachedToWindow()}, * {@link #getWindowVisibility()} is {@link #VISIBLE} and this view's parent {@link #isShown()}. @@ -14371,7 +14379,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, @CallSuper public void onVisibilityAggregated(boolean isVisible) { // Update our internal visibility tracking so we can detect changes - boolean oldVisible = (mPrivateFlags3 & PFLAG3_AGGREGATED_VISIBLE) != 0; + boolean oldVisible = isAggregatedVisible(); mPrivateFlags3 = isVisible ? (mPrivateFlags3 | PFLAG3_AGGREGATED_VISIBLE) : (mPrivateFlags3 & ~PFLAG3_AGGREGATED_VISIBLE); if (isVisible && mAttachInfo != null) { @@ -14423,6 +14431,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } notifyAppearedOrDisappearedForContentCaptureIfNeeded(isVisible); + if (isVisible != oldVisible) { + updateSystemGestureExclusionRects(); + } } /** diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index 2e5a7501f898..36fea589da99 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -1473,6 +1473,9 @@ public interface WindowManager extends ViewManager { * <p>When this flag is enabled for a window, it automatically sets * the system UI visibility flags {@link View#SYSTEM_UI_FLAG_LAYOUT_STABLE} and * {@link View#SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}.</p> + * + * <p>Note: For devices that support + * {@link android.content.pm.PackageManager#FEATURE_AUTOMOTIVE} this flag may be ignored. */ public static final int FLAG_TRANSLUCENT_STATUS = 0x04000000; @@ -1492,6 +1495,10 @@ public interface WindowManager extends ViewManager { * <p>When this flag is enabled for a window, it automatically sets * the system UI visibility flags {@link View#SYSTEM_UI_FLAG_LAYOUT_STABLE} and * {@link View#SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION}.</p> + * + * <p>Note: For devices that support + * {@link android.content.pm.PackageManager#FEATURE_AUTOMOTIVE} this flag can be disabled + * by the car manufacturers. */ public static final int FLAG_TRANSLUCENT_NAVIGATION = 0x08000000; diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index d302c2b08217..032af1c5c7b5 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -707,9 +707,10 @@ public final class InputMethodManager { if (mBindSequence != bindSequence) { return; } - if (matrixValues == null) { - // That this app is unbound from the parent ActivityView. In this case, - // calling updateCursorAnchorInfo() isn't safe. Only clear the matrix. + if (matrixValues == null || mActivityViewToScreenMatrix == null) { + // Either InputBoundResult#mActivityViewToScreenMatrixValues is null + // OR this app is unbound from the parent ActivityView. In this case, + // calling updateCursorAnchorInfo() isn't safe. Only clear the matrix. mActivityViewToScreenMatrix = null; return; } 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/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index 00206fc38d1d..de77aaae1653 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -164,6 +164,8 @@ public class ChooserActivity extends ResolverActivity { public static final String LAUNCH_LOCATON_DIRECT_SHARE = "direct_share"; private static final int APP_PREDICTION_SHARE_TARGET_QUERY_PACKAGE_LIMIT = 20; public static final String APP_PREDICTION_INTENT_FILTER_KEY = "intent_filter"; + + private boolean mIsAppPredictorComponentAvailable; private AppPredictor mAppPredictor; private AppPredictor.Callback mAppPredictorCallback; private Map<ChooserTarget, AppTarget> mDirectShareAppTargetCache; @@ -491,6 +493,9 @@ public class ChooserActivity extends ResolverActivity { @Override protected void onCreate(Bundle savedInstanceState) { final long intentReceivedTime = System.currentTimeMillis(); + // This is the only place this value is being set. Effectively final. + mIsAppPredictorComponentAvailable = isAppPredictionServiceAvailable(); + mIsSuccessfullySelected = false; Intent intent = getIntent(); Parcelable targetParcelable = intent.getParcelableExtra(Intent.EXTRA_INTENT); @@ -707,6 +712,32 @@ public class ChooserActivity extends ResolverActivity { } /** + * Returns true if app prediction service is defined and the component exists on device. + */ + private boolean isAppPredictionServiceAvailable() { + final String appPredictionServiceName = + getString(R.string.config_defaultAppPredictionService); + if (appPredictionServiceName == null) { + return false; + } + final ComponentName appPredictionComponentName = + ComponentName.unflattenFromString(appPredictionServiceName); + if (appPredictionComponentName == null) { + return false; + } + + // Check if the app prediction component actually exists on the device. + Intent intent = new Intent(); + intent.setComponent(appPredictionComponentName); + if (getPackageManager().resolveService(intent, PackageManager.MATCH_ALL) == null) { + Log.e(TAG, "App prediction service is defined, but does not exist: " + + appPredictionServiceName); + return false; + } + return true; + } + + /** * Check if the profile currently used is a work profile. * @return true if it is work profile, false if it is parent profile (or no work profile is * set up) @@ -1693,6 +1724,9 @@ public class ChooserActivity extends ResolverActivity { @Nullable private AppPredictor getAppPredictor() { + if (!mIsAppPredictorComponentAvailable) { + return null; + } if (mAppPredictor == null && getPackageManager().getAppPredictionServicePackageName() != null) { final IntentFilter filter = getTargetIntentFilter(); diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl index d60d5438b3a7..15b1d75e88d0 100644 --- a/core/java/com/android/internal/app/IBatteryStats.aidl +++ b/core/java/com/android/internal/app/IBatteryStats.aidl @@ -106,7 +106,7 @@ interface IBatteryStats { void notePhoneOn(); void notePhoneOff(); void notePhoneSignalStrength(in SignalStrength signalStrength); - void notePhoneDataConnectionState(int dataType, boolean hasData); + void notePhoneDataConnectionState(int dataType, boolean hasData, int serviceType); void notePhoneState(int phoneState); void noteWifiOn(); void noteWifiOff(); diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 3a7caa4c2fc0..457308498398 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -906,8 +906,6 @@ public class BatteryStatsImpl extends BatteryStats { @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) protected StopwatchTimer mBluetoothScanTimer; - boolean mIsCellularTxPowerHigh = false; - int mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; long mMobileRadioActiveStartTime; StopwatchTimer mMobileRadioActiveTimer; @@ -5261,16 +5259,26 @@ public class BatteryStatsImpl extends BatteryStats { } @UnsupportedAppUsage - public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) { + public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData, int serviceType) { // BatteryStats uses 0 to represent no network type. // Telephony does not have a concept of no network type, and uses 0 to represent unknown. // Unknown is included in DATA_CONNECTION_OTHER. - int bin = DATA_CONNECTION_NONE; + int bin = DATA_CONNECTION_OUT_OF_SERVICE; if (hasData) { if (dataType > 0 && dataType <= TelephonyManager.MAX_NETWORK_TYPE) { bin = dataType; } else { - bin = DATA_CONNECTION_OTHER; + switch (serviceType) { + case ServiceState.STATE_OUT_OF_SERVICE: + bin = DATA_CONNECTION_OUT_OF_SERVICE; + break; + case ServiceState.STATE_EMERGENCY_ONLY: + bin = DATA_CONNECTION_EMERGENCY_SERVICE; + break; + default: + bin = DATA_CONNECTION_OTHER; + break; + } } } if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData); @@ -11190,19 +11198,9 @@ public class BatteryStatsImpl extends BatteryStats { } } if (levelMaxTimeSpent == ModemActivityInfo.TX_POWER_LEVELS - 1) { - if (!mIsCellularTxPowerHigh) { - mHistoryCur.states2 |= HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG; - addHistoryRecordLocked(elapsedRealtime, uptime); - mIsCellularTxPowerHigh = true; - } - return; - } - if (mIsCellularTxPowerHigh) { - mHistoryCur.states2 &= ~HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG; + mHistoryCur.states2 |= HistoryItem.STATE2_CELLULAR_HIGH_TX_POWER_FLAG; addHistoryRecordLocked(elapsedRealtime, uptime); - mIsCellularTxPowerHigh = false; } - return; } private final class BluetoothActivityInfoCache { @@ -13660,7 +13658,6 @@ public class BatteryStatsImpl extends BatteryStats { mCameraOnTimer.readSummaryFromParcelLocked(in); mBluetoothScanNesting = 0; mBluetoothScanTimer.readSummaryFromParcelLocked(in); - mIsCellularTxPowerHigh = false; int NRPMS = in.readInt(); if (NRPMS > 10000) { @@ -14644,7 +14641,6 @@ public class BatteryStatsImpl extends BatteryStats { mCameraOnTimer = new StopwatchTimer(mClocks, null, -13, null, mOnBatteryTimeBase, in); mBluetoothScanNesting = 0; mBluetoothScanTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase, in); - mIsCellularTxPowerHigh = false; mDischargeUnplugLevel = in.readInt(); mDischargePlugLevel = in.readInt(); mDischargeCurrentLevel = in.readInt(); diff --git a/core/java/com/android/internal/util/ScreenshotHelper.java b/core/java/com/android/internal/util/ScreenshotHelper.java index 7fd94c6859fb..cac691cf7d45 100644 --- a/core/java/com/android/internal/util/ScreenshotHelper.java +++ b/core/java/com/android/internal/util/ScreenshotHelper.java @@ -1,6 +1,7 @@ package com.android.internal.util; import android.annotation.NonNull; +import android.annotation.Nullable; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -13,6 +14,8 @@ import android.os.RemoteException; import android.os.UserHandle; import android.util.Log; +import java.util.function.Consumer; + public class ScreenshotHelper { private static final String TAG = "ScreenshotHelper"; @@ -34,17 +37,58 @@ public class ScreenshotHelper { } /** + * Request a screenshot be taken with a specific timeout. + * + * Added to support reducing unit test duration; the method variant without a timeout argument + * is recommended for general use. + * + * @param screenshotType The type of screenshot, for example either + * {@link android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN} + * or + * {@link android.view.WindowManager.TAKE_SCREENSHOT_SELECTED_REGION} + * @param hasStatus {@code true} if the status bar is currently showing. {@code false} + * if + * not. + * @param hasNav {@code true} if the navigation bar is currently showing. {@code + * false} + * if not. + * @param handler A handler used in case the screenshot times out + * @param completionConsumer Consumes `false` if a screenshot was not taken, and `true` if the + * screenshot was taken. + */ + public void takeScreenshot(final int screenshotType, final boolean hasStatus, + final boolean hasNav, @NonNull Handler handler, + @Nullable Consumer<Boolean> completionConsumer) { + takeScreenshot(screenshotType, hasStatus, hasNav, SCREENSHOT_TIMEOUT_MS, handler, + completionConsumer); + } + + /** * Request a screenshot be taken. * - * @param screenshotType The type of screenshot, for example either - * {@link android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN} - * or {@link android.view.WindowManager.TAKE_SCREENSHOT_SELECTED_REGION} - * @param hasStatus {@code true} if the status bar is currently showing. {@code false} if not. - * @param hasNav {@code true} if the navigation bar is currently showing. {@code false} if not. - * @param handler A handler used in case the screenshot times out + * Added to support reducing unit test duration; the method variant without a timeout argument + * is recommended for general use. + * + * @param screenshotType The type of screenshot, for example either + * {@link android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN} + * or + * {@link android.view.WindowManager.TAKE_SCREENSHOT_SELECTED_REGION} + * @param hasStatus {@code true} if the status bar is currently showing. {@code false} + * if + * not. + * @param hasNav {@code true} if the navigation bar is currently showing. {@code + * false} + * if not. + * @param timeoutMs If the screenshot hasn't been completed within this time period, + * the screenshot attempt will be cancelled and `completionConsumer` + * will be run. + * @param handler A handler used in case the screenshot times out + * @param completionConsumer Consumes `false` if a screenshot was not taken, and `true` if the + * screenshot was taken. */ public void takeScreenshot(final int screenshotType, final boolean hasStatus, - final boolean hasNav, @NonNull Handler handler) { + final boolean hasNav, long timeoutMs, @NonNull Handler handler, + @Nullable Consumer<Boolean> completionConsumer) { synchronized (mScreenshotLock) { if (mScreenshotConnection != null) { return; @@ -54,7 +98,8 @@ public class ScreenshotHelper { final Intent serviceIntent = new Intent(); final Runnable mScreenshotTimeout = new Runnable() { - @Override public void run() { + @Override + public void run() { synchronized (mScreenshotLock) { if (mScreenshotConnection != null) { mContext.unbindService(mScreenshotConnection); @@ -62,6 +107,9 @@ public class ScreenshotHelper { notifyScreenshotError(); } } + if (completionConsumer != null) { + completionConsumer.accept(false); + } } }; @@ -86,15 +134,22 @@ public class ScreenshotHelper { handler.removeCallbacks(mScreenshotTimeout); } } + if (completionConsumer != null) { + completionConsumer.accept(true); + } } }; msg.replyTo = new Messenger(h); - msg.arg1 = hasStatus ? 1: 0; - msg.arg2 = hasNav ? 1: 0; + msg.arg1 = hasStatus ? 1 : 0; + msg.arg2 = hasNav ? 1 : 0; + try { messenger.send(msg); } catch (RemoteException e) { Log.e(TAG, "Couldn't take screenshot: " + e); + if (completionConsumer != null) { + completionConsumer.accept(false); + } } } } @@ -115,7 +170,7 @@ public class ScreenshotHelper { Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE, UserHandle.CURRENT)) { mScreenshotConnection = conn; - handler.postDelayed(mScreenshotTimeout, SCREENSHOT_TIMEOUT_MS); + handler.postDelayed(mScreenshotTimeout, timeoutMs); } } } diff --git a/core/java/com/android/internal/util/XmlUtils.java b/core/java/com/android/internal/util/XmlUtils.java index 344d7ef8c83f..8799e3d4c6bf 100644 --- a/core/java/com/android/internal/util/XmlUtils.java +++ b/core/java/com/android/internal/util/XmlUtils.java @@ -26,6 +26,8 @@ import android.util.ArrayMap; import android.util.Base64; import android.util.Xml; +import libcore.util.HexEncoding; + import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; @@ -396,16 +398,7 @@ public class XmlUtils { final int N = val.length; out.attribute(null, "num", Integer.toString(N)); - StringBuilder sb = new StringBuilder(val.length*2); - for (int i=0; i<N; i++) { - int b = val[i]; - int h = (b >> 4) & 0x0f; - sb.append((char)(h >= 10 ? ('a'+h-10) : ('0'+h))); - h = b & 0x0f; - sb.append((char)(h >= 10 ? ('a'+h-10) : ('0'+h))); - } - - out.text(sb.toString()); + out.text(HexEncoding.encodeToString(val).toLowerCase()); out.endTag(null, "byte-array"); } @@ -1032,7 +1025,9 @@ public class XmlUtils { "Not a number in num attribute in byte-array"); } - byte[] array = new byte[num]; + // 0 len byte array does not have a text in the XML tag. So, initialize to 0 len array. + // For all other array lens, HexEncoding.decode() below overrides the array. + byte[] array = new byte[0]; int eventType = parser.getEventType(); do { @@ -1043,16 +1038,7 @@ public class XmlUtils { throw new XmlPullParserException( "Invalid value found in byte-array: " + values); } - // This is ugly, but keeping it to mirror the logic in #writeByteArrayXml. - for (int i = 0; i < num; i ++) { - char nibbleHighChar = values.charAt(2 * i); - char nibbleLowChar = values.charAt(2 * i + 1); - int nibbleHigh = nibbleHighChar > 'a' ? (nibbleHighChar - 'a' + 10) - : (nibbleHighChar - '0'); - int nibbleLow = nibbleLowChar > 'a' ? (nibbleLowChar - 'a' + 10) - : (nibbleLowChar - '0'); - array[i] = (byte) ((nibbleHigh & 0x0F) << 4 | (nibbleLow & 0x0F)); - } + array = HexEncoding.decode(values); } } else if (eventType == parser.END_TAG) { if (parser.getName().equals(endTag)) { diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java index 9fc79cb606e6..510b321e8070 100644 --- a/core/java/com/android/server/SystemConfig.java +++ b/core/java/com/android/server/SystemConfig.java @@ -53,6 +53,8 @@ import java.util.Map; /** * Loads global system configuration info. + * Note: Initializing this class hits the disk and is slow. This class should generally only be + * accessed by the system_server process. */ public class SystemConfig { static final String TAG = "SystemConfig"; @@ -209,6 +211,11 @@ public class SystemConfig { private final ArraySet<String> mBugreportWhitelistedPackages = new ArraySet<>(); public static SystemConfig getInstance() { + if (!isSystemProcess()) { + Slog.wtf(TAG, "SystemConfig is being accessed by a process other than " + + "system_server."); + } + synchronized (SystemConfig.class) { if (sInstance == null) { sInstance = new SystemConfig(); @@ -1154,4 +1161,8 @@ public class SystemConfig { mSplitPermissions.add(new SplitPermissionInfo(splitPerm, newPermissions, targetSdk)); } } + + private static boolean isSystemProcess() { + return Process.myUid() == Process.SYSTEM_UID; + } } diff --git a/core/jni/android_hardware_input_InputWindowHandle.cpp b/core/jni/android_hardware_input_InputWindowHandle.cpp index a1d1d4f0733d..57d16496fca5 100644 --- a/core/jni/android_hardware_input_InputWindowHandle.cpp +++ b/core/jni/android_hardware_input_InputWindowHandle.cpp @@ -28,6 +28,7 @@ #include "android_hardware_input_InputWindowHandle.h" #include "android_hardware_input_InputApplicationHandle.h" #include "android_util_Binder.h" +#include <binder/IPCThreadState.h> namespace android { @@ -78,6 +79,12 @@ NativeInputWindowHandle::NativeInputWindowHandle(jweak objWeak) : NativeInputWindowHandle::~NativeInputWindowHandle() { JNIEnv* env = AndroidRuntime::getJNIEnv(); env->DeleteWeakGlobalRef(mObjWeak); + + // Clear the weak reference to the layer handle and flush any binder ref count operations so we + // do not hold on to any binder references. + // TODO(b/139697085) remove this after it can be flushed automatically + mInfo.touchableRegionCropHandle.clear(); + IPCThreadState::self()->flushCommands(); } jobject NativeInputWindowHandle::getInputWindowHandleObjLocalRef(JNIEnv* env) { diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index 10e851b3d630..578f9045dfcb 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tik om alle netwerke te sien"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Koppel"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Alle netwerke"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Koppel aan Wi-Fi-netwerke?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Voorgestel deur <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ja"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nee"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Laat voorgestelde Wi‑Fi-netwerke toe?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"Netwerke wat deur <xliff:g id="NAME">%s</xliff:g> voorgestel is. Toestel sal dalk outomaties koppel."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Laat toe"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Nee, dankie"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi-Fi sal outomaties aanskakel"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Wanneer jy naby \'n gestoorde hoëgehaltenetwerk is"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Moenie weer aanskakel nie"</string> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index 06654c4590ea..d228bcf5852b 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ሁሉንም አውታረ መረቦችን ለማየት መታ ያድርጉ"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"አገናኝ"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"ሁሉም አውታረ መረቦች"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"ከWi-Fi አውታረ መረቦች ጋር ይገናኝ?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"በ<xliff:g id="NAME">%s</xliff:g> የተጠቆሙ"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"አዎ"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"አይ"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"የተጠቆሙ የWi‑Fi አውታረ መረቦች ይፈቀዱ?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"በ<xliff:g id="NAME">%s</xliff:g> የተጠቆሙ አውታረ መረቦች። መሣሪያ በራስ-ሰር ሊገናኝ ይችላል።"</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"ፍቀድ"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"አይ፣ አመሰግናለሁ"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi በራስ-ሰር ይበራል"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"ከፍተኛ ጥራት ያለው የተቀመጠ አውታረ መረብ አቅራቢያ ሲሆኑ"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"መልሰህ አታብራ"</string> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index 4cf4c9f8e5cc..7d387eca26ca 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -1343,10 +1343,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"انقر للاطلاع على جميع الشبكات"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"اتصال"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"جميع الشبكات"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"هل تريد الاتصال بشبكات Wi-Fi؟"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"اقتراح من <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"نعم"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"لا"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"هل تريد السماح لشبكات Wi‑Fi المقترحة؟"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> الشبكات المقترحة. قد يتم توصيل الجهاز تلقائيًا."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"سماح"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"لا، شكرًا"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"سيتم تشغيل شبكة Wi-Fi تلقائيًا."</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"عندما تكون بالقرب من شبكة محفوظة عالية الجودة"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"عدم إعادة التشغيل"</string> diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml index c53af2b3fa7e..6ad408c1e2dd 100644 --- a/core/res/res/values-as/strings.xml +++ b/core/res/res/values-as/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"সকলো নেটৱৰ্ক চাবলৈ টিপক"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"সংযোগ কৰক"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"সকলো নেটৱৰ্ক"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"ৱাই-ফাই নেটৱৰ্কৰ সৈতে সংযোগ কৰিবনে?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g>এ প্ৰস্তাব দিয়া"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"হয়"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"নহয়"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"পৰামর্শ হিচাপে পোৱা নেটৱর্কবোৰক অনুমতি দিবনে?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g>এ পৰামর্শ হিচাপে দিয়া নেটৱর্কবোৰ। ডিভাইচটো স্বয়ংক্ৰিয়ভাৱে সংযোগ হ\'ব পাৰে।"</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"অনুমতি দিয়ক"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"নালাগে, ধন্যবাদ"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"ৱাই-ফাই স্বয়ংক্ৰিয়ভাৱে অন হ\'ব"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"যেতিয়া আপুনি ছেভ কৰি থোৱা উচ্চ মানৰ নেটৱৰ্কৰ কাষত থাকে"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"পুনৰাই অন নকৰিব"</string> diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml index a3a2f2a0ecff..aa1eb013265d 100644 --- a/core/res/res/values-az/strings.xml +++ b/core/res/res/values-az/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Bütün şəbəkələri görmək üçün klikləyin"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Qoşulun"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Bütün şəbəkələr"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Wi-Fi şəbəkələrinə qoşulsun?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> tərəfindən təklif edildi"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Bəli"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Xeyr"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Təklif edilən Wi‑Fi şəbəkələrinə icazə verilsin?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> təklif edilən şəbəkə. Cihaz avtomatik qoşula bilər."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"İcazə verin"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Xeyr, təşəkkürlər"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi avtomatik olaraq aktiv ediləcək"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Yadda saxlanmış yüksək keyfiyyətli şəbəkələr yaxınlıqda olduqda"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Yenidən aktiv etməyin"</string> diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml index 61a2167b8860..cf9775738450 100644 --- a/core/res/res/values-b+sr+Latn/strings.xml +++ b/core/res/res/values-b+sr+Latn/strings.xml @@ -1277,10 +1277,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Dodirnite da biste videli sve mreže"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Poveži"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Sve mreže"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Želite li da se povežete sa Wi-Fi mrežama?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> predlaže"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Da"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ne"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Želite da dozvolite predložene Wi‑Fi mreže?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"Mreže koje predlaže <xliff:g id="NAME">%s</xliff:g>. Uređaj će se možda povezati automatski."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Dozvoli"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Ne, hvala"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi će se automatski uključiti"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Kada ste u blizini sačuvane mreže visokog kvaliteta"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Ne uključuj ponovo"</string> diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml index 1bc5320a4ebe..297be37132ce 100644 --- a/core/res/res/values-be/strings.xml +++ b/core/res/res/values-be/strings.xml @@ -1299,10 +1299,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Дакраніцеся, каб убачыць усе сеткі"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Падключыцца"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Усе сеткі"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Падключыцца да сетак Wi-Fi?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Прапанавана ўладальнікам <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Так"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Не"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Дазволіць падключэнне да прапанаваных сетак Wi‑Fi?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"Праграма \"<xliff:g id="NAME">%s</xliff:g>\" прапанавала сеткі. Прылада можа падключыцца аўтаматычна."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Дазволіць"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Не, дзякуй"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi уключыцца аўтаматычна"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Побач з захаванай сеткай з высакаякасным сігналам"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Не ўключаць зноў"</string> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index 49d0a378a49b..339873fa061c 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Докоснете, за да видите всички мрежи"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Свързване"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Всички мрежи"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Да се установи ли връзка с Wi-Fi мрежи?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Предложено от <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Да"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Не"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Да се разрешат ли предложените Wi‑Fi мрежи?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"Предложени от <xliff:g id="NAME">%s</xliff:g> мрежи. Устройството може да се свърже автоматично."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Разрешаване"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Не, благодаря"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi ще се включи автоматично"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Когато сте в района на запазена мрежа с високо качество"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Без повторно включване"</string> diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml index ae4e1236283e..4e7e563b12b0 100644 --- a/core/res/res/values-bn/strings.xml +++ b/core/res/res/values-bn/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"সমস্ত নেটওয়ার্ক দেখতে ট্যাপ করুন"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"সংযুক্ত করুন"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"সব নেটওয়ার্ক"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"ওয়াই-ফাই নেটওয়ার্কের সাথে কানেক্ট করতে চান?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> সাজেস্ট করেছে"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"হ্যাঁ"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"না"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"সাজেস্ট করা ওয়াই-ফাই নেটওয়ার্কে কানেক্ট করার অনুমতি দিতে চান?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g>-এর সাজেস্ট করা নেটওয়ার্ক। ডিভাইস নিজে থেকে কানেক্ট হতে পারে।"</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"অনুমতি দিন"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"না থাক"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"ওয়াই-ফাই অটোমেটিক চালু হবে"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"যখন আপনি একটি উচ্চ মানের সংরক্ষিত নেটওয়ার্ক কাছাকাছি থাকেন"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"আবার চালু করবেন না"</string> diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml index 54e146b9f1da..4f0c5ee1af88 100644 --- a/core/res/res/values-bs/strings.xml +++ b/core/res/res/values-bs/strings.xml @@ -1279,10 +1279,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Dodirnite da vidite sve mreže"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Povežite se"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Sve mreže"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Povezivati na WiFi mreže?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Predlaže <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Da"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ne"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Dozvoliti predložene WiFi mreže?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"Mreže koje predlaže <xliff:g id="NAME">%s</xliff:g>. Uređaj će se možda povezati automatski."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Dozvoli"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Ne, hvala"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"WiFi će se uključiti automatski"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Kada ste u blizini sačuvane mreže visokog kvaliteta"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Nemoj ponovo uključiti"</string> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index 3a74d2ab2bfc..d6ebd469f280 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toca per veure totes les xarxes"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connecta"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Totes les xarxes"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Vols connectar-te a una xarxa Wi‑Fi?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Suggerida per <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Sí"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"No"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Vols permetre les xarxes Wi‑Fi suggerides?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"Xarxes suggerides de l\'aplicació <xliff:g id="NAME">%s</xliff:g>. El dispositiu pot connectar-se automàticament."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Permet"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"No, gràcies"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"La Wi-Fi s\'activarà automàticament"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Quan siguis a prop d\'una xarxa de qualitat desada"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"No tornis a activar"</string> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index 63b3e4c6e2db..36c7b128e021 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -1299,10 +1299,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Klepnutím zobrazíte všechny sítě"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Připojit"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Všechny sítě"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Připojit k sítím Wi-Fi?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Navrženo kanálem <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ano"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ne"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Povolit navrhované sítě Wi-Fi?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"Sítě navrhované aplikací <xliff:g id="NAME">%s</xliff:g>. Zařízení se může připojovat automaticky."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Povolit"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Ne, díky"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi se zapne automaticky"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Když budete v dosahu kvalitní uložené sítě"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Znovu nezapínat"</string> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index ee5597f289bc..4116b1d6b1fd 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tryk for at se alle netværk"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Opret forbindelse"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Alle netværk"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Vil du oprette forbindelse til Wi-Fi-netværk?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Foreslået af <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ja"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nej"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Vil du tillade foreslåede Wi‑Fi-netværk?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"Netværk foreslået af <xliff:g id="NAME">%s</xliff:g>. Enheden opretter muligvis forbindelse automatisk."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Tillad"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Nej tak"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi aktiveres automatisk"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Når du er i nærheden af et gemt netværk af høj kvalitet"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Aktivér ikke igen"</string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 8083aeb0e125..7b8ef7b57053 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tippen, um alle Netzwerke zu sehen"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Verbinden"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Alle Netzwerke"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Verbindung mit WLANs herstellen?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Vorschlag von <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ja"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nein"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Vorgeschlagene WLANs zulassen?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"Von <xliff:g id="NAME">%s</xliff:g> vorgeschlagene Netzwerke. Gerät verbindet sich möglicherweise automatisch."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Zulassen"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Nein danke"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"WLAN wird automatisch aktiviert"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Wenn du in der Nähe eines sicheren gespeicherten Netzwerks bist"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Nicht wieder aktivieren"</string> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index d74bc5951d5e..1fc42903eb79 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Πατήστε για να δείτε όλα τα δίκτυα"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Σύνδεση"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Όλα τα δίκτυα"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Σύνδεση σε δίκτυα Wi-Fi;"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Προτείνεται από <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ναι"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Όχι"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Να επιτρέπονται προτεινόμενα δίκτυα Wi‑Fi;"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"Προτεινόμενα δίκτυα <xliff:g id="NAME">%s</xliff:g>. Η συσκευή μπορεί να συνδεθεί αυτόματα."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Αποδοχή"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Όχι, ευχαριστώ"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Το Wi‑Fi θα ενεργοποιηθεί αυτόματα"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Όταν βρίσκεστε κοντά σε αποθηκευμένο δίκτυο υψηλής ποιότητας"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Να μην ενεργοποιηθεί ξανά"</string> diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml index f5a5698b5b61..f0d9c741b5df 100644 --- a/core/res/res/values-en-rAU/strings.xml +++ b/core/res/res/values-en-rAU/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap to see all networks"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connect"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"All networks"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Connect to Wi‑Fi networks?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Suggested by <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Yes"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"No"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Allow suggested Wi‑Fi networks?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> suggested networks. Device may connect automatically."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Allow"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"No, thanks"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi will turn on automatically"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"When you\'re near a high‑quality saved network"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Don\'t turn back on"</string> diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml index 47318862c76f..6cf284320cdb 100644 --- a/core/res/res/values-en-rCA/strings.xml +++ b/core/res/res/values-en-rCA/strings.xml @@ -95,7 +95,6 @@ <string name="notification_channel_voice_mail" msgid="3954099424160511919">"Voicemail messages"</string> <string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi Calling"</string> <string name="notification_channel_sim" msgid="4052095493875188564">"SIM status"</string> - <string name="notification_channel_sim_high_prio" msgid="1787666807724243207">"High priority SIM status"</string> <string name="peerTtyModeFull" msgid="6165351790010341421">"Peer requested TTY Mode FULL"</string> <string name="peerTtyModeHco" msgid="5728602160669216784">"Peer requested TTY Mode HCO"</string> <string name="peerTtyModeVco" msgid="1742404978686538049">"Peer requested TTY Mode VCO"</string> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index f5a5698b5b61..f0d9c741b5df 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap to see all networks"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connect"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"All networks"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Connect to Wi‑Fi networks?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Suggested by <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Yes"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"No"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Allow suggested Wi‑Fi networks?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> suggested networks. Device may connect automatically."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Allow"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"No, thanks"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi will turn on automatically"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"When you\'re near a high‑quality saved network"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Don\'t turn back on"</string> diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml index f5a5698b5b61..f0d9c741b5df 100644 --- a/core/res/res/values-en-rIN/strings.xml +++ b/core/res/res/values-en-rIN/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tap to see all networks"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connect"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"All networks"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Connect to Wi‑Fi networks?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Suggested by <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Yes"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"No"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Allow suggested Wi‑Fi networks?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> suggested networks. Device may connect automatically."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Allow"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"No, thanks"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi will turn on automatically"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"When you\'re near a high‑quality saved network"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Don\'t turn back on"</string> diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml index 95ebcdc8c603..f62b3857b930 100644 --- a/core/res/res/values-en-rXC/strings.xml +++ b/core/res/res/values-en-rXC/strings.xml @@ -95,7 +95,6 @@ <string name="notification_channel_voice_mail" msgid="3954099424160511919">"Voicemail messages"</string> <string name="notification_channel_wfc" msgid="2130802501654254801">"Wi-Fi calling"</string> <string name="notification_channel_sim" msgid="4052095493875188564">"SIM status"</string> - <string name="notification_channel_sim_high_prio" msgid="1787666807724243207">"High priority SIM status"</string> <string name="peerTtyModeFull" msgid="6165351790010341421">"Peer requested TTY Mode FULL"</string> <string name="peerTtyModeHco" msgid="5728602160669216784">"Peer requested TTY Mode HCO"</string> <string name="peerTtyModeVco" msgid="1742404978686538049">"Peer requested TTY Mode VCO"</string> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index 7a22a8e454a1..9704987161b8 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -30,7 +30,7 @@ <string name="untitled" msgid="4638956954852782576">"<Sin título>"</string> <string name="emptyPhoneNumber" msgid="7694063042079676517">"(No hay número de teléfono)"</string> <string name="unknownName" msgid="6867811765370350269">"Desconocido"</string> - <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Correo de voz"</string> + <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Buzón de voz"</string> <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string> <string name="mmiError" msgid="5154499457739052907">"Problema de conexión o código incorrecto de MMI."</string> <string name="mmiFdnError" msgid="5224398216385316471">"La operación está limitada a números de marcación fija."</string> @@ -941,7 +941,7 @@ <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Permite que la aplicación modifique el historial o los favoritos del navegador almacenados en el dispositivo. La aplicación puede utilizar este permiso para borrar o modificar los datos del navegador. Nota: Este permiso no puede ser utilizado por navegadores externos ni otras aplicaciones que tengan funciones de navegación por Internet."</string> <string name="permlab_setAlarm" msgid="1379294556362091814">"programar una alarma"</string> <string name="permdesc_setAlarm" msgid="316392039157473848">"Permite que la aplicación establezca una alarma en una aplicación de alarma instalada. Es posible que algunas aplicaciones de alarma no incluyan esta función."</string> - <string name="permlab_addVoicemail" msgid="5525660026090959044">"agregar correo de voz"</string> + <string name="permlab_addVoicemail" msgid="5525660026090959044">"agregar buzón de voz"</string> <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Permite que la aplicación agregue mensajes a la bandeja de entrada de tu buzón de voz."</string> <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"Modificar los permisos de ubicación geográfica del navegador"</string> <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Permite que la aplicación modifique los permisos de ubicación geográfica del navegador. Las aplicaciones maliciosas pueden utilizar esto para permitir el envío de información de ubicación a sitios web arbitrarios."</string> @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Presiona para ver todas las redes"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectar"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Todas las redes"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"¿Quieres conectarte a redes Wi-Fi?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Sugerido por <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Sí"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"No"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"¿Quieres permitir las redes Wi‑Fi sugeridas?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> sugirió redes. Es posible que el dispositivo se conecte automáticamente."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Permitir"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"No, gracias"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Se activará la conexión Wi-Fi automáticamente"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Cuando estés cerca de una red guardada de alta calidad"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"No volver a activar"</string> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index ae7f38a18986..527ccf7c4601 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toca para ver todas las redes"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectarse"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Todas las redes"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"¿Quieres conectarte a redes Wi-Fi?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Sugerido por <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Sí"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"No"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"¿Permitir sugerencias de redes Wi‑Fi?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> te ha sugerido alguna red. El dispositivo puede que se conecte automáticamente."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Permitir"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"No, gracias"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"La conexión Wi‑Fi se activará automáticamente"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Cuando estés cerca de una red de alta calidad guardada"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"No volver a activar"</string> diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml index d3404a646301..9b1bdd37258d 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Puudutage kõikide võrkude nägemiseks"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Ühenda"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Kõik võrgud"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Kas soovite luua ühenduse WiFi-võrkudega?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Soovitas <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Jah"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ei"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Kas lubada soovitatud WiFi-võrgud?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"Rakenduse <xliff:g id="NAME">%s</xliff:g> soovitatud võrgud. Seade võib automaatselt ühenduse luua."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Luba"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Tänan, ei"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"WiFi lülitub sisse automaatselt"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Kui olete kvaliteetse salvestatud võrgu läheduses"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Ära lülita tagasi sisse"</string> diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml index 8897b9f599c4..35d97af3424b 100644 --- a/core/res/res/values-eu/strings.xml +++ b/core/res/res/values-eu/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Sakatu hau sare guztiak ikusteko"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Konektatu"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Sare guztiak"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Wifi-sareetara konektatu nahi duzu?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> aplikazioak iradoki du"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Bai"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ez"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Iradokitako wifi-sareak baimendu nahi dituzu?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> aplikazioak sare batzuk iradoki ditu. Baliteke gailua automatikoki konektatzea."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Baimendu"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Ez. Eskerrik asko."</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi konexioa automatikoki aktibatuko da"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Gordeta daukazun kalitate handiko sare batetik gertu zaudenean"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Ez aktibatu berriro"</string> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index 7d86be9a8ecd..42495f0cc170 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"برای دیدن همه شبکهها ضربه بزنید"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"اتصال"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"همه شبکهها"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"به شبکههای Wi-Fi متصل میشوید؟"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"پیشنهاد <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"بله"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"خیر"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"شبکههای Wi‑Fi پیشنهادی مجاز شود؟"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"شبکههای پیشنهادی <xliff:g id="NAME">%s</xliff:g>. ممکن است دستگاه بهطور خودکار متصل شود."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"مجاز"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"نه متشکرم"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi بهطور خودکار روشن خواهد شد"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"وقتی نزدیک شبکه ذخیرهشده با کیفیت بالا هستید"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"دوباره روشن نشود"</string> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index 0a6132d10a85..4f4eacb8afe3 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Napauta, niin näet kaikki verkot."</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Yhdistä"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Kaikki verkot"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Yhdistetäänkö Wi-Fi-verkkoihin?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Ehdottaja: <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Kyllä"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ei"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Sallitaanko ehdotetut Wi-Fi-verkot?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> ehdotti verkkoja. Laite voi muodostaa yhteyden automaattisesti."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Salli"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Ei kiitos"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi-Fi käynnistyy automaattisesti"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Kun olet lähellä laadukasta tallennettua verkkoa"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Älä käynnistä uudelleen"</string> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index cee285971c51..52d40ed9bf2e 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Touchez pour afficher tous les réseaux"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connexion"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Tous les réseaux"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Se connecter aux réseaux Wi-Fi?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Suggéré par <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Oui"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Non"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Autoriser les suggestions de réseaux Wi‑Fi?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"Réseaux suggérés par <xliff:g id="NAME">%s</xliff:g>. L\'appareil peut s\'y connecter automatiquement."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Autoriser"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Non merci"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Le Wi-Fi s\'activera automatiquement"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Lorsque vous êtes près d\'un réseau enregistré de haute qualité"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Ne pas réactiver"</string> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 35553c459b5b..6e3192ef5ef1 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Appuyer pour afficher tous les réseaux"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Se connecter"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Tous les réseaux"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Se connecter à des réseaux Wi-Fi ?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Suggérée par <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Oui"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Non"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Autoriser les suggestions de réseaux Wi‑Fi ?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"Réseaux suggérés par <xliff:g id="NAME">%s</xliff:g>. L\'appareil pourra se connecter automatiquement."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Autoriser"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Non, merci"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Le Wi-Fi sera activé automatiquement"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Lorsque vous êtes à proximité d\'un réseau enregistré de haute qualité"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Ne pas réactiver"</string> diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml index 6bdf045de2b6..e81c3f427fcf 100644 --- a/core/res/res/values-gl/strings.xml +++ b/core/res/res/values-gl/strings.xml @@ -387,7 +387,7 @@ <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"Permite á aplicación executarse unha vez o sistema se inicie completamente. Isto pode provocar que o teléfono tarde máis tempo en iniciarse e permitir á aplicación reducir a velocidade xeral do teléfono ao manterse sempre en execución."</string> <string name="permlab_broadcastSticky" msgid="7919126372606881614">"enviar difusión persistente"</string> <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"Permite á aplicación enviar difusións permanentes que continúan unha vez finalizada a difusión. Un uso excesivo pode provocar que a tableta funcione con lentitude ou de forma inestable debido á necesidade de utilizar demasiada memoria."</string> - <string name="permdesc_broadcastSticky" product="tv" msgid="6839285697565389467">"Permite que a aplicación envíe emisións permanentes, que continúan unha vez finalizada a emisión. O uso excesivo pode volver a televisión máis lenta ou inestable, facendo que utilice moita memoria."</string> + <string name="permdesc_broadcastSticky" product="tv" msgid="6839285697565389467">"Permite que a aplicación envíe emisións atractivas, que permanecen unha vez finalizada a emisión. O uso excesivo pode volver a televisión máis lenta ou inestable, facendo que utilice moita memoria."</string> <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"Permite á aplicación enviar difusións permanentes que continúan unha vez finalizada a difusión. Un uso excesivo pode provocar que o teléfono funcione con lentitude ou de forma inestable debido á necesidade de utilizar demasiada memoria."</string> <string name="permlab_readContacts" msgid="8348481131899886131">"ler os teus contactos"</string> <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"Permite á aplicación ler datos acerca dos teus contactos almacenados na tableta, incluída a frecuencia coa que os chamaches, lles enviaches un correo electrónico ou te comunicaches con individuos específicos doutras formas. Con este permiso as aplicacións poden gardar os teus datos de contacto e as aplicacións maliciosas poden compartir os datos de contacto sen o teu coñecemento."</string> @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toca para ver todas as redes"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectarse"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Todas as redes"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Queres conectarte a redes wifi?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Suxerido por <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Si"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Non"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Queres permitir as redes wifi suxeridas?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"Redes suxeridas de <xliff:g id="NAME">%s</xliff:g>. O dispositivo pode conectarse automaticamente."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Permitir"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Non, grazas"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"A wifi activarase automaticamente"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Cando esteas preto dunha rede gardada de alta calidade"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Non volver activar"</string> diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml index c86c9e604c0e..7f22d6767dee 100644 --- a/core/res/res/values-gu/strings.xml +++ b/core/res/res/values-gu/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"બધા નેટવર્ક જોવા ટૅપ કરો"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"કનેક્ટ કરો"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"બધા નેટવર્કો"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"વાઇ-ફાઇ નેટવર્ક સાથે કનેક્ટ કરીએ?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> દ્વારા સૂચવાયેલ"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"હા"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"ના"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"સૂચવેલા વાઇ-ફાઇ નેટવર્કને મંજૂરી આપીએ?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> સૂચવેલા નેટવર્ક. ડિવાઇસ ઑટોમૅટિક રીતે કનેક્ટ થાય તેમ બની શકે છે."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"મંજૂરી આપો"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"ના, આભાર"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"વાઇ-ફાઇ આપમેળે ચાલુ થઈ જશે"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"જ્યારે તમે એક ઉચ્ચ ક્વૉલિટીવાળા સાચવેલ નેટવર્કની નજીક હોવ"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"પાછું ચાલુ કરશો નહીં"</string> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index d7a8ea533c3e..bd7da7d3d26b 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"सभी नेटवर्क देखने के लिए यहां पर टैप करें"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"कनेक्ट करें"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"सभी नेटवर्क"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"वाई-फ़ाई नेटवर्क से कनेक्ट करना चाहते हैं?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> का सुझाया हुआ"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"हां"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"नहीं"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"सुझाए गए वाई-फ़ाई नेटवर्क को अनुमति देना चाहते हैं?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> के सुझाए गए नेटवर्क. डिवाइस अपने आप कनेक्ट हो सकता है."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"अनुमति दें"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"रहने दें"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"वाई-फ़ाई अपने आप चालू हो जाएगा"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"जब आप किसी अच्छी क्वालिटी वाले सेव किए गए नेटवर्क के पास हों"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"वापस चालू न करें"</string> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index aca3b2d8098e..ef87d72ef583 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -1277,10 +1277,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Dodirnite za prikaz svih mreža"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Poveži"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Sve mreže"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Želite li se povezati s Wi-Fi mrežama?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Preporuka aplikacije <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Da"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ne"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Želite li dopustiti predložene Wi‑Fi mreže?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"Mreže koje predlaže aplikacija <xliff:g id="NAME">%s</xliff:g>. Uređaji se mogu povezati automatski."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Dopusti"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Ne, hvala"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi će se uključiti automatski"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Kada ste u blizini spremljene mreže visoke kvalitete"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Više ne uključuj"</string> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index 6d81d02a2aa9..9e87c8ebb418 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Koppintással megjelenítheti az összes hálózatot"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Kapcsolódás"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Összes hálózat"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Kapcsolódik a Wi-Fi-hálózathoz?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> javasolta"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Igen"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nem"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Engedélyezi a javasolt Wi-Fi-hálózatokat?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"A(z) <xliff:g id="NAME">%s</xliff:g> hálózatokat javasolt. Az eszköz automatikusan csatlakozhat hozzájuk."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Engedélyezés"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Nem, köszönöm"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"A Wi-Fi automatikusan bekapcsol"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Amikor jó minőségű mentett hálózat közelében tartózkodik"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Ne kapcsolódjon vissza"</string> diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml index 4e07d8811273..d90f8c15f4d0 100644 --- a/core/res/res/values-hy/strings.xml +++ b/core/res/res/values-hy/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Հպեք՝ բոլոր ցանցերը տեսնելու համար"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Միանալ"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Բոլոր ցանցերը"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Միանա՞լ Wi-Fi ցանցերին"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Առաջարկվել է <xliff:g id="NAME">%s</xliff:g>-ի կողմից"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Այո"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ոչ"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Թույլատրե՞լ առաջարկվող Wi‑Fi ցանցերի օգտագործումը"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> հավելվածի առաջարկվող ցանցեր: Սարքը կարող է ավտոմատ միանալ:"</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Թույլատրել"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Ոչ, շնորհակալություն"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi-ն ավտոմատ կմիանա"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Լավ ազդանշանով պահված ցանցի տարածքում գտնվելիս"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Նորից չմիացնել"</string> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index 32ec5d555e67..44376b1dd179 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Ketuk untuk melihat semua jaringan"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Hubungkan"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Semua jaringan"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Sambungkan perangkat ke jaringan Wi-Fi?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Disarankan oleh <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ya"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Tidak"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Izinkan jaringan Wi-Fi yang disarankan?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> jaringan yang disarankan. Perangkat dapat terhubung secara otomatis."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Izinkan"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Lain kali"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi akan aktif otomatis"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Saat berada di dekat jaringan berkualitas tinggi yang tersimpan"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Jangan aktifkan kembali"</string> diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml index b06a7f0714c6..325f713e6ebd 100644 --- a/core/res/res/values-is/strings.xml +++ b/core/res/res/values-is/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Ýttu til að sjá öll netkerfi"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Tengjast"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Öll netkerfi"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Tengjast Wi-Fi neti?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Tillaga frá <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Já"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nei"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Leyfa ráðlögð Wi‑Fi net?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> kom með tillögur að netkerfum. Tækið gæti tengst sjálfkrafa."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Leyfa"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Nei, takk"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Kveikt verður sjálfkrafa á Wi‑Fi"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Þegar þú ert nálægt vistuðu hágæðaneti"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Ekki kveikja aftur"</string> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index 98f5fb2a2cd3..9332f61c9678 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tocca per vedere tutte le reti"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Connetti"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Tutte le reti"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Connettersi a reti Wi-Fi?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Consigliato da <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Sì"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"No"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Vuoi consentire le reti Wi-Fi suggerite?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> ha suggerito delle reti. Il dispositivo potrebbe collegarsi automaticamente."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Consenti"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"No, grazie"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Il Wi‑Fi verrà attivato automaticamente"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Quando ti trovi nell\'area di una rete salvata di alta qualità"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Non riattivare"</string> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index 00a37ebd6208..070f678c3b04 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -1299,10 +1299,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"יש להקיש כדי לראות את כל הרשתות"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"התחבר"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"כל הרשתות"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"להתחבר לרשתות Wi‑Fi?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"הוצע על-ידי <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"כן"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"לא"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"לאפשר הצעות לרשתות Wi-Fi?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"הצעות לרשתות <xliff:g id="NAME">%s</xliff:g>. ייתכן שחיבור המכשיר ייעשה באופן אוטומטי."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"אישור"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"לא תודה"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"ה-Wi-Fi יופעל אוטומטית"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"כשתימצאו בקרבת רשת באיכות גבוהה ששמרתם"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"אל תפעיל שוב"</string> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index bc0b67d73f6c..eea2355c08a9 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"すべてのネットワークを表示するにはタップします"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"接続"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"すべてのネットワーク"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Wi-Fi ネットワークに接続しますか?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> によるおすすめ"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"はい"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"いいえ"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Wi‑Fi ネットワーク候補を許可しますか?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> からのネットワーク候補にデバイスが自動的に接続される可能性があります。"</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"許可"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"許可しない"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi-Fi は自動的にオンになります"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"高品質の保存済みネットワークの検出時"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"再度オンにしない"</string> diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml index 896ad137dec9..77cb0682f56e 100644 --- a/core/res/res/values-ka/strings.xml +++ b/core/res/res/values-ka/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"შეეხეთ ყველა ქსელის სანახავად"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"დაკავშირება"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"ყველა ქსელი"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"გსურთ Wi-Fi ქსელებთან დაკავშირება?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"შეთავაზებულია <xliff:g id="NAME">%s</xliff:g>-ის მიერ"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"დიახ"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"არა"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"გსურთ, დაუშვათ შემოთავაზებული Wi‑Fi ქსელები?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> შემოთავაზებული ქსელები. მოწყობილობა შეიძლება ავტომატურად დაუკავშირდეს."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"დაშვება"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"არა, გმადლობთ"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi-Fi ავტომატურად ჩაირთვება"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"როცა შენახულ მაღალხარისხიან ქსელებთან ახლოს იმყოფებით"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"ხელახლა ნუ ჩართავ"</string> diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml index 801e3777e24c..19ccbe55e63b 100644 --- a/core/res/res/values-kk/strings.xml +++ b/core/res/res/values-kk/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Барлық желілерді көру үшін түртіңіз"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Қосылу"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Барлық желілер"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Wi-Fi желісіне жалғансын ба?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> ұсынған."</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Иә"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Жоқ"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Ұсынылған Wi‑Fi желілеріне рұқсат беру керек пе?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> ұсынған желілер. Құрылғы автоматты түрде қосылуы мүмкін."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Рұқсат беру"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Жоқ, рақмет"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi автоматты түрде қосылады"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Сақталған жоғары сапалы желіге жақын болғанда"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Қайта қоспау"</string> diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml index 8bb03e061e7e..88708024d992 100644 --- a/core/res/res/values-km/strings.xml +++ b/core/res/res/values-km/strings.xml @@ -1257,10 +1257,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ចុចដើម្បីមើលបណ្តាញទាំងអស់"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"ភ្ជាប់"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"បណ្ដាញទាំងអស់"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"ភ្ជាប់បណ្តាញ Wi-Fi?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"បានណែនាំដោយ <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"បាទ/ចាស"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"ទេ"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"អនុញ្ញាតឱ្យភ្ជាប់បណ្ដាញ Wi‑Fi ដែលបានណែនាំ?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"បណ្ដាញដែលបានណែនាំរបស់ <xliff:g id="NAME">%s</xliff:g> ។ ឧបករណ៍អាចភ្ជាប់ដោយស្វ័យប្រវត្តិ។"</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"អនុញ្ញាត"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"ទេ អរគុណ"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi នឹងបើកដោយស្វ័យប្រវត្តិ"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"នៅពេលដែលអ្នកនៅជិតបណ្តាញគុណភាពខ្ពស់ដែលបានរក្សាទុក"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"កុំបើកឡើងវិញ"</string> diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml index 46e743bd469f..e95426f1e39f 100644 --- a/core/res/res/values-kn/strings.xml +++ b/core/res/res/values-kn/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ಎಲ್ಲಾ ನೆಟ್ವರ್ಕ್ಗಳನ್ನು ನೋಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"ಸಂಪರ್ಕಿಸಿ"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"ಎಲ್ಲಾ ನೆಟ್ವರ್ಕ್ಗಳು"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ಗಳಿಗೆ ಸಂಪರ್ಕಿಸುವುದೇ?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"ಸೂಚಿಸಿದವರು: <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"ಹೌದು"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"ಇಲ್ಲ"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"ಸೂಚಿಸಿರುವ ನೆಟ್ವರ್ಕ್ಗಳನ್ನು ಅನುಮತಿಸುವುದೇ?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> ಸೂಚಿಸಿರುವ ನೆಟ್ವರ್ಕ್ಗಳು. ಸಾಧನಗಳು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಸಂಪರ್ಕಗೊಳ್ಳಬಹುದು."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"ಅನುಮತಿಸಿ"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"ಬೇಡ"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"ವೈ‑ಫೈ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಆನ್ ಆಗುತ್ತದೆ"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"ನೀವು ಉಳಿಸಿದ ಅಧಿಕ ಗುಣಮಟ್ಟದ ನೆಟ್ವರ್ಕ್ ಸಮೀಪದಲ್ಲಿದ್ದಾಗ"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"ಮತ್ತೆ ಆನ್ ಮಾಡಲು ಹಿಂತಿರುಗಬೇಡಿ"</string> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index 9d547ca682f3..3f278da959e8 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"모든 네트워크를 보려면 탭하세요."</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"연결"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"모든 네트워크"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Wi-Fi 네트워크에 연결하시겠습니까?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g>에서 추천"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"예"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"아니요"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"제안된 Wi‑Fi 네트워크를 허용하시겠습니까?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g>에서 네트워크를 제안했습니다. 기기가 자동으로 연결될 수 있습니다."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"허용"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"허용 안함"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi가 자동으로 사용 설정됨"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"저장된 고품질 네트워크가 가까이 있는 경우"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"다시 사용 설정하지 않음"</string> diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml index 9da12409fd3d..34f1e066cfc3 100644 --- a/core/res/res/values-ky/strings.xml +++ b/core/res/res/values-ky/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Бардык тармактарды көрүү үчүн басыңыз"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Туташуу"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Бардык тармактар"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Wi-Fi тармактарына туташсынбы?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> сунуштайт"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ооба"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Жок"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Сунушталган Wi‑Fi тармактарына туташтырылсынбы?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> сунуштаган тармактар. Түзмөк автоматтык түрдө туташышы мүмкүн."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Уруксат берүү"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Жок, рахмат"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi автоматтык түрдө күйөт"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Байланыш сигналы күчтүү тармактарга жакындаганда"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Өзү кайра күйбөйт"</string> diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml index 55747d0556f4..379b8e7f98f7 100644 --- a/core/res/res/values-lo/strings.xml +++ b/core/res/res/values-lo/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ແຕະເພື່ອເບິ່ງເຄືອຂ່າຍທັງໝົດ"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"ເຊື່ອມຕໍ່"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"ເຄືອຂ່າຍທັງໝົດ"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"ເຊື່ອມຕໍ່ຫາເຄືອຂ່າຍ Wi‑Fi ບໍ?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"ແນະນຳໂດຍ <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"ແມ່ນ"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"ບໍ່ແມ່ນ"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"ອະນຸຍາດເຄືອຂ່າຍ Wi‑Fi ທີ່ແນະນຳບໍ?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"ເຄືອຂ່າຍ <xliff:g id="NAME">%s</xliff:g> ທີ່ແນະນຳ. ອຸປະກອນອາດເຊື່ອມຕໍ່ເອງໂດຍອັດຕະໂນມັດ."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"ອະນຸຍາດ"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"ບໍ່, ຂອບໃຈ"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"ຈະມີການເປີດໃຊ້ Wi‑Fi ອັດຕະໂນມັດ"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"ເມື່ອທ່ານຢູ່ໃກ້ເຄືອຂ່າຍຄຸນນະພາບສູງທີ່ບັນທຶກໄວ້"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"ບໍ່ຕ້ອງເປີດໃຊ້ຄືນໃໝ່"</string> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index f0ce8621142c..10fd95f4e63a 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -1299,10 +1299,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Palieskite, jei norite matyti visus tinklus"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Prisijungti"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Visi tinklai"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Prisijungti prie „Wi-Fi“ tinklų?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Pasiūlė „<xliff:g id="NAME">%s</xliff:g>“"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Taip"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ne"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Leisti siūlomus „Wi‑Fi“ tinklus?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"„<xliff:g id="NAME">%s</xliff:g>“ siūlomi tinklai. Įrenginys gali prisijungti automatiškai."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Leisti"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Ne, ačiū"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"„Wi‑Fi“ bus įjungtas automatiškai"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Kai būsite netoli išsaugoto aukštos kokybės tinklo"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Neįjunkite vėl"</string> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index bed07f26da80..6d29ccae9306 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -1277,10 +1277,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Pieskarieties, lai skatītu visus tīklus"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Izveidot savienojumu"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Visi tīkli"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Vai veidot savienojumus ar Wi-Fi tīkliem?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Iesaka <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Jā"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nē"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Vai atļaut ieteiktos Wi‑Fi tīklus?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"Lietotnes <xliff:g id="NAME">%s</xliff:g> ieteiktie tīkli. Ierīcē var tikt automātiski izveidots savienojums."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Atļaut"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Nē, paldies"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi tiks automātiski ieslēgts"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Kad atrodaties saglabāta augstas kvalitātes tīkla tuvumā"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Neieslēgt atkārtoti"</string> diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml index 357764caab7c..0d6bc720732e 100644 --- a/core/res/res/values-mk/strings.xml +++ b/core/res/res/values-mk/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Допрете за да ги видите сите мрежи"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Поврзете се"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Сите мрежи"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Да се поврзе со Wi-Fi мрежи?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Предложено од <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Да"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Не"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Да се дозволат предложените Wi‑Fi мрежи?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"Предложени мрежи од <xliff:g id="NAME">%s</xliff:g>. Уредот може да се поврзе автоматски."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Дозволи"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Не, фала"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi ќе се вклучи автоматски"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Кога сте во близина на зачувана мрежа со висок квалитет"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Не вклучувај повторно"</string> diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml index 9ad8b1341567..c41dd75dbe5d 100644 --- a/core/res/res/values-ml/strings.xml +++ b/core/res/res/values-ml/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"എല്ലാ നെറ്റ്വർക്കുകളും കാണാൻ ടാപ്പുചെയ്യുക"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"കണക്റ്റുചെയ്യുക"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"എല്ലാ നെറ്റ്വർക്കുകളും"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"വൈഫൈ നെറ്റ്വർക്കുകളിലേക്ക് കണക്റ്റ് ചെയ്യണോ?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> നിർദ്ദേശിച്ചത്"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"ഉവ്വ്"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"ഇല്ല"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"നിർദ്ദേശിച്ച വെെഫെെ നെറ്റ്വർക്കുകൾ അനുവദിക്കണോ?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> നിർദ്ദേശിച്ച നെറ്റ്വർക്കുകൾ. ഉപകരണം സ്വയമേവ കണക്റ്റ് ചെയ്തേക്കാം."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"അനുവദിക്കുക"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"വേണ്ട"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"വൈഫൈ സ്വമേധയാ ഓണാകും"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"നിങ്ങൾ ഉയർന്ന നിലവാരമുള്ള സംരക്ഷിക്കപ്പെട്ട നെറ്റ്വർക്കിനരികിലെത്തുമ്പോൾ"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"തിരികെ ഓണാക്കരുത്"</string> diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml index d5f358b20997..5591925705d5 100644 --- a/core/res/res/values-mn/strings.xml +++ b/core/res/res/values-mn/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Бүх сүлжээг харахын тулд товшино уу"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Холбогдох"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Бүх сүлжээ"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Wi-Fi сүлжээнд холбогдох уу?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> санал болгосон"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Тийм"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Үгүй"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Санал болгосон Wi‑Fi сүлжээг зөвшөөрөх үү?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> сүлжээ санал болголоо. Төхөөрөмж автоматаар холбогдож магадгүй."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Зөвшөөрөх"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Үгүй, баярлалаа"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi автоматаар асна"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Таныг хадгалсан, өндөр чанартай сүлжээний ойролцоо байх үед"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Буцааж асаахгүй"</string> diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml index 65ead3ba765c..0e41b3cdf2ad 100644 --- a/core/res/res/values-mr/strings.xml +++ b/core/res/res/values-mr/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"सर्व नेटवर्क पाहण्यासाठी टॅप करा"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"कनेक्ट करा"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"सर्व नेटवर्क"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"वाय-फाय नेटवर्कशी कनेक्ट करायचे?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> ने सुचवले"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"होय"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"नाही"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"सुचवलेल्या वाय-फाय नेटवर्कना अनुमती द्यायची का?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> सुचवलेली नेटवर्क. डिव्हाइस आपोआप कनेक्ट होऊ शकते."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"अनुमती द्या"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"नाही, नको"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"वाय-फाय आपोआप चालू होईल"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"तुम्ही जेव्हा सेव्ह केलेल्या उच्च दर्जाच्या नेटवर्कजवळ असाल तेव्हा"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"पुन्हा चालू करू नका"</string> diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml index b6743f4b257a..9479db4e45f9 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Ketik untuk melihat semua rangkaian"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Sambung"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Semua rangkaian"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Sambung ke rangkaian Wi-Fi?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Dicadangkan oleh <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ya"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Tidak"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Benarkan rangkaian Wi-Fi yang dicadangkan?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> rangkaian yang dicadangkan. Peranti mungkin disambungkan secara automatik."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Benarkan"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Tidak perlu"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi akan dihidupkan secara automatik"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Apabila anda berada berdekatan dengan rangkaian disimpan yang berkualiti tinggi"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Jangan hidupkan kembali"</string> diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml index 25f8545723b4..2bcbe13a0774 100644 --- a/core/res/res/values-my/strings.xml +++ b/core/res/res/values-my/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ကွန်ရက်အားလုံးကို ကြည့်ရန် တို့ပါ"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"ချိတ်ဆက်ရန်"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"ကွန်ရက်အားလုံး"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Wi‑Fi ကွန်ရက်များသို့ ချိတ်ဆက်လိုပါသလား။"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> က အကြံပြုထားသည်"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Yes"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"No"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"အကြံပြုထားသည့် Wi‑Fi ကွန်ရက်များကို ခွင့်ပြုလိုပါသလား။"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> သည် ကွန်ရက်များကို အကြံပြုထားသည်။ စက်သည် အလိုအလျောက် ချိတ်ဆက်နိုင်သည်။"</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"ခွင့်ပြုရန်"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"မလိုပါ"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi ကို အလိုအလျောက် ပြန်ဖွင့်ပေးလိမ့်ပါမည်"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"သိမ်းဆည်းထားသည့် အရည်အသွေးမြင့်ကွန်ရက်များအနီးသို့ ရောက်ရှိသည့်အခါ"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"ပြန်မဖွင့်ပါနှင့်"</string> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index c6d16987c005..224ea87b4119 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Trykk for å se alle nettverkene"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Koble til"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Alle nettverk"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Vil du koble til Wi-Fi-nettverk?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Foreslått av <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ja"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nei"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Vil du tillate foreslåtte Wi-Fi nettverk?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g>-foreslåtte nettverk. Enheten kan koble til automatisk."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Tillat"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Nei takk"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi slås på automatisk"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Når du er i nærheten av et lagret nettverk av høy kvalitet"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Ikke slå på igjen"</string> diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml index 47392328f27f..5c73f2931f7b 100644 --- a/core/res/res/values-ne/strings.xml +++ b/core/res/res/values-ne/strings.xml @@ -1261,10 +1261,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"सबै नेटवर्कहरू हेर्न ट्याप गर्नुहोस्"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"जडान गर्नुहोस्"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"सबै नेटवर्कहरू"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Wi-Fi नेटवर्कसँग जोड्ने हो?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> ले सुझाव दिएको"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"हो"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"होइन"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"सिफारिस गरिएका Wi‑Fi नेटवर्कहरूलाई अनुमति दिनुहोस्?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> ले सिफारिस गरेका नेटवर्कहरू। यन्त्र स्वतः जडान हुन सक्छ।"</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"अनुमति दिनुहोस्"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"पर्दैन, धन्यवाद"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi स्वतः सक्रिय हुनेछ"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"तपाईं कुनै सुरक्षित गरिएको उच्च गुणस्तरीय नेटवर्कको नजिक हुनुभएको अवस्थामा"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"फेरि सक्रिय नगर्नुहोला"</string> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index fe53b2387f8c..35a5ce15ff3a 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tik om alle netwerken te bekijken"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Verbinding maken"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Alle netwerken"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Verbinding maken met wifi-netwerken?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Voorgesteld door <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ja"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nee"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Voorgestelde wifi-netwerken toestaan?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> heeft netwerken voorgesteld. Apparaat kan automatisch verbinding maken."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Toestaan"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Nee, bedankt"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wifi wordt automatisch ingeschakeld"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Wanneer je in de buurt van een opgeslagen netwerk van hoge kwaliteit bent"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Niet weer inschakelen"</string> diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml index 949de6e385e8..5e87907a84a8 100644 --- a/core/res/res/values-or/strings.xml +++ b/core/res/res/values-or/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ସମସ୍ତ ନେଟ୍ୱର୍କ ଦେଖିବାକୁ ଟାପ୍ କରନ୍ତୁ"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"କନେକ୍ଟ କରନ୍ତୁ"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"ସମସ୍ତ ନେଟ୍ୱର୍କ"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"ୱାଇ-ଫାଇ ନେଟ୍ୱର୍କଗୁଡ଼ିକୁ ସଂଯୁକ୍ତ କରିବେ?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g>ଙ୍କ ଦ୍ୱାରା ପ୍ରସ୍ତାବିତ"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"ହଁ"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"ନାହିଁ"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"ପ୍ରସ୍ତାବିତ ୱାଇ-ଫାଇ ନେଟ୍ୱାର୍କଗୁଡ଼ିକୁ ଅନୁମତି ଦେବେ?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> ପ୍ରସ୍ତାବିତ ନେଟ୍ୱାର୍କଗୁଡ଼ିକ। ଡିଭାଇସ୍ ହୁଏତ ସ୍ୱଚାଳିତ ଭାବେ ସଂଯୋଗ ହୋଇପାରେ।"</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"ଅନୁମତି ଦିଅନ୍ତୁ"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"ନାହିଁ, ଥାଉ"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"ୱାଇ-ଫାଇ ସ୍ୱଚାଳିତ ଭାବେ ଅନ୍ ହେବ"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"ଆପଣ ଏକ ଉଚ୍ଚ-କ୍ୱାଲିଟୀ ବିଶିଷ୍ଟ ସେଭ୍ କରାଯାଇଥିବା ନେଟ୍ୱର୍କ ପାଖରେ ଥିବା ସମୟରେ"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"ପୁଣି ଅନ୍ କରନ୍ତୁ ନାହିଁ"</string> diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml index 4fc980b583b6..00d1320a930d 100644 --- a/core/res/res/values-pa/strings.xml +++ b/core/res/res/values-pa/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"ਸਾਰੇ ਨੈੱਟਵਰਕਾਂ ਨੂੰ ਦੇਖਣ ਲਈ ਟੈਪ ਕਰੋ"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"ਕਨੈਕਟ ਕਰੋ"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"ਸਾਰੇ ਨੈੱਟਵਰਕ"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"ਕੀ ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕਾਂ ਨਾਲ ਕਨੈਕਟ ਕਰਨਾ ਹੈ?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> ਵਲੋਂ ਸੁਝਾਇਆ ਗਿਆ"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"ਹਾਂ"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"ਨਹੀਂ"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"ਕੀ ਸੁਝਾਏ ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕ ਵਰਤਣੇ ਹਨ?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> ਦੇ ਸੁਝਾਏ ਨੈੱਟਵਰਕ। ਸ਼ਾਇਦ ਡੀਵਾਈਸ ਸਵੈਚਲਿਤ ਤੌਰ \'ਤੇ ਕਨੈਕਟ ਹੋਵੇ।"</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"ਵਰਤਣ ਦਿਓ"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"ਨਹੀਂ ਧੰਨਵਾਦ"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"ਵਾਈ‑ਫਾਈ ਸਵੈਚਲਿਤ ਤੌਰ \'ਤੇ ਚੱਲ ਪਵੇਗਾ"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"ਜਦੋਂ ਤੁਸੀਂ ਕਿਸੇ ਰੱਖਿਅਤ ਕੀਤੇ ਉੱਚ-ਗੁਣਵੱਤਾ ਵਾਲੇ ਨੈੱਟਵਰਕ ਦੇ ਨੇੜੇ ਹੋਵੋ"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"ਵਾਪਸ ਚਾਲੂ ਨਾ ਕਰੋ"</string> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index 302f541e3f55..b536eb1678bb 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -1299,10 +1299,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Kliknij, by zobaczyć wszystkie sieci"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Połącz"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Wszystkie sieci"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Nawiązywać połączenia z sieciami Wi-Fi?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Sugestia: <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Tak"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nie"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Zezwalać na sugerowane sieci Wi‑Fi?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"Sugerowane sieci: <xliff:g id="NAME">%s</xliff:g>. Urządzenie może połączyć się automatycznie."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Zezwól"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Nie, dziękuję"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi włączy się automatycznie"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Gdy znajdziesz się w pobliżu zapisanej sieci o mocnym sygnale"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Nie włączaj ponownie"</string> diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml index d0e1bc95e048..a8be5952718d 100644 --- a/core/res/res/values-pt-rBR/strings.xml +++ b/core/res/res/values-pt-rBR/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toque para ver todas as redes"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectar"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Todas as redes"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Conectar a redes Wi-Fi?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Sugerido por <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Sim"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Não"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Permitir redes Wi-Fi sugeridas?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"Redes sugeridas pelo app <xliff:g id="NAME">%s</xliff:g>. O dispositivo pode se conectar automaticamente."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Permitir"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Não"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"O Wi‑Fi será ativado automaticamente"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Quando você estiver perto de uma rede salva de alta qualidade"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Não ativar novamente"</string> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index a4cbc3e13fed..d2efaffe8d24 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toque para ver todas as redes"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Ligar"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Todas as redes"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Pretende estabelecer ligação a redes Wi-Fi?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Sugerida por <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Sim"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Não"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Pretende permitir redes Wi-Fi sugeridas?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"Redes sugeridas por <xliff:g id="NAME">%s</xliff:g>. O dispositivo pode estabelecer ligação automaticamente."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Permitir"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Não, obrigado"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"O Wi‑Fi será ativado automaticamente"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Quando estiver próximo de uma rede de alta qualidade guardada."</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Não reativar"</string> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index d0e1bc95e048..a8be5952718d 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Toque para ver todas as redes"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectar"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Todas as redes"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Conectar a redes Wi-Fi?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Sugerido por <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Sim"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Não"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Permitir redes Wi-Fi sugeridas?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"Redes sugeridas pelo app <xliff:g id="NAME">%s</xliff:g>. O dispositivo pode se conectar automaticamente."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Permitir"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Não"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"O Wi‑Fi será ativado automaticamente"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Quando você estiver perto de uma rede salva de alta qualidade"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Não ativar novamente"</string> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 245864cb4cb5..710b74a23635 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -1277,10 +1277,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Atingeți pentru a vedea toate rețelele"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Conectați-vă"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Toate rețelele"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Vă conectați la rețele Wi-Fi?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Sugerat de <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Da"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nu"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Permiteți rețelele Wi-Fi sugerate?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> a sugerat rețele. Dispozitivul se poate conecta automat."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Permiteți"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Nu, mulțumesc"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi se va activa automat"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Când vă aflați lângă o rețea salvată, de înaltă calitate"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Nu reactivați"</string> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 29c2e124f4b8..98634935c819 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -1299,10 +1299,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Нажмите, чтобы увидеть список сетей"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Подключиться"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Все сети"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Подключиться к сети Wi-Fi?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Предложено приложением \"<xliff:g id="NAME">%s</xliff:g>\""</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Да"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Нет"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Разрешить подключение к предложенным сетям Wi‑Fi?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"Приложение \"<xliff:g id="NAME">%s</xliff:g>\" рекомендует сети, к которым устройство может подключаться автоматически."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Разрешить"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Нет, спасибо"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi-Fi включится автоматически"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Когда вы будете в зоне действия сохраненной сети с хорошим сигналом."</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Не включать снова"</string> diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml index 65b899c10754..e9a413fd33f4 100644 --- a/core/res/res/values-si/strings.xml +++ b/core/res/res/values-si/strings.xml @@ -1257,10 +1257,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"සියලු ජාල බැලීමට තට්ටු කරන්න"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"සම්බන්ධ කරන්න"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"සියලු ජාල"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Wi-Fi ජාල වෙත සම්බන්ධ කරන්නේද?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> විසින් යෝජනා කරන ලදි"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"ඔව්"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"නැත"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"යෝජිත Wi-Fi ජාල ඉඩ දෙන්නද?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> යෝජිත ජාල. උපාංගය ස්වයංක්රියව සම්බන්ධ වනු ඇත."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"ඉඩ දෙන්න"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"එපා, ස්තූතියි"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi ස්වයංක්රියව ක්රියාත්මක වනු ඇත"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"ඔබ උසස් තත්ත්වයේ සුරැකි ජාලයක් අවට සිටින විට"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"නැවත ක්රියාත්මක නොකරන්න"</string> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index ee04effced2b..71636cdd097e 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -1299,10 +1299,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Klepnutím zobrazíte všetky siete"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Pripojiť"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Všetky siete"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Chcete sa pripojiť k sieťam Wi‑Fi?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Navrhuje <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Áno"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nie"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Chcete povoliť navrhované siete Wi‑Fi?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"Siete navrhnuté aplikáciou <xliff:g id="NAME">%s</xliff:g>. Zariadenie sa môže pripojiť automaticky."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Povoliť"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Nie, ďakujem"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi sa zapne automaticky"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Keď budete v blízkosti kvalitnej uloženej siete"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Znova nezapínať"</string> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index 3f1668c3e6e7..91f16e8cc234 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -1299,10 +1299,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Dotaknite se, če si želite ogledati vsa omrežja"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Vzpostavi povezavo"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Vsa omrežja"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Želite vzpostaviti povezavo z omrežji Wi-Fi?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Predlagala aplikacija <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Da"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ne"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Želite dovoliti predlagana omrežja Wi-Fi?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> – predlagana omrežja Naprava se lahko poveže samodejno."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Dovoli"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Ne, hvala"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Povezava Wi‑Fi se bo samodejno vklopila"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Ko ste v bližini zanesljivega shranjenega omrežja"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Ne vklopi znova"</string> @@ -2051,7 +2051,7 @@ <string name="shortcut_restore_signature_mismatch" msgid="2406209324521327518">"Bližnjice ni bilo mogoče obnoviti zaradi neujemanja podpisa aplikacije"</string> <string name="shortcut_restore_unknown_issue" msgid="8703738064603262597">"Bližnjice ni bilo mogoče obnoviti"</string> <string name="shortcut_disabled_reason_unknown" msgid="5276016910284687075">"Bližnjica je onemogočena"</string> - <string name="harmful_app_warning_uninstall" msgid="4837672735619532931">"ODSTRANI"</string> + <string name="harmful_app_warning_uninstall" msgid="4837672735619532931">"ODMESTI"</string> <string name="harmful_app_warning_open_anyway" msgid="596432803680914321">"VSEENO ODPRI"</string> <string name="harmful_app_warning_title" msgid="8982527462829423432">"Zaznana je bila škodljiva aplikacija"</string> <string name="slices_permission_request" msgid="8484943441501672932">"Aplikacija <xliff:g id="APP_0">%1$s</xliff:g> želi prikazati izreze aplikacije <xliff:g id="APP_2">%2$s</xliff:g>"</string> diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml index 49b6dcfb4da1..a1dea50b0655 100644 --- a/core/res/res/values-sq/strings.xml +++ b/core/res/res/values-sq/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Trokit për të parë të gjitha rrjetet"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Lidhu"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Të gjitha rrjetet"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Do të lidhesh me rrjetet Wi-Fi?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Sugjeruar nga <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Po"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Jo"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Të lejohen rrjetet e sugjeruara Wi‑Fi?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"Rrjet e sugjeruara të <xliff:g id="NAME">%s</xliff:g>. Pajisja mund të lidhet automatikisht."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Lejo"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Jo, faleminderit"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi do të aktivizohet automatikisht"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Kur ndodhesh pranë një rrjeti të ruajtur me cilësi të lartë"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Mos e aktivizo përsëri"</string> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index a8a4c5c13d5e..13938de69611 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -1277,10 +1277,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Додирните да бисте видели све мреже"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Повежи"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Све мреже"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Желите ли да се повежете са Wi-Fi мрежама?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> предлаже"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Да"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Не"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Желите да дозволите предложене Wi‑Fi мреже?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"Мреже које предлаже <xliff:g id="NAME">%s</xliff:g>. Уређај ће се можда повезати аутоматски."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Дозволи"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Не, хвала"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi ће се аутоматски укључити"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Када сте у близини сачуване мреже високог квалитета"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Не укључуј поново"</string> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index 12143f490cd0..60c1b66cc1a3 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tryck för att visa alla nätverk"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Anslut"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Alla nätverk"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Vill du ansluta till Wi-Fi-nätverk?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Förslag från <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ja"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Nej"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Vill du tillåta föreslagna Wi-Fi-nätverk?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"Nätverk som föreslagits av <xliff:g id="NAME">%s</xliff:g>. Enheten kan anslutas automatiskt."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Tillåt"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Nej tack"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi-Fi aktiveras automatiskt"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"När du är i närheten av ett sparat nätverk av hög kvalitet"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Återaktivera inte"</string> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index eb9ab2f76d38..bc96aa764e6a 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Gusa ili uone mitandao yote"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Unganisha"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Mitandao yote"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Je, ungependa kuunganisha kwenye mitandao ya Wi-Fi?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Imependekezwa na <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ndiyo"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Hapana"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Ungependa kuruhusu mitandao inayopendekezwa ya Wi-Fi?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"Mitandao inayopendekezwa kwa ajili ya <xliff:g id="NAME">%s</xliff:g>. Huenda kifaa kikaunganisha kiotomatiki."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Ruhusu"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Hapana, asante"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi itawashwa kiotomatiki"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Unapokuwa karibu na mtandao uliohifadhiwa wenye ubora wa juu"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Usiwashe tena"</string> diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml index fb815de04adf..fbca585eb539 100644 --- a/core/res/res/values-ta/strings.xml +++ b/core/res/res/values-ta/strings.xml @@ -364,9 +364,9 @@ <string name="permlab_enableCarMode" msgid="5684504058192921098">"கார் பயன்முறையை இயக்குதல்"</string> <string name="permdesc_enableCarMode" msgid="4853187425751419467">"கார் முறையை இயக்க, ஆப்ஸை அனுமதிக்கிறது."</string> <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"பிற பயன்பாடுகளை மூடுதல்"</string> - <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"பிற பயன்பாடுகளின் பின்புலச் செயல்முறைகளை நிறுத்த ஆப்ஸை அனுமதிக்கிறது. இதனால் பிற பயன்பாடுகள் இயங்குவதை நிறுத்தலாம்."</string> - <string name="permlab_systemAlertWindow" msgid="7238805243128138690">"இந்த ஆப்ஸ் பிற பயன்பாடுகளின் மேலே தோன்றலாம்"</string> - <string name="permdesc_systemAlertWindow" msgid="2393776099672266188">"இந்த ஆப்ஸ் பிற பயன்பாடுகளின் மேலே அல்லது திரையின் பிற பகுதிகளில் தோன்றலாம். இது வழக்கமான ஆப்ஸ் உபயோகத்தில் குறுக்கிட்டு, பிற பயன்பாடுகள் தோன்றும் விதத்தை மாற்றக்கூடும்."</string> + <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"பிற ஆப்ஸின் பின்புலச் செயல்முறைகளை நிறுத்த ஆப்ஸை அனுமதிக்கிறது. இதனால் பிற பயன்பாடுகள் இயங்குவதை நிறுத்தலாம்."</string> + <string name="permlab_systemAlertWindow" msgid="7238805243128138690">"இந்த ஆப்ஸ் பிற ஆப்ஸின் மேலே தோன்றலாம்"</string> + <string name="permdesc_systemAlertWindow" msgid="2393776099672266188">"இந்த ஆப்ஸ் பிற ஆப்ஸின் மேலே அல்லது திரையின் பிற பகுதிகளில் தோன்றலாம். இது வழக்கமான ஆப்ஸ் உபயோகத்தில் குறுக்கிட்டு, பிற பயன்பாடுகள் தோன்றும் விதத்தை மாற்றக்கூடும்."</string> <string name="permlab_runInBackground" msgid="7365290743781858803">"பின்னணியில் இயக்கு"</string> <string name="permdesc_runInBackground" msgid="7370142232209999824">"இந்த ஆப்ஸ், பின்னணியில் இயங்கலாம். இதனால் பேட்டரி விரைவாகத் தீர்ந்துவிடக்கூடும்."</string> <string name="permlab_useDataInBackground" msgid="8694951340794341809">"பின்னணியில் தரவைப் பயன்படுத்து"</string> @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"எல்லா நெட்வொர்க்குகளையும் பார்க்க, தட்டவும்"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"இணை"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"எல்லா நெட்வொர்க்குகளும்"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"வைஃபை நெட்வொக்குகளுடன் இணைக்கவா?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> ஆப்ஸால் பரிந்துரைக்கப்பட்டது"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"சரி"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"வேண்டாம்"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"பரிந்துரைக்கப்பட்ட வைஃபை நெட்வொர்க்குகளை அனுமதிக்க வேண்டுமா?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> பரிந்துரைக்கும் நெட்வொர்க்குகள். சாதனம் தானாக இணைக்கப்படக்கூடும்."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"அனுமதி"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"வேண்டாம்"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"வைஃபை தானாக ஆன் ஆகும்"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"சேமித்த, உயர்தர நெட்வொர்க்கிற்கு அருகில் இருக்கும்போது"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"மீண்டும் ஆன் செய்யாதே"</string> @@ -1378,7 +1378,7 @@ <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"பிற ஆப்ஸின் மேலே காட்டு"</string> - <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> பிற பயன்பாடுகளின் மீது தோன்றுகிறது"</string> + <string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"<xliff:g id="NAME">%s</xliff:g> பிற ஆப்ஸின் மீது தோன்றுகிறது"</string> <string name="alert_windows_notification_title" msgid="3697657294867638947">"<xliff:g id="NAME">%s</xliff:g> பிற ஆப்ஸின் மீது தோன்றுகிறது"</string> <string name="alert_windows_notification_message" msgid="8917232109522912560">"<xliff:g id="NAME">%s</xliff:g> இந்த அம்சத்தைப் பயன்படுத்த வேண்டாம் என நினைத்தால், அமைப்புகளைத் திறந்து அதை முடக்க, தட்டவும்."</string> <string name="alert_windows_notification_turn_off_action" msgid="2902891971380544651">"ஆஃப் செய்"</string> @@ -1999,7 +1999,7 @@ <string name="notification_app_name_settings" msgid="7751445616365753381">"அமைப்புகள்"</string> <string name="notification_appops_camera_active" msgid="5050283058419699771">"கேமரா"</string> <string name="notification_appops_microphone_active" msgid="4335305527588191730">"மைக்ரோஃபோன்"</string> - <string name="notification_appops_overlay_active" msgid="633813008357934729">"உங்கள் திரையில் உள்ள பிற பயன்பாடுகளின் மேல் காட்டுகிறது"</string> + <string name="notification_appops_overlay_active" msgid="633813008357934729">"உங்கள் திரையில் உள்ள பிற ஆப்ஸின் மேல் காட்டுகிறது"</string> <string name="dynamic_mode_notification_channel_name" msgid="2348803891571320452">"வழக்கமான பேட்டரி சேமிப்பானுக்கான விவர அறிவிப்பு"</string> <string name="dynamic_mode_notification_title" msgid="508815255807182035">"வழக்கமாகச் சார்ஜ் செய்வதற்கு முன்பே பேட்டரி தீர்ந்துபோகக்கூடும்"</string> <string name="dynamic_mode_notification_summary" msgid="2541166298550402690">"பேட்டரி நிலையை நீட்டிக்க பேட்டரி சேமிப்பான் இயக்கப்பட்டுள்ளது"</string> diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml index 5e2b46044f4b..d45adafedb77 100644 --- a/core/res/res/values-te/strings.xml +++ b/core/res/res/values-te/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"అన్ని నెట్వర్క్లు చూడటానికి నొక్కండి"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"కనెక్ట్ చేయి"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"అన్ని నెట్వర్క్లు"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Wi‑Fi నెట్వర్క్లకు కనెక్ట్ చేయాలా?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> ద్వారా సూచించబడింది"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"అవును"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"లేదు"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"సూచించిన Wi‑Fi నెట్వర్క్లను అనుమతించాలా?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> సూచించిన నెట్ వర్క్ లు పరికరం ఆటోమేటిక్ గా కనెక్ట్ కాకపోవచ్చు."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"అనుమతించు"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"వద్దు"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi స్వయంచాలకంగా ఆన్ అవుతుంది"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"మీరు అధిక నాణ్యత గల సేవ్ చేసిన నెట్వర్క్కు సమీపంగా ఉన్నప్పుడు"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"తిరిగి ఆన్ చేయవద్దు"</string> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index fdedffaea9a9..aba7edf49726 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -298,7 +298,7 @@ <string name="permgrouplab_microphone" msgid="171539900250043464">"ไมโครโฟน"</string> <string name="permgroupdesc_microphone" msgid="4988812113943554584">"บันทึกเสียง"</string> <string name="permgrouprequest_microphone" msgid="9167492350681916038">"อนุญาตให้ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> บันทึกเสียงไหม"</string> - <string name="permgrouplab_activityRecognition" msgid="1565108047054378642">"กิจกรรมการเคลื่อนไหวร่างกาย"</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="permgrouplab_camera" msgid="4820372495894586615">"กล้องถ่ายรูป"</string> @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"แตะเพื่อดูเครือข่ายทั้งหมด"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"เชื่อมต่อ"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"เครือข่ายทั้งหมด"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"เชื่อมต่อเครือข่าย Wi-Fi ไหม"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"แนะนำโดย <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"ใช่"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"ไม่"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"อนุญาตให้เชื่อมต่อเครือข่าย Wi-Fi ที่แนะนำไหม"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"เครือข่ายที่แนะนำ <xliff:g id="NAME">%s</xliff:g> อุปกรณ์อาจเชื่อมต่อโดยอัตโนมัติ"</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"อนุญาต"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"ไม่เป็นไร"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi จะเปิดโดยอัตโนมัติ"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"เมื่อคุณอยู่ใกล้เครือข่ายคุณภาพสูงที่บันทึกไว้"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"ไม่ต้องเปิดอีกครั้ง"</string> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index c33e5611ce7a..b1543881879e 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"I-tap upang makita ang lahat ng network"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Kumonekta"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Lahat ng network"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Kumonekta sa mga Wi-Fi network?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Iminumungkahi ng <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Oo"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Hindi"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Payagan ang mga iminumungkahing Wi‑Fi network?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"Mga iminumungkahing network ng <xliff:g id="NAME">%s</xliff:g>. Posibleng awtomatikong kumonekta ang device."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Payagan"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Hindi, salamat na lang"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Awtomatikong mag-o-on ang Wi‑Fi"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Kapag malapit ka sa naka-save na network na mataas ang kalidad"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Huwag i-on muli"</string> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index 7d69213ebe0c..6a955915b354 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Tüm ağları görmek için dokunun"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Bağlan"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Tüm ağlar"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Kablosuz ağlara bağlanılsın mı?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Öneren: <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Evet"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Hayır"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Önerilen kablosuz ağlara izin verilsin mi?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> tarafından önerilen ağlar. Cihaz otomatik olarak bağlanabilir."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"İzin ver"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Hayır, teşekkürler"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Kablosuz özelliği otomatik olarak açılacak"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Daha önce kaydedilmiş yüksek kaliteli bir ağın yakınında olduğunuzda"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Tekrar açılmasın"</string> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index f6ce4ebeece9..eb3b4ac3ac4b 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -1299,10 +1299,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Торкніться, щоб побачити всі мережі"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Під’єднатися"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Усі мережі"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Підключатися до мереж Wi-Fi?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Запропоновано додатком <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Так"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Ні"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Дозволити пропоновані мережі Wi‑Fi?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"Мережі, пропоновані додатком <xliff:g id="NAME">%s</xliff:g>. Пристрій може підключитися автоматично."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Дозволити"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Ні, дякую"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi-Fi вмикатиметься автоматично"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Коли ви поблизу збереженої мережі високої якості"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Не вмикати знову"</string> diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml index dba7f8f06f67..446a4d8a4628 100644 --- a/core/res/res/values-ur/strings.xml +++ b/core/res/res/values-ur/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"تمام نیٹ ورکس دیکھنے کیلئے تھپتھپائيں"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"منسلک کریں"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"سبھی نیٹ ورکس"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Wi-Fi نیٹ ورکس سے منسلک کریں؟"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> کی طرف سے تجویز کردہ"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"ہاں"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"نہیں"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"تجویز کردہ Wi‑Fi نیٹ ورکس کو اجازت دیں؟"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> تجویز کردہ نیٹ ورکس۔ آلہ خودکار طور پر منسلک ہو سکتا ہے۔"</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"اجازت ہیں"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"نہیں شکریہ"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi از خود آن ہو جائے گا"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"جب آپ اعلی معیار کے محفوظ کردہ نیٹ ورک کے قریب ہوں"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"دوبارہ آن نہ کریں"</string> diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml index 7a9a72a97cc1..188b34c798f5 100644 --- a/core/res/res/values-uz/strings.xml +++ b/core/res/res/values-uz/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Barcha tarmoqlarni ko‘rish uchun bosing"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Ulanish"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Barcha tarmoqlar"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Wi-Fi tarmoqlarga ulanilsinmi?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"<xliff:g id="NAME">%s</xliff:g> tomonidan taklif etilgan"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Ha"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Yoʻq"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Tavsiya qilingan Wi‑Fi tarmoqlarga ruxsat berilsinmi?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> tavsiya qilgan tarmoqlar. Qurilma avtomatik ulanishi mumkin."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Ruxsat"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Kerak emas"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi avtomatik ravishda yoqiladi"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Saqlangan tarmoqlar ichidan signali yaxshisi hududida ekaningizda"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Qayta yoqilmasin"</string> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index f7da3ed3f41c..adb8540a9db5 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Nhấn để xem tất cả các mạng"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Kết nối"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Tất cả các mạng"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Bạn muốn kết nối với mạng Wi‑Fi?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Do <xliff:g id="NAME">%s</xliff:g> đề xuất"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Có"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Không"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Cho phép các mạng Wi‑Fi được đề xuất?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"Các mạng do <xliff:g id="NAME">%s</xliff:g> đề xuất. Thiết bị có thể kết nối tự động."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Cho phép"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Không, cảm ơn"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi-Fi sẽ tự động bật"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Khi bạn ở gần mạng đã lưu chất lượng cao"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Không bật lại"</string> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index 487e4a020f2c..90ebf08bdc9a 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"点按即可查看所有网络"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"连接"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"所有网络"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"要连接到 WLAN 网络吗?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"由<xliff:g id="NAME">%s</xliff:g>推荐"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"是"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"否"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"是否允许系统连接到建议的 WLAN 网络?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g>建议的网络。设备可能会自动连接到这些网络。"</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"允许"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"不用了"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"WLAN 将自动开启"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"当您位于已保存的高品质网络信号范围内时"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"不要重新开启"</string> diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index c634c68ba954..b00831f9449e 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"輕按即可查看所有網絡"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"連線"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"所有網絡"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"要連線至 Wi-Fi 網絡嗎?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"由 <xliff:g id="NAME">%s</xliff:g> 推薦"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"是"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"否"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"要允許連線至建議的 Wi-Fi 網絡嗎?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"「<xliff:g id="NAME">%s</xliff:g>」已建議網絡連線,裝置可能會自動連接網絡。"</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"允許"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"不用了,謝謝"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi-Fi 將會自動開啟"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"當您位於已儲存的高品質網絡信號範圍內時"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"不要重新開啟"</string> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index 70fcd0cbf4eb..779d2622a95a 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"輕觸即可查看所有網路"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"連線"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"所有網路"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"要連線到 Wi-Fi 網路嗎?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"「<xliff:g id="NAME">%s</xliff:g>」建議的無線網路"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"是"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"否"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"是否允許系統連線到建議的 Wi‑Fi 網路?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"「<xliff:g id="NAME">%s</xliff:g>」建議的網路。裝置可能會自動連線到這些網路。"</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"允許"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"不用了,謝謝"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"Wi‑Fi 將自動開啟"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"當你位於已儲存的高品質網路範圍內時"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"不要重新開啟"</string> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index 9d19775f9af6..f5a3e74e6fe3 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -1255,10 +1255,10 @@ <string name="wifi_available_content_failed_to_connect" msgid="3377406637062802645">"Thepha ukuze ubone onke amanethiwekhi"</string> <string name="wifi_available_action_connect" msgid="2635699628459488788">"Xhuma"</string> <string name="wifi_available_action_all_networks" msgid="4368435796357931006">"Onke amanethiwekhi"</string> - <string name="wifi_suggestion_title" msgid="9099832833531486167">"Xhumeka kumanethiwekhi e-Wi-Fi?"</string> - <string name="wifi_suggestion_content" msgid="5883181205841582873">"Kuphakanyiswe ngu-<xliff:g id="NAME">%s</xliff:g>"</string> - <string name="wifi_suggestion_action_allow_app" msgid="3689946344485394085">"Yebo"</string> - <string name="wifi_suggestion_action_disallow_app" msgid="7977918905605931385">"Cha"</string> + <string name="wifi_suggestion_title" msgid="6396033039578436801">"Vumela amanethiwekhi e-Wi-Fi aphakanyisiwe?"</string> + <string name="wifi_suggestion_content" msgid="5603992011371520746">"<xliff:g id="NAME">%s</xliff:g> amanethiwekhi aphakanyisiwe. Idivayisi ingaxhumeka ngokuzenzakalela."</string> + <string name="wifi_suggestion_action_allow_app" msgid="7978995387498669901">"Vumela"</string> + <string name="wifi_suggestion_action_disallow_app" msgid="6434097275967940372">"Cha ngiyabonga"</string> <string name="wifi_wakeup_onboarding_title" msgid="228772560195634292">"I-Wi-Fi izovuleka ngokuzenzakalela"</string> <string name="wifi_wakeup_onboarding_subtext" msgid="3989697580301186973">"Uma useduze kwenethiwekhi yekhwalithi ephezulu elondoloziwe"</string> <string name="wifi_wakeup_onboarding_action_disable" msgid="838648204200836028">"Ungaphindi uvule"</string> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 1577a227ff67..bfcc8d4a566e 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -4255,4 +4255,9 @@ <!-- The list of packages to automatically opt out of refresh rates higher than 60hz because of known compatibility issues. --> <string-array name="config_highRefreshRateBlacklist"></string-array> + + <!-- Whether or not to hide the navigation bar when the soft keyboard is visible in order to + create additional screen real estate outside beyond the keyboard. Note that the user needs + to have a confirmed way to dismiss the keyboard when desired. --> + <bool name="config_automotiveHideNavBarForKeyboard">false</bool> </resources> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index b4edc4d88c3e..b35a9e9c8af9 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -3390,13 +3390,13 @@ <string name="wifi_available_action_all_networks">All networks</string> <!-- Notification title for a connection to a app suggested wireless network.--> - <string name="wifi_suggestion_title">Connect to Wi\u2011Fi networks?</string> + <string name="wifi_suggestion_title">Allow suggested Wi\u2011Fi networks?</string> <!-- Notification content for a connection to a app suggested wireless network.--> - <string name="wifi_suggestion_content">Suggested by <xliff:g id="name" example="App123">%s</xliff:g></string> + <string name="wifi_suggestion_content"><xliff:g id="name" example="App123">%s</xliff:g> suggested networks. Device may connect automatically. </string> <!-- Notification action for allowing app specified in the notification body.--> - <string name="wifi_suggestion_action_allow_app">Yes</string> + <string name="wifi_suggestion_action_allow_app">Allow</string> <!-- Notification action for disallowing app specified in the notification body.--> - <string name="wifi_suggestion_action_disallow_app">No</string> + <string name="wifi_suggestion_action_disallow_app">No thanks</string> <!--Notification title for Wi-Fi Wake onboarding. This is displayed the first time a user disables Wi-Fi with the feature enabled. --> <string name="wifi_wakeup_onboarding_title">Wi\u2011Fi will turn on automatically</string> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 0d9c4b39fea0..f06b17eb6f1d 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3835,4 +3835,5 @@ <java-symbol type="drawable" name="android_logotype" /> <java-symbol type="layout" name="platlogo_layout" /> + <java-symbol type="bool" name="config_automotiveHideNavBarForKeyboard" /> </resources> diff --git a/core/tests/screenshothelpertests/Android.bp b/core/tests/screenshothelpertests/Android.bp new file mode 100644 index 000000000000..3d54b68b7ddc --- /dev/null +++ b/core/tests/screenshothelpertests/Android.bp @@ -0,0 +1,28 @@ +android_test { + name: "ScreenshotHelperTests", + + srcs: [ + "src/**/*.java", + ], + + static_libs: [ + "frameworks-base-testutils", + "androidx.test.runner", + "androidx.test.rules", + "androidx.test.ext.junit", + "mockito-target-minus-junit4", + "platform-test-annotations", + ], + + libs: [ + "android.test.runner", + "android.test.base", + "android.test.mock", + ], + + platform_apis: true, + test_suites: ["device-tests"], + + certificate: "platform", +} + diff --git a/core/tests/screenshothelpertests/AndroidManifest.xml b/core/tests/screenshothelpertests/AndroidManifest.xml new file mode 100644 index 000000000000..2e12ef4db358 --- /dev/null +++ b/core/tests/screenshothelpertests/AndroidManifest.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + android:installLocation="internalOnly" + package="com.android.internal.util" + android:sharedUserId="android.uid.systemui" > + + <application > + <uses-library android:name="android.test.runner" /> + </application> + + <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" + android:targetPackage="com.android.internal.util" + android:label="Screenshot Helper Tests" /> + + <protected-broadcast android:name="android.intent.action.USER_PRESENT" /> + +</manifest> diff --git a/core/tests/screenshothelpertests/src/com/android/internal/util/ScreenshotHelperTest.java b/core/tests/screenshothelpertests/src/com/android/internal/util/ScreenshotHelperTest.java new file mode 100644 index 000000000000..848364584ef3 --- /dev/null +++ b/core/tests/screenshothelpertests/src/com/android/internal/util/ScreenshotHelperTest.java @@ -0,0 +1,98 @@ +/* + * 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.util; + +import static android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN; +import static android.view.WindowManager.TAKE_SCREENSHOT_SELECTED_REGION; + +import static junit.framework.Assert.assertFalse; +import static junit.framework.Assert.fail; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; + +import android.content.Context; +import android.os.Handler; +import android.os.Looper; + +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +@RunWith(AndroidJUnit4.class) +public final class ScreenshotHelperTest { + private Context mContext; + private ScreenshotHelper mScreenshotHelper; + private Handler mHandler; + + + @Before + public void setUp() { + // `ScreenshotHelper.notifyScreenshotError()` calls `Context.sendBroadcastAsUser()` and + // `Context.bindServiceAsUser`. + // + // This raises a `SecurityException` if the device is locked. Calling either `Context` + // method results in a broadcast of `android.intent.action. USER_PRESENT`. Only the system + // process is allowed to broadcast that `Intent`. + mContext = Mockito.spy(Context.class); + Mockito.doNothing().when(mContext).sendBroadcastAsUser(any(), any()); + Mockito.doReturn(true).when(mContext).bindServiceAsUser(any(), any(), anyInt(), any()); + + mHandler = new Handler(Looper.getMainLooper()); + mScreenshotHelper = new ScreenshotHelper(mContext); + } + + @Test + public void testFullscreenScreenshot() { + mScreenshotHelper.takeScreenshot(TAKE_SCREENSHOT_FULLSCREEN, false, false, mHandler, null); + } + + @Test + public void testSelectedRegionScreenshot() { + mScreenshotHelper.takeScreenshot(TAKE_SCREENSHOT_SELECTED_REGION, false, false, mHandler, + null); + } + + @Test + public void testScreenshotTimesOut() { + long timeoutMs = 10; + + CountDownLatch lock = new CountDownLatch(1); + mScreenshotHelper.takeScreenshot(TAKE_SCREENSHOT_FULLSCREEN, false, false, timeoutMs, + mHandler, + worked -> { + assertFalse(worked); + lock.countDown(); + }); + + try { + // Add tolerance for delay to prevent flakes. + long awaitDurationMs = timeoutMs + 100; + if (!lock.await(awaitDurationMs, TimeUnit.MILLISECONDS)) { + fail("lock never freed"); + } + } catch (InterruptedException e) { + fail("lock interrupted"); + } + } +} diff --git a/core/tests/utiltests/src/com/android/internal/util/XmlUtilsTest.java b/core/tests/utiltests/src/com/android/internal/util/XmlUtilsTest.java index 2596ecefe53d..27f3596f239b 100644 --- a/core/tests/utiltests/src/com/android/internal/util/XmlUtilsTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/XmlUtilsTest.java @@ -16,13 +16,22 @@ package com.android.internal.util; +import static org.junit.Assert.assertArrayEquals; + +import android.util.Xml; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; +import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; + import junit.framework.TestCase; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlSerializer; + public class XmlUtilsTest extends TestCase { // https://code.google.com/p/android/issues/detail?id=63717 @@ -38,4 +47,23 @@ public class XmlUtilsTest extends TestCase { assertEquals("nullValue", deserialized.get(null)); assertEquals("fooValue", deserialized.get("foo")); } + + public void testreadWriteXmlByteArrayValue() throws Exception { + byte[] testByteArray = {0x1 , 0xa, 0xb, 0x9, 0x34, (byte) 0xaa, (byte) 0xba, (byte) 0x99}; + + ByteArrayOutputStream baos = new ByteArrayOutputStream(1024); + XmlSerializer serializer = new FastXmlSerializer(); + serializer.setOutput(baos, StandardCharsets.UTF_8.name()); + serializer.startDocument(null, true); + XmlUtils.writeValueXml(testByteArray, "testByteArray", serializer); + serializer.endDocument(); + + InputStream bais = new ByteArrayInputStream(baos.toByteArray()); + XmlPullParser pullParser = Xml.newPullParser(); + pullParser.setInput(bais, StandardCharsets.UTF_8.name()); + String[] name = new String[1]; + byte[] testByteArrayDeserialized = (byte[]) XmlUtils.readValueXml(pullParser, name); + assertEquals("testByteArray", name[0]); + assertArrayEquals(testByteArray, testByteArrayDeserialized); + } } diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java index b9945cc735d8..e6eaa6964d49 100644 --- a/graphics/java/android/graphics/drawable/GradientDrawable.java +++ b/graphics/java/android/graphics/drawable/GradientDrawable.java @@ -207,7 +207,7 @@ public class GradientDrawable extends Drawable { } public GradientDrawable() { - this(new GradientState(Orientation.TOP_BOTTOM, null), null); + this(new GradientState(Orientation.LEFT_RIGHT, null), null); } /** diff --git a/media/jni/android_media_ImageWriter.cpp b/media/jni/android_media_ImageWriter.cpp index cfcba76d3af2..7a0eeee17b0d 100644 --- a/media/jni/android_media_ImageWriter.cpp +++ b/media/jni/android_media_ImageWriter.cpp @@ -26,6 +26,7 @@ #include <gui/IProducerListener.h> #include <gui/Surface.h> +#include <ui/PublicFormat.h> #include <android_runtime/AndroidRuntime.h> #include <android_runtime/android_view_Surface.h> #include <android_runtime/android_hardware_HardwareBuffer.h> @@ -126,7 +127,7 @@ private: Condition mCondition; std::deque<wp<Surface>> mQueue; - static const nsecs_t kWaitDuration = 20000000; // 20 ms + static const nsecs_t kWaitDuration = 500000000; // 500 ms }; sp<DetachThread> mThread; @@ -401,8 +402,28 @@ static jlong ImageWriter_init(JNIEnv* env, jobject thiz, jobject weakThiz, jobje return 0; } } else { + // Set consumer buffer format to user specified format + PublicFormat publicFormat = static_cast<PublicFormat>(userFormat); + int nativeFormat = mapPublicFormatToHalFormat(publicFormat); + android_dataspace nativeDataspace = mapPublicFormatToHalDataspace(publicFormat); + res = native_window_set_buffers_format(anw.get(), nativeFormat); + if (res != OK) { + ALOGE("%s: Unable to configure consumer native buffer format to %#x", + __FUNCTION__, nativeFormat); + jniThrowRuntimeException(env, "Failed to set Surface format"); + return 0; + } + + res = native_window_set_buffers_data_space(anw.get(), nativeDataspace); + if (res != OK) { + ALOGE("%s: Unable to configure consumer dataspace %#x", + __FUNCTION__, nativeDataspace); + jniThrowRuntimeException(env, "Failed to set Surface dataspace"); + return 0; + } surfaceFormat = userFormat; } + ctx->setBufferFormat(surfaceFormat); env->SetIntField(thiz, gImageWriterClassInfo.mWriterFormat, reinterpret_cast<jint>(surfaceFormat)); diff --git a/packages/CarSystemUI/Android.bp b/packages/CarSystemUI/Android.bp index 589623b0d6cd..bbae9ff51615 100644 --- a/packages/CarSystemUI/Android.bp +++ b/packages/CarSystemUI/Android.bp @@ -26,8 +26,8 @@ android_app { ], static_libs: [ - "CarNotificationLib", "SystemUI-core", + "CarNotificationLib", "SystemUIPluginLib", "SystemUISharedLib", "SettingsLib", @@ -47,6 +47,8 @@ android_app { "androidx.lifecycle_lifecycle-extensions", "SystemUI-tags", "SystemUI-proto", + "dagger2-2.19", + "//external/kotlinc:kotlin-annotations", ], libs: [ diff --git a/packages/CarSystemUI/AndroidManifest.xml b/packages/CarSystemUI/AndroidManifest.xml index 195d4fee5162..261b9f508ccd 100644 --- a/packages/CarSystemUI/AndroidManifest.xml +++ b/packages/CarSystemUI/AndroidManifest.xml @@ -21,4 +21,8 @@ coreApp="true"> <!-- This permission is required to monitor car power state. --> <uses-permission android:name="android.car.permission.CAR_POWER" /> + <!-- This permission is required to get the trusted device list of a user. --> + <uses-permission android:name="android.car.permission.CAR_ENROLL_TRUST"/> + <!-- This permission is required to get bluetooth broadcast. --> + <uses-permission android:name="android.permission.BLUETOOTH" /> </manifest> diff --git a/packages/SystemUI/res/layout/left_docked_overlay.xml b/packages/CarSystemUI/res/drawable/unlock_dialog_background.xml index 430143ca3bc2..bec6ba7b7c4f 100644 --- a/packages/SystemUI/res/layout/left_docked_overlay.xml +++ b/packages/CarSystemUI/res/drawable/unlock_dialog_background.xml @@ -12,8 +12,15 @@ ~ 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. + ~ limitations under the License --> - -<!-- empty stub --> -<merge /> +<shape xmlns:android="http://schemas.android.com/apk/res/android"> + <solid android:color="@color/unlock_dialog_background_color"/> + <padding + android:bottom="@*android:dimen/car_padding_2" + android:left="@*android:dimen/car_padding_2" + android:right="@*android:dimen/car_padding_2" + android:top="@*android:dimen/car_padding_2"/> + <corners + android:radius="@dimen/unlock_dialog_radius"/> +</shape>
\ No newline at end of file diff --git a/packages/CarSystemUI/res/layout/trust_agent_unlock_dialog.xml b/packages/CarSystemUI/res/layout/trust_agent_unlock_dialog.xml new file mode 100644 index 000000000000..9df78f1378b1 --- /dev/null +++ b/packages/CarSystemUI/res/layout/trust_agent_unlock_dialog.xml @@ -0,0 +1,73 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ 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 + --> + +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/unlock_dialog_parent" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:gravity="center"> + + <LinearLayout + android:id="@+id/unlock_dialog" + android:layout_width="@dimen/unlock_dialog_width" + android:layout_height="wrap_content" + android:gravity="center" + android:layout_gravity="center" + android:orientation="vertical" + android:background="@drawable/unlock_dialog_background" + android:padding="@*android:dimen/car_padding_2"> + <FrameLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content"> + <ProgressBar + android:layout_gravity="center" + android:layout_width="@dimen/unlock_dialog_progress_bar_size" + android:layout_height="@dimen/unlock_dialog_progress_bar_size" /> + <ImageView + android:id="@+id/avatar" + android:layout_gravity="center" + android:layout_width="@dimen/unlock_dialog_avatar_size" + android:layout_height="@dimen/unlock_dialog_avatar_size" + android:scaleType="fitCenter"/> + </FrameLayout> + + <TextView + android:id="@+id/user_name" + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:text="@string/unlock_dialog_default_user_name" + android:textSize="@*android:dimen/car_body1_size" + android:textColor="@android:color/white"/> + + <TextView + android:id="@+id/unlocking_text" + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:layout_marginTop="@*android:dimen/car_padding_1" + android:text="@string/unlock_dialog_message_default" + android:textSize="@*android:dimen/car_body4_size" + android:textColor="@color/unlock_dialog_message_text_default"/> + + <Button + android:id="@+id/enter_pin_button" + android:layout_marginTop="@*android:dimen/car_padding_1" + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:text="@string/unlock_dialog_button_text_pin" + style="@style/UnlockDialogButton"/> + </LinearLayout> +</FrameLayout>
\ No newline at end of file diff --git a/packages/CarSystemUI/res/values/colors.xml b/packages/CarSystemUI/res/values/colors.xml index e13c94052281..b81896283570 100644 --- a/packages/CarSystemUI/res/values/colors.xml +++ b/packages/CarSystemUI/res/values/colors.xml @@ -32,7 +32,7 @@ <color name="system_bar_background_opaque">#ff172026</color> <color name="status_bar_background_color">#33000000</color> - <drawable name="system_bar_background">@android:color/transparent</drawable> + <drawable name="system_bar_background">@color/status_bar_background_color</drawable> <!-- The background color of the notification shade --> <color name="notification_shade_background_color">#DD000000</color> diff --git a/packages/CarSystemUI/res/values/colors_car.xml b/packages/CarSystemUI/res/values/colors_car.xml index 69ab3f3cf957..0a3f7aa92d84 100644 --- a/packages/CarSystemUI/res/values/colors_car.xml +++ b/packages/CarSystemUI/res/values/colors_car.xml @@ -26,4 +26,9 @@ <color name="car_user_switcher_add_user_background_color">@*android:color/car_dark_blue_grey_600</color> <color name="car_user_switcher_add_user_add_sign_color">@*android:color/car_body1_light</color> + <!-- colors for unlock dialog --> + <color name="unlock_dialog_background_color">#ff282a2d</color> + <color name="unlock_dialog_message_text_default">@*android:color/car_grey_400</color> + <color name="unlock_dialog_enter_pin_text_color">#ff66b5ff</color> + </resources> diff --git a/packages/CarSystemUI/res/values/dimens_car.xml b/packages/CarSystemUI/res/values/dimens_car.xml index 42a764959545..9cb09c942781 100644 --- a/packages/CarSystemUI/res/values/dimens_car.xml +++ b/packages/CarSystemUI/res/values/dimens_car.xml @@ -43,4 +43,10 @@ <!-- This must be the negative of car_user_switcher_container_height for the animation. --> <dimen name="car_user_switcher_container_anim_height">-420dp</dimen> + <!-- dimensions for the unlock dialog --> + <dimen name="unlock_dialog_width">500dp</dimen> + <dimen name="unlock_dialog_radius">16dp</dimen> + <dimen name="unlock_dialog_avatar_size">100dp</dimen> + <dimen name="unlock_dialog_progress_bar_size">140dp</dimen> + </resources> diff --git a/packages/CarSystemUI/res/values/integers_car.xml b/packages/CarSystemUI/res/values/integers_car.xml index be2cb0d8d900..fb67b302a4ae 100644 --- a/packages/CarSystemUI/res/values/integers_car.xml +++ b/packages/CarSystemUI/res/values/integers_car.xml @@ -31,5 +31,7 @@ <!--Percentage of the screen height, from the bottom, that a notification panel being peeked at will result in remaining closed the panel if released--> <integer name="notification_settle_close_percentage">80</integer> + <!-- The delay before the unlock dialog pops up --> + <integer name="unlock_dialog_delay_ms">0</integer> </resources> diff --git a/packages/CarSystemUI/res/values/strings_car.xml b/packages/CarSystemUI/res/values/strings_car.xml index 83e91c57ccc3..717692e2f02f 100644 --- a/packages/CarSystemUI/res/values/strings_car.xml +++ b/packages/CarSystemUI/res/values/strings_car.xml @@ -29,4 +29,19 @@ <string name="user_add_user_message_setup">When you add a new user, that person needs to set up their space.</string> <!-- Message to inform user that the newly created user will have permissions to update apps for all other users. [CHAR LIMIT=100] --> <string name="user_add_user_message_update">Any user can update apps for all other users.</string> + <!-- Default messages displayed on the unlock dialog before unlock advertising started. [CHAR LIMIT=30]--> + <string name="unlock_dialog_message_default">Waiting\u2026</string> + <!-- Message to inform user that the IHU is looking for trusted device. [CHAR LIMIT=30] --> + <string name="unlock_dialog_message_start">Looking for trusted device\u2026</string> + + <!-- Cancel Button text for user who has PIN as security lock. [CHAR LIMIT=30] --> + <string name="unlock_dialog_button_text_pin">Enter PIN instead</string> + <!-- Cancel Button text for user who has Pattern as security lock. [CHAR LIMIT=30] --> + <string name="unlock_dialog_button_text_pattern">Enter Pattern instead</string> + <!-- Cancel Button text for user who has Password as security lock. [CHAR LIMIT=30] --> + <string name="unlock_dialog_button_text_password">Enter Password instead</string> + <!-- Default user name shows on unlock dialog --> + <string name="unlock_dialog_default_user_name">Default Name</string> + <!-- Default title for unlock dialog --> + <string name="unlock_dialog_title">Unlock Dialogue</string> </resources> diff --git a/packages/CarSystemUI/res/values/styles.xml b/packages/CarSystemUI/res/values/styles.xml index 371bebdebc86..a9423bf6f260 100644 --- a/packages/CarSystemUI/res/values/styles.xml +++ b/packages/CarSystemUI/res/values/styles.xml @@ -46,4 +46,12 @@ <item name="android:layout_width">96dp</item> <item name="android:background">@drawable/nav_button_background</item> </style> + + <style name="UnlockDialogButton"> + <item name="android:background">?android:attr/selectableItemBackground</item> + <item name="android:textAlignment">center</item> + <item name="android:textColor">@color/unlock_dialog_enter_pin_text_color</item> + <item name="android:paddingHorizontal">16dp</item> + <item name="android:textAllCaps">false</item> + </style> </resources>
\ No newline at end of file diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java index 3b278b40acea..c7654e81e0b1 100644 --- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java +++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java @@ -20,12 +20,8 @@ import android.content.Context; import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.ViewMediatorCallback; -import com.android.systemui.car.CarNotificationEntryManager; -import com.android.systemui.car.CarNotificationInterruptionStateProvider; import com.android.systemui.statusbar.car.CarFacetButtonController; import com.android.systemui.statusbar.car.CarStatusBarKeyguardViewManager; -import com.android.systemui.statusbar.notification.NotificationEntryManager; -import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; import com.android.systemui.volume.CarVolumeDialogComponent; import com.android.systemui.volume.VolumeDialogComponent; @@ -33,8 +29,6 @@ import com.android.systemui.volume.VolumeDialogComponent; import javax.inject.Singleton; import dagger.Component; -import dagger.Module; -import dagger.Provides; /** * Class factory to provide car specific SystemUI components. @@ -44,11 +38,14 @@ public class CarSystemUIFactory extends SystemUIFactory { private CarDependencyComponent mCarDependencyComponent; @Override - protected void init(Context context) { - super.init(context); + protected SystemUIRootComponent buildSystemUIRootComponent(Context context) { mCarDependencyComponent = DaggerCarSystemUIFactory_CarDependencyComponent.builder() .contextHolder(new ContextHolder(context)) .build(); + return DaggerCarSystemUIRootComponent.builder() + .dependencyProvider(new com.android.systemui.DependencyProvider()) + .contextHolder(new ContextHolder(context)) + .build(); } public CarDependencyComponent getCarDependencyComponent() { @@ -64,42 +61,9 @@ public class CarSystemUIFactory extends SystemUIFactory { return new CarVolumeDialogComponent(systemUi, context); } - @Override - public NotificationInterruptionStateProvider provideNotificationInterruptionStateProvider( - Context context) { - return new CarNotificationInterruptionStateProvider(context); - } - - @Override - public boolean provideAllowNotificationLongPress() { - return false; - } - - @Module - protected static class ContextHolder { - private Context mContext; - - public ContextHolder(Context context) { - mContext = context; - } - - @Provides - public Context provideContext() { - return mContext; - } - } - @Singleton @Component(modules = ContextHolder.class) public interface CarDependencyComponent { CarFacetButtonController getCarFacetButtonController(); } - - /** - * Use {@link CarNotificationEntryManager}, which does nothing when adding a notification. - */ - @Singleton - public NotificationEntryManager provideNotificationEntryManager(Context context) { - return new CarNotificationEntryManager(context); - } } diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java new file mode 100644 index 000000000000..9a063aa7b791 --- /dev/null +++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java @@ -0,0 +1,97 @@ +/* + * 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 static com.android.systemui.Dependency.LEAK_REPORT_EMAIL_NAME; + +import android.content.Context; + +import com.android.systemui.car.CarNotificationEntryManager; +import com.android.systemui.car.CarNotificationInterruptionStateProvider; +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.NotificationEntryManager; +import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider; +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; + +@Module +abstract class CarSystemUIModule { + + @Binds + abstract NotificationInterruptionStateProvider bindNotificationInterruptionStateProvider( + CarNotificationInterruptionStateProvider notificationInterruptionStateProvider); + + @Singleton + @Provides + @Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME) + static boolean provideAllowNotificationLongPress() { + return false; + } + + /** + * Use {@link CarNotificationEntryManager}, which does nothing when adding a notification. + */ + @Binds + abstract NotificationEntryManager bindNotificationEntryManager( + CarNotificationEntryManager notificationEntryManager); + + @Singleton + @Provides + @Named(LEAK_REPORT_EMAIL_NAME) + static String provideLeakReportEmail() { + return "buganizer-system+181579@google.com"; + } + + @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); + } + + @Binds + abstract SystemUIRootComponent bindSystemUIRootComponent( + CarSystemUIRootComponent systemUIRootComponent); +} diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIRootComponent.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIRootComponent.java new file mode 100644 index 000000000000..d6b766b80939 --- /dev/null +++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIRootComponent.java @@ -0,0 +1,35 @@ +/* + * 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 javax.inject.Singleton; + +import dagger.Component; + +@Singleton +@Component( + modules = { + DependencyProvider.class, + DependencyBinder.class, + ServiceBinder.class, + SystemUIFactory.ContextHolder.class, + SystemUIModule.class, + CarSystemUIModule.class + }) +interface CarSystemUIRootComponent extends SystemUIRootComponent { + +} diff --git a/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java b/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java index 6d9c7bafb2b2..a107dd793551 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java @@ -21,13 +21,19 @@ import android.service.notification.StatusBarNotification; import com.android.systemui.statusbar.notification.NotificationEntryManager; +import javax.inject.Inject; +import javax.inject.Singleton; + /** * Car specific notification entry manager that does nothing when adding a notification. * * <p> This is because system UI notifications are disabled and we have a different implementation. * Please see {@link com.android.car.notification}. */ +@Singleton public class CarNotificationEntryManager extends NotificationEntryManager { + + @Inject public CarNotificationEntryManager(Context context) { super(context); } diff --git a/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationInterruptionStateProvider.java b/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationInterruptionStateProvider.java index 6d960d7b9e21..ec40cc377594 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationInterruptionStateProvider.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationInterruptionStateProvider.java @@ -21,9 +21,15 @@ import android.content.Context; import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider; import com.android.systemui.statusbar.notification.collection.NotificationEntry; +import javax.inject.Inject; +import javax.inject.Singleton; + /** Auto-specific implementation of {@link NotificationInterruptionStateProvider}. */ +@Singleton public class CarNotificationInterruptionStateProvider extends NotificationInterruptionStateProvider { + + @Inject public CarNotificationInterruptionStateProvider(Context context) { super(context); } diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java index 2874ce60bf16..25191f6a9617 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java +++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java @@ -26,11 +26,15 @@ import android.car.Car; import android.car.drivingstate.CarDrivingStateEvent; import android.car.drivingstate.CarUxRestrictionsManager; import android.car.hardware.power.CarPowerManager.CarPowerStateListener; +import android.car.trust.CarTrustAgentEnrollmentManager; import android.content.Context; import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.drawable.Drawable; +import android.inputmethodservice.InputMethodService; +import android.os.IBinder; import android.util.Log; +import android.view.Display; import android.view.GestureDetector; import android.view.Gravity; import android.view.MotionEvent; @@ -61,9 +65,9 @@ import com.android.systemui.Prefs; import com.android.systemui.R; import com.android.systemui.SystemUIFactory; import com.android.systemui.classifier.FalsingLog; -import com.android.systemui.classifier.FalsingManagerFactory; import com.android.systemui.fragments.FragmentHostManager; import com.android.systemui.keyguard.ScreenLifecycle; +import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.qs.QS; import com.android.systemui.qs.car.CarQSFragment; import com.android.systemui.shared.system.ActivityManagerWrapper; @@ -85,8 +89,7 @@ import java.util.Map; /** * A status bar (and navigation bar) tailored for the automotive use case. */ -public class CarStatusBar extends StatusBar implements - CarBatteryController.BatteryViewHandler { +public class CarStatusBar extends StatusBar implements CarBatteryController.BatteryViewHandler { private static final String TAG = "CarStatusBar"; // used to calculate how fast to open or close the window private static final float DEFAULT_FLING_VELOCITY = 0; @@ -167,6 +170,9 @@ public class CarStatusBar extends StatusBar implements private boolean mIsSwipingVerticallyToClose; // Whether heads-up notifications should be shown when shade is open. private boolean mEnableHeadsUpNotificationWhenNotificationShadeOpen; + // If the nav bar should be hidden when the soft keyboard is visible. + private boolean mHideNavBarForKeyboard; + private boolean mBottomNavBarVisible; private final CarPowerStateListener mCarPowerStateListener = (int state) -> { @@ -188,6 +194,17 @@ public class CarStatusBar extends StatusBar implements // builds the nav bar mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class); mDeviceIsProvisioned = mDeviceProvisionedController.isDeviceProvisioned(); + + // Keyboard related setup, before nav bars are created. + mHideNavBarForKeyboard = mContext.getResources().getBoolean( + com.android.internal.R.bool.config_automotiveHideNavBarForKeyboard); + mBottomNavBarVisible = false; + + // Need to initialize screen lifecycle before calling super.start - before switcher is + // created. + mScreenLifecycle = Dependency.get(ScreenLifecycle.class); + mScreenLifecycle.addObserver(mScreenObserver); + super.start(); mTaskStackListener = new TaskStackListenerImpl(); mActivityManagerWrapper = ActivityManagerWrapper.getInstance(); @@ -234,9 +251,6 @@ public class CarStatusBar extends StatusBar implements mPowerManagerHelper.connectToCarService(); mSwitchToGuestTimer = new SwitchToGuestTimer(mContext); - - mScreenLifecycle = Dependency.get(ScreenLifecycle.class); - mScreenLifecycle.addObserver(mScreenObserver); } /** @@ -718,6 +732,13 @@ public class CarStatusBar extends StatusBar implements buildNavBarContent(); attachNavBarWindows(); + // Try setting up the initial state of the nav bar if applicable. + if (result != null) { + setImeWindowStatus(Display.DEFAULT_DISPLAY, result.mImeToken, + result.mImeWindowVis, result.mImeBackDisposition, + result.mShowImeSwitcher); + } + // There has been a car customized nav bar on the default display, so just create nav bars // on external displays. mNavigationBarController.createNavigationBars(false /* includeDefaultDisplay */, result); @@ -756,22 +777,33 @@ public class CarStatusBar extends StatusBar implements } - private void attachNavBarWindows() { + /** + * We register for soft keyboard visibility events such that we can hide the navigation bar + * giving more screen space to the IME. Note: this is optional and controlled by + * {@code com.android.internal.R.bool.config_automotiveHideNavBarForKeyboard}. + */ + @Override + public void setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition, + boolean showImeSwitcher) { + if (!mHideNavBarForKeyboard) { + return; + } - if (mShowBottom) { - WindowManager.LayoutParams lp = new WindowManager.LayoutParams( - LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, - WindowManager.LayoutParams.TYPE_NAVIGATION_BAR, - WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE - | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL - | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH - | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, - PixelFormat.TRANSLUCENT); - lp.setTitle("CarNavigationBar"); - lp.windowAnimations = 0; - mWindowManager.addView(mNavigationBarWindow, lp); + if (mContext.getDisplay().getDisplayId() != displayId) { + return; } + boolean isKeyboardVisible = (vis & InputMethodService.IME_VISIBLE) != 0; + if (!isKeyboardVisible) { + attachBottomNavBarWindow(); + } else { + detachBottomNavBarWindow(); + } + } + + private void attachNavBarWindows() { + attachBottomNavBarWindow(); + if (mShowLeft) { int width = mContext.getResources().getDimensionPixelSize( R.dimen.car_left_navigation_bar_width); @@ -806,7 +838,49 @@ public class CarStatusBar extends StatusBar implements rightlp.gravity = Gravity.RIGHT; mWindowManager.addView(mRightNavigationBarWindow, rightlp); } + } + + /** + * Attaches the bottom nav bar window. Can be extended to modify the specific behavior of + * attaching the bottom nav bar. + */ + protected void attachBottomNavBarWindow() { + if (!mShowBottom) { + return; + } + if (mBottomNavBarVisible) { + return; + } + mBottomNavBarVisible = true; + + WindowManager.LayoutParams lp = new WindowManager.LayoutParams( + LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.TYPE_NAVIGATION_BAR, + WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE + | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL + | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH + | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, + PixelFormat.TRANSLUCENT); + lp.setTitle("CarNavigationBar"); + lp.windowAnimations = 0; + mWindowManager.addView(mNavigationBarWindow, lp); + } + + /** + * Detaches the bottom nav bar window. Can be extended to modify the specific behavior of + * detaching the bottom nav bar. + */ + protected void detachBottomNavBarWindow() { + if (!mShowBottom) { + return; + } + + if (!mBottomNavBarVisible) { + return; + } + mBottomNavBarVisible = false; + mWindowManager.removeView(mNavigationBarWindow); } private void buildBottomBar(int layout) { @@ -877,7 +951,7 @@ public class CarStatusBar extends StatusBar implements KeyguardUpdateMonitor.getInstance(mContext).dump(fd, pw, args); } - FalsingManagerFactory.getInstance(mContext).dump(pw); + Dependency.get(FalsingManager.class).dump(pw); FalsingLog.dump(pw); pw.println("SharedPreferences:"); @@ -956,8 +1030,12 @@ public class CarStatusBar extends StatusBar implements UserSwitcherController userSwitcherController = Dependency.get(UserSwitcherController.class); if (userSwitcherController.useFullscreenUserSwitcher()) { + Car car = Car.createCar(mContext); + CarTrustAgentEnrollmentManager enrollmentManager = (CarTrustAgentEnrollmentManager) car + .getCarManager(Car.CAR_TRUST_AGENT_ENROLLMENT_SERVICE); mFullscreenUserSwitcher = new FullscreenUserSwitcher(this, - mStatusBarWindow.findViewById(R.id.fullscreen_user_switcher_stub), mContext); + mStatusBarWindow.findViewById(R.id.fullscreen_user_switcher_stub), + enrollmentManager, mContext); } else { super.createUserSwitcher(); } @@ -1072,9 +1150,10 @@ public class CarStatusBar extends StatusBar implements // shade is visible to the user. When the notification shade is completely open then // alpha value will be 1. float alpha = (float) height / mNotificationView.getHeight(); - Drawable background = mNotificationView.getBackground(); + Drawable background = mNotificationView.getBackground().mutate(); background.setAlpha((int) (alpha * 255)); + mNotificationView.setBackground(background); } } diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarTrustAgentUnlockDialogHelper.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarTrustAgentUnlockDialogHelper.java new file mode 100644 index 000000000000..ec72ee74f59a --- /dev/null +++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarTrustAgentUnlockDialogHelper.java @@ -0,0 +1,256 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.car; + +import android.app.admin.DevicePolicyManager; +import android.bluetooth.BluetoothAdapter; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.graphics.PixelFormat; +import android.os.Handler; +import android.os.UserHandle; +import android.os.UserManager; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.WindowManager; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.TextView; + +import com.android.internal.widget.LockPatternUtils; +import com.android.systemui.R; + +/** + * A helper class displays an unlock dialog and receives broadcast about detecting trusted device + * & unlocking state to show the appropriate message on the dialog. + */ +class CarTrustAgentUnlockDialogHelper extends BroadcastReceiver{ + private static final String TAG = CarTrustAgentUnlockDialogHelper.class.getSimpleName(); + + private final Context mContext; + private final WindowManager mWindowManager; + private final UserManager mUserManager; + private final WindowManager.LayoutParams mParams; + /** + * Not using Dialog because context passed from {@link FullscreenUserSwitcher} is not an + * activity. + */ + private final View mUnlockDialogLayout; + private final TextView mUnlockingText; + private final Button mButton; + private final IntentFilter mFilter; + private int mUid; + private boolean mIsDialogShowing; + private OnHideListener mOnHideListener; + + CarTrustAgentUnlockDialogHelper(Context context) { + mContext = context; + mUserManager = mContext.getSystemService(UserManager.class); + mWindowManager = mContext.getSystemService(WindowManager.class); + mParams = createLayoutParams(); + mFilter = getIntentFilter(); + + mParams.packageName = mContext.getPackageName(); + mParams.setTitle(mContext.getString(R.string.unlock_dialog_title)); + + mUnlockDialogLayout = LayoutInflater.from(mContext).inflate( + R.layout.trust_agent_unlock_dialog, null); + mUnlockDialogLayout.setLayoutParams(mParams); + + View dialogParent = mUnlockDialogLayout.findViewById(R.id.unlock_dialog_parent); + dialogParent.setOnTouchListener((v, event)-> { + hideUnlockDialog(/* dismissUserSwitcher= */ false); + return true; + }); + View unlockDialog = mUnlockDialogLayout.findViewById(R.id.unlock_dialog); + unlockDialog.setOnTouchListener((v, event) -> { + // If the person taps inside the unlock dialog, the touch event will be intercepted here + // and the dialog will not exit + return true; + }); + mUnlockingText = mUnlockDialogLayout.findViewById(R.id.unlocking_text); + mButton = mUnlockDialogLayout.findViewById(R.id.enter_pin_button); + mButton.setOnClickListener(v -> { + hideUnlockDialog(/* dismissUserSwitcher= */true); + // TODO(b/138250105) Stop unlock advertising + }); + + BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); + if (bluetoothAdapter != null + && bluetoothAdapter.getLeState() == BluetoothAdapter.STATE_BLE_ON) { + mUnlockingText.setText(R.string.unlock_dialog_message_start); + } + } + + /** + * This filter is listening on: + * {@link BluetoothAdapter#ACTION_BLE_STATE_CHANGED} for starting unlock advertising; + * {@link Intent#ACTION_USER_UNLOCKED} for IHU unlocked + */ + private IntentFilter getIntentFilter() { + IntentFilter filter = new IntentFilter(); + filter.addAction(BluetoothAdapter.ACTION_BLE_STATE_CHANGED); + filter.addAction(Intent.ACTION_USER_UNLOCKED); + return filter; + } + + /** + * Show dialog for the given user + */ + void showUnlockDialog(int uid, OnHideListener listener) { + showUnlockDialogAfterDelay(uid, 0, listener); + } + + /** + * Show dialog for the given user after the certain time of delay has elapsed + * + * @param uid the user to unlock + * @param listener listener that listens to dialog hide + */ + void showUnlockDialogAfterDelay(int uid, OnHideListener listener) { + long delayMillis = mContext.getResources().getInteger(R.integer.unlock_dialog_delay_ms); + showUnlockDialogAfterDelay(uid, delayMillis, listener); + } + + /** + * Show dialog for the given user after the supplied delay has elapsed + */ + private void showUnlockDialogAfterDelay(int uid, long delayMillis, OnHideListener listener) { + setUid(uid); + mOnHideListener = listener; + if (!mIsDialogShowing) { + logd("Receiver registered"); + mContext.registerReceiverAsUser(this, UserHandle.ALL, mFilter, + /* broadcastPermission= */ null, + /* scheduler= */ null); + new Handler().postDelayed(() -> { + if (!mUserManager.isUserUnlocked(uid)) { + logd("Showed unlock dialog for user: " + uid + " after " + delayMillis + + " delay."); + mWindowManager.addView(mUnlockDialogLayout, mParams); + } + }, delayMillis); + } + mIsDialogShowing = true; + } + + private void setUid(int uid) { + mUid = uid; + TextView userName = mUnlockDialogLayout.findViewById(R.id.user_name); + userName.setText(mUserManager.getUserInfo(mUid).name); + ImageView avatar = mUnlockDialogLayout.findViewById(R.id.avatar); + avatar.setImageBitmap(mUserManager.getUserIcon(mUid)); + setButtonText(); + } + + private void hideUnlockDialog(boolean dismissUserSwitcher) { + if (!mIsDialogShowing) { + return; + } + mWindowManager.removeView(mUnlockDialogLayout); + logd("Receiver unregistered"); + mContext.unregisterReceiver(this); + if (mOnHideListener != null) { + mOnHideListener.onHide(dismissUserSwitcher); + } + mIsDialogShowing = false; + } + + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (action == null) { + return; + } + switch (action) { + case BluetoothAdapter.ACTION_BLE_STATE_CHANGED: + logd("Received ACTION_BLE_STATE_CHANGED"); + int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1); + if (state == BluetoothAdapter.STATE_BLE_ON) { + logd("Received BLE_ON"); + mUnlockingText.setText(R.string.unlock_dialog_message_start); + } + break; + case Intent.ACTION_USER_UNLOCKED: + int uid = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); + if (uid == mUid) { + logd("IHU unlocked"); + hideUnlockDialog(/* notifyOnHideListener= */false); + } else { + Log.e(TAG, "Received ACTION_USER_UNLOCKED for unexpected uid: " + uid); + } + break; + default: + Log.e(TAG, "Encountered unexpected action when attempting to set " + + "unlock state message: " + action); + } + } + + // Set button text based on screen lock type + private void setButtonText() { + LockPatternUtils lockPatternUtils = new LockPatternUtils(mContext); + int passwordQuality = lockPatternUtils.getActivePasswordQuality(mUid); + switch (passwordQuality) { + // PIN + case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC: + case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX: + mButton.setText(R.string.unlock_dialog_button_text_pin); + break; + // Pattern + case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING: + mButton.setText(R.string.unlock_dialog_button_text_pattern); + break; + // Password + case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC: + case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC: + case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX: + mButton.setText(R.string.unlock_dialog_button_text_password); + break; + default: + Log.e(TAG, "Encountered unexpected screen lock type when attempting to set " + + "button text:" + passwordQuality); + } + } + + private WindowManager.LayoutParams createLayoutParams() { + return new WindowManager.LayoutParams( + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG, + WindowManager.LayoutParams.FLAG_FULLSCREEN + | WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS + | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, + PixelFormat.TRANSLUCENT + ); + } + + private void logd(String message) { + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, message); + } + } + + /** + * Listener used to notify when the dialog is hidden + */ + interface OnHideListener { + void onHide(boolean dismissUserSwitcher); + } +} diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java index 0a167d9acf98..0f7c1ee8ea7e 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java +++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java @@ -18,29 +18,61 @@ package com.android.systemui.statusbar.car; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; +import android.car.trust.CarTrustAgentEnrollmentManager; +import android.car.userlib.CarUserManagerHelper; +import android.content.BroadcastReceiver; import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.UserInfo; +import android.os.UserHandle; +import android.os.UserManager; +import android.util.Log; import android.view.View; import android.view.ViewStub; import androidx.recyclerview.widget.GridLayoutManager; import com.android.systemui.R; +import com.android.systemui.statusbar.car.CarTrustAgentUnlockDialogHelper.OnHideListener; +import com.android.systemui.statusbar.car.UserGridRecyclerView.UserRecord; /** * Manages the fullscreen user switcher. */ public class FullscreenUserSwitcher { + private static final String TAG = FullscreenUserSwitcher.class.getSimpleName(); + // Because user 0 is headless, user count for single user is 2 + private static final int NUMBER_OF_BACKGROUND_USERS = 1; private final UserGridRecyclerView mUserGridView; private final View mParent; private final int mShortAnimDuration; private final CarStatusBar mStatusBar; + private final Context mContext; + private final UserManager mUserManager; + private final CarTrustAgentEnrollmentManager mEnrollmentManager; + private CarTrustAgentUnlockDialogHelper mUnlockDialogHelper; + private UserGridRecyclerView.UserRecord mSelectedUser; + private CarUserManagerHelper mCarUserManagerHelper; + private final BroadcastReceiver mUserUnlockReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "user 0 is unlocked, SharedPreference is accessible."); + } + showDialogForInitialUser(); + mContext.unregisterReceiver(mUserUnlockReceiver); + } + }; + - public FullscreenUserSwitcher(CarStatusBar statusBar, ViewStub containerStub, Context context) { + public FullscreenUserSwitcher(CarStatusBar statusBar, ViewStub containerStub, + CarTrustAgentEnrollmentManager enrollmentManager, Context context) { mStatusBar = statusBar; mParent = containerStub.inflate(); - // Hide the user grid by default. It will only be made visible by clicking on a cancel - // button in a bouncer. - hide(); + mEnrollmentManager = enrollmentManager; + mContext = context; + View container = mParent.findViewById(R.id.container); // Initialize user grid. @@ -50,9 +82,51 @@ public class FullscreenUserSwitcher { mUserGridView.setLayoutManager(layoutManager); mUserGridView.buildAdapter(); mUserGridView.setUserSelectionListener(this::onUserSelected); + mCarUserManagerHelper = new CarUserManagerHelper(context); + mUnlockDialogHelper = new CarTrustAgentUnlockDialogHelper(mContext); + mUserManager = mContext.getSystemService(UserManager.class); mShortAnimDuration = container.getResources() .getInteger(android.R.integer.config_shortAnimTime); + IntentFilter filter = new IntentFilter(Intent.ACTION_USER_UNLOCKED); + if (mUserManager.isUserUnlocked(UserHandle.USER_SYSTEM)) { + // User0 is unlocked, switched to the initial user + showDialogForInitialUser(); + } else { + // listen to USER_UNLOCKED + mContext.registerReceiverAsUser(mUserUnlockReceiver, + UserHandle.getUserHandleForUid(UserHandle.USER_SYSTEM), + filter, + /* broadcastPermission= */ null, + /* scheduler */ null); + } + } + + private void showDialogForInitialUser() { + int initialUser = mCarUserManagerHelper.getInitialUser(); + UserInfo initialUserInfo = mUserManager.getUserInfo(initialUser); + mSelectedUser = new UserRecord(initialUserInfo, + /* isStartGuestSession= */ false, + /* isAddUser= */ false, + /* isForeground= */ true); + // For single user without trusted device, hide the user switcher. + if (!hasMultipleUsers() && !hasTrustedDevice(initialUser)) { + dismissUserSwitcher(); + return; + } + // Show unlock dialog for initial user + if (hasTrustedDevice(initialUser)) { + mUnlockDialogHelper.showUnlockDialogAfterDelay(initialUser, + mOnHideListener); + } + } + + /** + * Check if there is only one possible user to login in. + * In a Multi-User system there is always one background user (user 0) + */ + private boolean hasMultipleUsers() { + return mUserManager.getUserCount() > NUMBER_OF_BACKGROUND_USERS + 1; } /** @@ -77,14 +151,33 @@ public class FullscreenUserSwitcher { } /** - * Every time user clicks on an item in the switcher, we hide the switcher, either - * gradually or immediately. + * Every time user clicks on an item in the switcher, if the clicked user has no trusted device, + * we hide the switcher, either gradually or immediately. * - * We dismiss the entire keyguard if user clicked on the foreground user (user we're already - * logged in as). + * If the user has trusted device, we show an unlock dialog to notify user the unlock state. + * When the unlock dialog is dismissed by user, we hide the unlock dialog and the switcher. + * + * We dismiss the entire keyguard when we hide the switcher if user clicked on the foreground + * user (user we're already logged in as). */ private void onUserSelected(UserGridRecyclerView.UserRecord record) { - if (record.mIsForeground) { + mSelectedUser = record; + if (hasTrustedDevice(record.mInfo.id)) { + mUnlockDialogHelper.showUnlockDialog(record.mInfo.id, mOnHideListener); + return; + } + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "no trusted device enrolled for uid: " + record.mInfo.id); + } + dismissUserSwitcher(); + } + + private void dismissUserSwitcher() { + if (mSelectedUser == null) { + Log.e(TAG, "Request to dismiss user switcher, but no user selected"); + return; + } + if (mSelectedUser.mIsForeground) { hide(); mStatusBar.dismissKeyguard(); return; @@ -106,4 +199,22 @@ public class FullscreenUserSwitcher { }); } + + private boolean hasTrustedDevice(int uid) { + return !mEnrollmentManager.getEnrolledDeviceInfoForUser(uid).isEmpty(); + } + + private OnHideListener mOnHideListener = new OnHideListener() { + @Override + public void onHide(boolean dismissUserSwitcher) { + if (dismissUserSwitcher) { + dismissUserSwitcher(); + } else { + // Re-draw the parent view, otherwise the unlock dialog will not be removed from + // the screen immediately. + mParent.invalidate(); + } + + } + }; } 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/SettingsLib/SearchWidget/res/values-pt-rPT/strings.xml b/packages/SettingsLib/SearchWidget/res/values-pt-rPT/strings.xml index 363d88544a03..7846be161c0f 100644 --- a/packages/SettingsLib/SearchWidget/res/values-pt-rPT/strings.xml +++ b/packages/SettingsLib/SearchWidget/res/values-pt-rPT/strings.xml @@ -17,5 +17,5 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="search_menu" msgid="1604061903696928905">"Pesquisar definições"</string> + <string name="search_menu" msgid="1604061903696928905">"Definições de pesquisa"</string> </resources> diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml index f1fc9f9e3d4e..13890e029274 100644 --- a/packages/SettingsLib/res/values-bn/strings.xml +++ b/packages/SettingsLib/res/values-bn/strings.xml @@ -452,7 +452,7 @@ <string name="cancel" msgid="6859253417269739139">"বাতিল"</string> <string name="okay" msgid="1997666393121016642">"ঠিক আছে"</string> <string name="zen_mode_enable_dialog_turn_on" msgid="8287824809739581837">"চালু করুন"</string> - <string name="zen_mode_settings_turn_on_dialog_title" msgid="2297134204747331078">"\'বিরক্ত করবে না\' মোড চালু করুন"</string> + <string name="zen_mode_settings_turn_on_dialog_title" msgid="2297134204747331078">"\'বিরক্ত করবেন না\' মোড চালু করুন"</string> <string name="zen_mode_settings_summary_off" msgid="6119891445378113334">"কখনও নয়"</string> <string name="zen_interruption_level_priority" msgid="2078370238113347720">"শুধুমাত্র অগ্রাধিকার"</string> <string name="zen_mode_and_condition" msgid="4927230238450354412">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string> diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml index 7874aeb02996..beb1ac546949 100644 --- a/packages/SettingsLib/res/values-es-rUS/strings.xml +++ b/packages/SettingsLib/res/values-es-rUS/strings.xml @@ -141,7 +141,7 @@ <string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Aplicaciones eliminadas"</string> <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Aplicaciones y usuarios eliminados"</string> <string name="data_usage_ota" msgid="5377889154805560860">"Actualizaciones del sistema"</string> - <string name="tether_settings_title_usb" msgid="6688416425801386511">"Conexión a red por USB"</string> + <string name="tether_settings_title_usb" msgid="6688416425801386511">"Conexión USB"</string> <string name="tether_settings_title_wifi" msgid="3277144155960302049">"Hotspot portátil"</string> <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Conexión Bluetooth"</string> <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"Compartir conexión"</string> @@ -286,7 +286,7 @@ <string name="wait_for_debugger_summary" msgid="1766918303462746804">"Esperar que se conecte el depurador para iniciar la aplicación"</string> <string name="debug_input_category" msgid="1811069939601180246">"Entrada"</string> <string name="debug_drawing_category" msgid="6755716469267367852">"Dibujo"</string> - <string name="debug_hw_drawing_category" msgid="6220174216912308658">"Procesamiento acelerado mediante hardware"</string> + <string name="debug_hw_drawing_category" msgid="6220174216912308658">"Representación acelerada mediante hardware"</string> <string name="media_category" msgid="4388305075496848353">"Multimedia"</string> <string name="debug_monitoring_category" msgid="7640508148375798343">"Supervisión"</string> <string name="strict_mode" msgid="1938795874357830695">"Modo estricto"</string> diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml index 3a20d04d7ab2..238eba58e0a5 100644 --- a/packages/SettingsLib/res/values-hi/strings.xml +++ b/packages/SettingsLib/res/values-hi/strings.xml @@ -46,7 +46,7 @@ <string name="wifi_limited_connection" msgid="7717855024753201527">"सीमित कनेक्शन"</string> <string name="wifi_status_no_internet" msgid="5784710974669608361">"इंटरनेट कनेक्शन नहीं है"</string> <string name="wifi_status_sign_in_required" msgid="123517180404752756">"साइन इन करना ज़रूरी है"</string> - <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"ऐक्सेस पॉइंट फ़िलहाल भरा हुआ है"</string> + <string name="wifi_ap_unable_to_handle_new_sta" msgid="5348824313514404541">"एक्सेस पॉइंट फ़िलहाल भरा हुआ है"</string> <string name="connected_via_carrier" msgid="7583780074526041912">"%1$s के ज़रिए कनेक्ट"</string> <string name="available_via_carrier" msgid="1469036129740799053">"%1$s के ज़रिए उपलब्ध"</string> <string name="osu_opening_provider" msgid="5488997661548640424">"<xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g> खोला जा रहा है"</string> @@ -68,7 +68,7 @@ <string name="bluetooth_pairing" msgid="1426882272690346242">"युग्मित कर रहा है…"</string> <string name="bluetooth_connected_no_headset" msgid="616068069034994802">"जुड़ गया (फ़ोन के ऑडियो को छोड़कर)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string> <string name="bluetooth_connected_no_a2dp" msgid="3736431800395923868">"जुड़ गया (मीडिया ऑडियो को छोड़कर)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string> - <string name="bluetooth_connected_no_map" msgid="3200033913678466453">"जुड़ गया (मैसेज का ऐक्सेस नहीं)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string> + <string name="bluetooth_connected_no_map" msgid="3200033913678466453">"जुड़ गया (मैसेज का एक्सेस नहीं)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_no_a2dp" msgid="2047403011284187056">"जुड़ गया (फ़ोन या मीडिया ऑडियो को छोड़कर)<xliff:g id="ACTIVE_DEVICE">%1$s</xliff:g>"</string> <string name="bluetooth_connected_battery_level" msgid="5162924691231307748">"जुड़ गया, बैटरी का लेवल <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> <string name="bluetooth_connected_no_headset_battery_level" msgid="1610296229139400266">"जुड़ गया (फ़ोन के ऑडियो को छोड़कर), बैटरी का लेवल <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g><xliff:g id="ACTIVE_DEVICE">%2$s</xliff:g>"</string> @@ -88,7 +88,7 @@ <string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"संपर्क साझाकरण के लिए उपयोग करें"</string> <string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"इंटरनेट कनेक्शन साझाकरण"</string> <string name="bluetooth_profile_map" msgid="1019763341565580450">"लेख संदेश"</string> - <string name="bluetooth_profile_sap" msgid="5764222021851283125">"सिम ऐक्सेस"</string> + <string name="bluetooth_profile_sap" msgid="5764222021851283125">"सिम एक्सेस"</string> <string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"HD ऑडियो: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string> <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"HD ऑडियो"</string> <string name="bluetooth_profile_hearing_aid" msgid="6680721080542444257">"सुनने में मदद करने वाले डिवाइस"</string> @@ -200,7 +200,7 @@ <string name="development_settings_not_available" msgid="4308569041701535607">"यह उपयोगकर्ता, डेवलपर के लिए सेटिंग और टूल का इस्तेमाल नहीं कर सकता"</string> <string name="vpn_settings_not_available" msgid="956841430176985598">"VPN सेटिंग इस उपयोगकर्ता के लिए उपलब्ध नहीं हैं"</string> <string name="tethering_settings_not_available" msgid="6765770438438291012">"टेदरिंग सेटिंग इस उपयोगकर्ता के लिए उपलब्ध नहीं हैं"</string> - <string name="apn_settings_not_available" msgid="7873729032165324000">"ऐक्सेस पॉइंट के नाम की सेटिंग इस उपयोगकर्ता के लिए मौजूद नहीं हैं"</string> + <string name="apn_settings_not_available" msgid="7873729032165324000">"एक्सेस पॉइंट के नाम की सेटिंग इस उपयोगकर्ता के लिए मौजूद नहीं हैं"</string> <string name="enable_adb" msgid="7982306934419797485">"USB डीबग करना"</string> <string name="enable_adb_summary" msgid="4881186971746056635">"डीबग मोड जब USB कनेक्ट किया गया हो"</string> <string name="clear_adb_keys" msgid="4038889221503122743">"USB डीबग करने की मंज़ूरी रद्द करें"</string> @@ -414,7 +414,7 @@ <string name="disabled" msgid="9206776641295849915">"बंद किया गया"</string> <string name="external_source_trusted" msgid="2707996266575928037">"अनुमति है"</string> <string name="external_source_untrusted" msgid="2677442511837596726">"अनुमति नहीं है"</string> - <string name="install_other_apps" msgid="6986686991775883017">"अनजान ऐप्लिकेशन इंस्टॉल करने का ऐक्सेस"</string> + <string name="install_other_apps" msgid="6986686991775883017">"अनजान ऐप्लिकेशन इंस्टॉल करने का एक्सेस"</string> <string name="home" msgid="3256884684164448244">"सेटिंग का होम पेज"</string> <string-array name="battery_labels"> <item msgid="8494684293649631252">"0%"</item> diff --git a/packages/SettingsLib/res/values-hy/arrays.xml b/packages/SettingsLib/res/values-hy/arrays.xml index 7368f1d105f2..5cffafed6689 100644 --- a/packages/SettingsLib/res/values-hy/arrays.xml +++ b/packages/SettingsLib/res/values-hy/arrays.xml @@ -43,7 +43,7 @@ <item msgid="8937994881315223448">"Միացված է <xliff:g id="NETWORK_NAME">%1$s</xliff:g>-ին"</item> <item msgid="1330262655415760617">"Անջատված"</item> <item msgid="7698638434317271902">"Անջատվում է <xliff:g id="NETWORK_NAME">%1$s</xliff:g>-ից…"</item> - <item msgid="197508606402264311">"Անջատված է"</item> + <item msgid="197508606402264311">"Անջատած է"</item> <item msgid="8578370891960825148">"Անհաջող"</item> <item msgid="5660739516542454527">"Արգելափակված"</item> <item msgid="1805837518286731242">"Վատ ցանցից ժամանակավոր խուսափում"</item> diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml index a74b4ae3ae9e..bf587405c668 100644 --- a/packages/SettingsLib/res/values-hy/strings.xml +++ b/packages/SettingsLib/res/values-hy/strings.xml @@ -263,7 +263,7 @@ <string name="debug_view_attributes" msgid="6485448367803310384">"Միացնել ցուցադրման հատկանիշների ստուգումը"</string> <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Միշտ ակտիվացրած պահել բջջային տվյալները, նույնիսկ Wi‑Fi-ը միացրած ժամանակ (ցանցերի միջև արագ փոխարկման համար):"</string> <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Օգտագործել սարքակազմի արագացման միացումը, եթե հասանելի է"</string> - <string name="adb_warning_title" msgid="6234463310896563253">"Թույլատրե՞լ USB վրիպազերծումը:"</string> + <string name="adb_warning_title" msgid="6234463310896563253">"Թույլատրե՞լ USB-ի վրիպազերծումը:"</string> <string name="adb_warning_message" msgid="7316799925425402244">"USB վրիպազերծումը միայն ծրագրավորման նպատակների համար է: Օգտագործեք այն ձեր համակարգչից տվյալները ձեր սարք պատճենելու համար, առանց ծանուցման ձեր սարքի վրա ծրագրեր տեղադրելու և տվյալների մատյանը ընթերցելու համար:"</string> <string name="adb_keys_warning_message" msgid="5659849457135841625">"Փակե՞լ USB-ի վրիպազերծման մուտքը` անջատելով այն բոլոր համակարգիչներից, որտեղ նախկինում թույլատրել էիք:"</string> <string name="dev_settings_warning_title" msgid="7244607768088540165">"Ընդունե՞լ ծրագրավորման կարգավորումներ:"</string> diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml index 57e690d46b23..cf442b73e721 100644 --- a/packages/SettingsLib/res/values-ta/strings.xml +++ b/packages/SettingsLib/res/values-ta/strings.xml @@ -159,7 +159,7 @@ <string name="tts_default_pitch_title" msgid="6135942113172488671">"ஒலித்திறன்"</string> <string name="tts_default_pitch_summary" msgid="1944885882882650009">"உருவாக்கப்படும் பேச்சின் டோன் பாதிக்கப்படும்"</string> <string name="tts_default_lang_title" msgid="8018087612299820556">"மொழி"</string> - <string name="tts_lang_use_system" msgid="2679252467416513208">"அமைப்பின் மொழியைப் பயன்படுத்தவும்"</string> + <string name="tts_lang_use_system" msgid="2679252467416513208">"அமைப்பின் மொழியில்"</string> <string name="tts_lang_not_selected" msgid="7395787019276734765">"மொழி தேர்ந்தெடுக்கப்படவில்லை"</string> <string name="tts_default_lang_summary" msgid="5219362163902707785">"பேசப்படும் உரைக்கு மொழி சார்ந்த குரலை அமைக்கிறது"</string> <string name="tts_play_example_title" msgid="7094780383253097230">"எடுத்துக்காட்டைக் கவனிக்கவும்"</string> diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml index 5c06c80a049c..4e2d6fa76ad0 100644 --- a/packages/SettingsLib/res/values-vi/strings.xml +++ b/packages/SettingsLib/res/values-vi/strings.xml @@ -201,7 +201,7 @@ <string name="vpn_settings_not_available" msgid="956841430176985598">"Cài đặt VPN không khả dụng cho người dùng này"</string> <string name="tethering_settings_not_available" msgid="6765770438438291012">"Cài đặt chia sẻ kết nối không khả dụng cho người dùng này"</string> <string name="apn_settings_not_available" msgid="7873729032165324000">"Cài đặt tên điểm truy cập không khả dụng cho người dùng này"</string> - <string name="enable_adb" msgid="7982306934419797485">"Gỡ lỗi qua USB"</string> + <string name="enable_adb" msgid="7982306934419797485">"Gỡ lỗi USB"</string> <string name="enable_adb_summary" msgid="4881186971746056635">"Bật chế độ gỡ lỗi khi kết nối USB"</string> <string name="clear_adb_keys" msgid="4038889221503122743">"Thu hồi ủy quyền gỡ lỗi USB"</string> <string name="bugreport_in_power" msgid="7923901846375587241">"Phím tắt báo cáo lỗi"</string> @@ -263,7 +263,7 @@ <string name="debug_view_attributes" msgid="6485448367803310384">"Cho phép kiểm tra thuộc tính của chế độ xem"</string> <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Luôn bật dữ liệu di động ngay cả khi Wi-Fi đang hoạt động (để chuyển đổi mạng nhanh)."</string> <string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Sử dụng tính năng tăng tốc phần cứng khi chia sẻ kết nối nếu có"</string> - <string name="adb_warning_title" msgid="6234463310896563253">"Cho phép gỡ lỗi qua USB?"</string> + <string name="adb_warning_title" msgid="6234463310896563253">"Cho phép gỡ lỗi USB?"</string> <string name="adb_warning_message" msgid="7316799925425402244">"Gỡ lỗi USB chỉ dành cho mục đích phát triển. Hãy sử dụng tính năng này để sao chép dữ liệu giữa máy tính và thiết bị của bạn, cài đặt ứng dụng trên thiết bị của bạn mà không thông báo và đọc dữ liệu nhật ký."</string> <string name="adb_keys_warning_message" msgid="5659849457135841625">"Thu hồi quyền truy cập gỡ lỗi USB từ tất cả máy tính mà bạn đã ủy quyền trước đó?"</string> <string name="dev_settings_warning_title" msgid="7244607768088540165">"Cho phép cài đặt phát triển?"</string> 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/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 17274f418a1e..4f74605b4003 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -20,6 +20,7 @@ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" package="com.android.systemui" android:sharedUserId="android.uid.systemui" + xmlns:tools="http://schemas.android.com/tools" coreApp="true"> <!-- Using OpenGL ES 2.0 --> @@ -259,7 +260,8 @@ android:theme="@style/Theme.SystemUI" android:defaultToDeviceProtectedStorage="true" android:directBootAware="true" - android:appComponentFactory="androidx.core.app.CoreComponentFactory"> + tools:replace="android:appComponentFactory" + android:appComponentFactory=".SystemUIAppComponentFactory"> <!-- Keep theme in sync with SystemUIApplication.onCreate(). Setting the theme on the application does not affect views inflated by services. The application theme is set again from onCreate to take effect for those views. --> diff --git a/packages/SystemUI/docs/dagger.md b/packages/SystemUI/docs/dagger.md index c2159df1cee1..c440fba10135 100644 --- a/packages/SystemUI/docs/dagger.md +++ b/packages/SystemUI/docs/dagger.md @@ -53,7 +53,7 @@ variants (like other form factors e.g. Car). ### Adding injection to a new SystemUI object Anything that depends on any `@Singleton` provider from SystemUIRootComponent -should be declared as an `@Subcomponent` of the root component, this requires +should be declared as a `@Subcomponent` of the root component. This requires declaring your own interface for generating your own modules or just the object you need injected. The subcomponent also needs to be added to SystemUIRootComponent in SystemUIFactory so it can be acquired. @@ -204,6 +204,13 @@ public CustomView(@Named(VIEW_CONTEXT) Context themedViewContext, AttributeSet a } ``` +## Updating Dagger2 + +Binaries can be downloaded from https://repo1.maven.org/maven2/com/google/dagger/ and then loaded +into +[/prebuilts/tools/common/m2/repository/com/google/dagger/](http://cs/android/prebuilts/tools/common/m2/repository/com/google/dagger/) + + ## TODO List - Eliminate usages of Dependency#get diff --git a/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/views/TaskStackView.java index 14fd149d22f4..b89218c81a91 100644 --- a/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/views/TaskStackView.java +++ b/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/views/TaskStackView.java @@ -41,8 +41,10 @@ import android.widget.ScrollView; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; +import com.android.systemui.Dependency; import com.android.systemui.Interpolators; import com.android.systemui.R; +import com.android.systemui.plugins.FalsingManager; import com.android.systemui.recents.LegacyRecentsImpl; import com.android.systemui.recents.RecentsActivity; import com.android.systemui.recents.RecentsActivityLaunchState; @@ -86,15 +88,15 @@ import com.android.systemui.recents.events.ui.focus.NavigateTaskViewEvent; import com.android.systemui.recents.misc.DozeTrigger; import com.android.systemui.recents.misc.ReferenceCountedTrigger; import com.android.systemui.recents.misc.SystemServicesProxy; +import com.android.systemui.recents.model.TaskStack; import com.android.systemui.recents.utilities.AnimationProps; import com.android.systemui.recents.utilities.Utilities; -import com.android.systemui.shared.recents.model.Task; -import com.android.systemui.recents.model.TaskStack; import com.android.systemui.recents.views.grid.GridTaskView; import com.android.systemui.recents.views.grid.TaskGridLayoutAlgorithm; import com.android.systemui.recents.views.grid.TaskViewFocusFrame; - +import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.system.ActivityManagerWrapper; + import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -256,7 +258,8 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal mLayoutAlgorithm = new TaskStackLayoutAlgorithm(context, this); mStableLayoutAlgorithm = new TaskStackLayoutAlgorithm(context, null); mStackScroller = new TaskStackViewScroller(context, this, mLayoutAlgorithm); - mTouchHandler = new TaskStackViewTouchHandler(context, this, mStackScroller); + mTouchHandler = new TaskStackViewTouchHandler( + context, this, mStackScroller, Dependency.get(FalsingManager.class)); mAnimationHelper = new TaskStackAnimationHelper(context, this); mTaskCornerRadiusPx = LegacyRecentsImpl.getConfiguration().isGridEnabled ? res.getDimensionPixelSize(R.dimen.recents_grid_task_view_rounded_corners_radius) : diff --git a/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java b/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java index dd6926c848b4..a7fb4fae09ec 100644 --- a/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java +++ b/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java @@ -37,6 +37,7 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.SwipeHelper; +import com.android.systemui.plugins.FalsingManager; import com.android.systemui.recents.Constants; import com.android.systemui.recents.LegacyRecentsImpl; import com.android.systemui.recents.events.EventBus; @@ -107,7 +108,7 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback { boolean mInterceptedBySwipeHelper; public TaskStackViewTouchHandler(Context context, TaskStackView sv, - TaskStackViewScroller scroller) { + TaskStackViewScroller scroller, FalsingManager falsingManager) { Resources res = context.getResources(); ViewConfiguration configuration = ViewConfiguration.get(context); mContext = context; @@ -119,7 +120,7 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback { mWindowTouchSlop = configuration.getScaledWindowTouchSlop(); mFlingAnimUtils = new FlingAnimationUtils(context, 0.2f); mOverscrollSize = res.getDimensionPixelSize(R.dimen.recents_fling_overscroll_distance); - mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, context) { + mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, context, falsingManager) { @Override protected float getSize(View v) { return getScaledDismissSize(); diff --git a/packages/SystemUI/res-keyguard/values-cs/strings.xml b/packages/SystemUI/res-keyguard/values-cs/strings.xml index 3adc2792ef10..0d88a2074efa 100644 --- a/packages/SystemUI/res-keyguard/values-cs/strings.xml +++ b/packages/SystemUI/res-keyguard/values-cs/strings.xml @@ -41,7 +41,7 @@ <string name="keyguard_low_battery" msgid="9218432555787624490">"Připojte dobíjecí zařízení."</string> <string name="keyguard_instructions_when_pattern_disabled" msgid="8566679946700751371">"Klávesy odemknete stisknutím tlačítka nabídky."</string> <string name="keyguard_network_locked_message" msgid="6743537524631420759">"Síť je blokována"</string> - <string name="keyguard_missing_sim_message_short" msgid="6327533369959764518">"Chybí SIM karta"</string> + <string name="keyguard_missing_sim_message_short" msgid="6327533369959764518">"Není vložena SIM karta"</string> <string name="keyguard_missing_sim_message" product="tablet" msgid="4550152848200783542">"V tabletu není SIM karta."</string> <string name="keyguard_missing_sim_message" product="default" msgid="6585414237800161146">"V telefonu není SIM karta."</string> <string name="keyguard_missing_sim_instructions" msgid="7350295932015220392">"Vložte SIM kartu."</string> diff --git a/packages/SystemUI/res-keyguard/values-fa/strings.xml b/packages/SystemUI/res-keyguard/values-fa/strings.xml index 9c9de22b96d9..22c4c48a7e37 100644 --- a/packages/SystemUI/res-keyguard/values-fa/strings.xml +++ b/packages/SystemUI/res-keyguard/values-fa/strings.xml @@ -37,7 +37,7 @@ <string name="keyguard_plugged_in_wireless" msgid="8404159927155454732">"<xliff:g id="PERCENTAGE">%s</xliff:g> • درحال شارژ بیسیم"</string> <string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • درحال شارژ شدن"</string> <string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • درحال شارژ سریع"</string> - <string name="keyguard_plugged_in_charging_slowly" msgid="509533586841478405">"<xliff:g id="PERCENTAGE">%s</xliff:g> • آهستهآهسته شارژ میشود"</string> + <string name="keyguard_plugged_in_charging_slowly" msgid="509533586841478405">"<xliff:g id="PERCENTAGE">%s</xliff:g> • درحال شارژ آهسته"</string> <string name="keyguard_low_battery" msgid="9218432555787624490">"شارژر را وصل کنید."</string> <string name="keyguard_instructions_when_pattern_disabled" msgid="8566679946700751371">"برای باز کردن قفل روی «منو» فشار دهید."</string> <string name="keyguard_network_locked_message" msgid="6743537524631420759">"شبکه قفل شد"</string> diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml index 21c2c6b879f8..1bfc4c05c92c 100644 --- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml +++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml @@ -24,48 +24,7 @@ android:outlineProvider="none" android:elevation="5dp" > <!-- Put it above the status bar header --> - <LinearLayout - android:id="@+id/keyguard_indication_area" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginBottom="@dimen/keyguard_indication_margin_bottom" - android:layout_gravity="bottom|center_horizontal" - android:orientation="horizontal"> - - <include layout="@layout/left_docked_overlay" /> - - <LinearLayout - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_weight="1" - android:layout_gravity="center_vertical|center_horizontal" - android:orientation="vertical"> - - <com.android.systemui.statusbar.phone.KeyguardIndicationTextView - android:id="@+id/keyguard_indication_enterprise_disclosure" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:gravity="center" - android:paddingStart="@dimen/keyguard_indication_text_padding" - android:paddingEnd="@dimen/keyguard_indication_text_padding" - android:textAppearance="@style/TextAppearance.Keyguard.BottomArea" - android:visibility="gone" /> - - <com.android.systemui.statusbar.phone.KeyguardIndicationTextView - android:id="@+id/keyguard_indication_text" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:gravity="center" - android:paddingStart="@dimen/keyguard_indication_text_padding" - android:paddingEnd="@dimen/keyguard_indication_text_padding" - android:textAppearance="@style/TextAppearance.Keyguard.BottomArea" - android:accessibilityLiveRegion="polite" /> - - </LinearLayout> - - <include layout="@layout/right_docked_overlay" /> - - </LinearLayout> + <include layout="@layout/keyguard_indication_area_overlay" /> <FrameLayout android:id="@+id/preview_container" diff --git a/packages/SystemUI/res/layout/keyguard_indication_area_overlay.xml b/packages/SystemUI/res/layout/keyguard_indication_area_overlay.xml new file mode 100644 index 000000000000..cc30a682757c --- /dev/null +++ b/packages/SystemUI/res/layout/keyguard_indication_area_overlay.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/keyguard_indication_area" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginBottom="@dimen/keyguard_indication_margin_bottom" + android:layout_gravity="bottom|center_horizontal" + android:orientation="vertical"> + + <include layout="@layout/keyguard_indication_text_view" /> + +</LinearLayout>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/keyguard_indication_text_view.xml b/packages/SystemUI/res/layout/keyguard_indication_text_view.xml new file mode 100644 index 000000000000..2b2100c850d8 --- /dev/null +++ b/packages/SystemUI/res/layout/keyguard_indication_text_view.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> + +<merge xmlns:android="http://schemas.android.com/apk/res/android"> + + <com.android.systemui.statusbar.phone.KeyguardIndicationTextView + android:id="@+id/keyguard_indication_enterprise_disclosure" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center" + android:paddingStart="@dimen/keyguard_indication_text_padding" + android:paddingEnd="@dimen/keyguard_indication_text_padding" + android:textAppearance="@style/TextAppearance.Keyguard.BottomArea" + android:visibility="gone"/> + + <com.android.systemui.statusbar.phone.KeyguardIndicationTextView + android:id="@+id/keyguard_indication_text" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center" + android:paddingStart="@dimen/keyguard_indication_text_padding" + android:paddingEnd="@dimen/keyguard_indication_text_padding" + android:textAppearance="@style/TextAppearance.Keyguard.BottomArea" + android:accessibilityLiveRegion="polite"/> +</merge>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/right_docked_overlay.xml b/packages/SystemUI/res/layout/right_docked_overlay.xml deleted file mode 100644 index 430143ca3bc2..000000000000 --- a/packages/SystemUI/res/layout/right_docked_overlay.xml +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - ~ 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. - --> - -<!-- empty stub --> -<merge /> diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index e0907aee49f6..538fdce944ad 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Minder dringende kennisgewings hieronder"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Tik weer om oop te maak"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Swiep op om oop te maak"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Swiep op om weer te probeer"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Jou organisasie bestuur hierdie toestel"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Hierdie toestel word deur <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> bestuur"</string> <string name="phone_hint" msgid="4872890986869209950">"Swiep vanaf ikoon vir foon"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Dit hou dit in sig totdat jy dit ontspeld. Raak en hou Tuis om dit te ontspeld."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Raak en hou die Terug- en Oorsig-knoppie om hierdie skerm te ontspeld"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Raak en hou die Terug- en Tuis-knoppie om hierdie skerm te ontspeld"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Swiep na bo en hou om hierdie skerm te ontspeld"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Het dit"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Nee, dankie"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Skerm is vasgespeld"</string> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index f16193a96863..a3ff5b4d7e83 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"በጣም አስቸካይ ያልሆኑ ማሳወቂያዎች ከታች"</string> <string name="notification_tap_again" msgid="7590196980943943842">"ለመክፈት ዳግም መታ ያድርጉ"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"ለመክፈት በጣት ወደ ላይ ጠረግ ያድርጉ"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"እንደገና ለመሞከር ወደ ላይ ይጥረጉ"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"ይህ መሣሪያ በእርስዎ ድርጅት የሚተዳደር ነው"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"ይህ መሣሪያ በ<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> የሚተዳደር ነው"</string> <string name="phone_hint" msgid="4872890986869209950">"ለስልክ ከአዶ ላይ ጠረግ ያድርጉ"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"ይሄ እስኪነቅሉት ድረስ በእይታ ውስጥ ያስቀምጠዋል። ለመንቀል መነሻ የሚለውን ይንኩ እና ይያዙ።"</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"ይህን ማያ ገጽ ለመንቀል ተመለስ እና አጠቃላይ ዕይታ አዝራሮችን ይንኩ እና ይያዙ"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"ይህን ማያ ገጽ ለመንቀል ተመለስ እና መነሻ የሚለውን ይንኩ እና ይያዙ"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"ይህን ማያ ገጽ ለመንቀል ወደ ላይ ጠርገው ይያዙ"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"ገባኝ"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"አይ፣ አመሰግናለሁ"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"ማያ ገጽ ተሰክቷል"</string> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index 3d297aee1cc2..529ca5c12a9d 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -409,6 +409,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"الإشعارات الأقل إلحاحًا أدناه"</string> <string name="notification_tap_again" msgid="7590196980943943842">"انقر مرة أخرى للفتح"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"يمكنك الفتح بالتمرير سريعًا لأعلى."</string> + <string name="keyguard_retry" msgid="5221600879614948709">"مرِّر سريعًا للأعلى لإعادة المحاولة."</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"تتولى مؤسستك إدارة هذا الجهاز."</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"تتم إدارة هذا الجهاز بواسطة <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"يمكنك التمرير سريعًا من الرمز لتشغيل الهاتف"</string> @@ -556,6 +557,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"يؤدي هذا إلى استمرار عرض الشاشة المُختارة إلى أن تتم إزالة تثبيتها. المس مع الاستمرار زر \"الشاشة الرئيسية\" لإزالة التثبيت."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"لإزالة تثبيت هذه الشاشة، يمكنك أن تلمس مع الاستمرار زرّي \"رجوع\" و\"نظرة عامة\"."</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"لإزالة تثبيت هذه الشاشة، يمكنك أن تلمس مع الاستمرار زرّي \"رجوع\" و\"الشاشة الرئيسية\"."</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"مرّر الشاشة بسرعة للأعلى مع الاستمرار لإزالة تثبيت الشاشة."</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"حسنًا"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"لا، شكرًا"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"تمّ تثبيت الشاشة."</string> diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml index c7b5f0893711..7d8ba648e1bb 100644 --- a/packages/SystemUI/res/values-as/strings.xml +++ b/packages/SystemUI/res/values-as/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"কম জৰুৰী জাননীসমূহ তলত"</string> <string name="notification_tap_again" msgid="7590196980943943842">"খুলিবলৈ পুনৰাই টিপক"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"খুলিবলৈ ওপৰলৈ ছোৱাইপ কৰক"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"পুনৰ চেষ্টা কৰিবলৈ ওপৰলৈ ছোৱাইপ কৰক"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"আপোনাৰ প্ৰতিষ্ঠানে এই ডিভাইচটো পৰিচালনা কৰে"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"এই ডিভাইচটো <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>ৰ দ্বাৰা পৰিচালিত।"</string> <string name="phone_hint" msgid="4872890986869209950">"ফ\'নৰ বাবে আইকনৰপৰা ছোৱাইপ কৰক"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"এই কাৰ্যই আপুনি আনপিন নকৰালৈকে ইয়াক দেখা পোৱা অৱস্থাত ৰাখে। আনপিন কৰিবলৈ পিছলৈ যাওক আৰু হ\'মত স্পৰ্শ কৰি সেঁচি ধৰক।"</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"এই স্ক্ৰীণখন আনপিন কৰিবলৈ পিছলৈ যাওক আৰু অৱলোকন বুটামত স্পৰ্শ কৰি হেঁচি ধৰক।"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"এই স্ক্ৰীণখন আনপিন কৰিবলৈ পিছলৈ যাওক আৰু হ\'ম বুটামত স্পৰ্শ কৰি হেঁচি ধৰক।"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"এই স্ক্রীণখন আনপিন কৰিবলৈ ওপৰলৈ ছোৱাইপ কৰি ধৰি ৰাখক"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"বুজি পালোঁ"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"নালাগে, ধন্যবাদ"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"স্ক্ৰীণ পিন কৰা হ’ল"</string> diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml index 847d10d20861..5ae4d2df4636 100644 --- a/packages/SystemUI/res/values-az/strings.xml +++ b/packages/SystemUI/res/values-az/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Daha az təcili bildirişlər aşağıdadır"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Açmaq üçün yenidən tıklayın"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Açmaq üçün yuxarı sürüşdürün"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Yenidən cəhd etmək üçün yuxarı sürüşdürün"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Bu cihaz təşkilatınız tərəfindən idarə olunur"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Bu cihaz <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> tərəfindən idarə olunur"</string> <string name="phone_hint" msgid="4872890986869209950">"Telefon üçün ikonadan sürüşdürün"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Sancaq götürülənə qədər bu görünəcək. Sancağı götürmək üçün Əsas səhifə düyməsinə basıb saxlayın."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Bu ekrandan sancağı götürmək üçün Geri və İcmal düymələrinə basıb saxlayın"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Bu ekrandan sancağı götürmək üçün Geri və Əsas səhifə düymələrinə basıb saxlayın"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Bu ekranı sancaqdan çıxarmaq üçün sürüşdürüb saxlayın"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Anladım!"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Yox, çox sağ olun"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Ekran sancılıb"</string> diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml index 78e9d0463361..95346e4cff82 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml @@ -403,6 +403,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Manje hitna obaveštenja su u nastavku"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Dodirnite ponovo da biste otvorili"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Prevucite nagore da biste otvorili"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Prevucite nagore da biste probali ponovo"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Ovim uređajem upravlja organizacija"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Ovim uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Prevucite od ikone za telefon"</string> @@ -547,6 +548,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Na ovaj način se ovo stalno prikazuje dok ga ne otkačite. Dodirnite i zadržite Početna da biste ga otkačili."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Da biste otkačili ovaj ekran, dodirnite i zadržite dugmad Nazad i Pregled"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Da biste otkačili ovaj ekran, dodirnite i zadržite dugmad Nazad i Početna"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Da biste otkačili ovaj ekran, prevucite nagore i zadržite"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Važi"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Ne, hvala"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Ekran je zakačen"</string> diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml index a6b46697db28..36745648b051 100644 --- a/packages/SystemUI/res/values-be/strings.xml +++ b/packages/SystemUI/res/values-be/strings.xml @@ -407,6 +407,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Менш тэрміновыя апавяшчэнні ніжэй"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Дакраніцеся яшчэ раз, каб адкрыць"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Каб адкрыць, прагарніце ўверх"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Прагартайце ўверх, каб паўтарыць спробу"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Гэта прылада знаходзіцца пад кіраваннем вашай арганізацыі"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Гэта прылада знаходзіцца пад кіраваннем <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Тэлефон: правядзіце пальцам ад значка"</string> @@ -552,6 +553,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Будзе паказвацца, пакуль не адмацуеце. Каб адмацаваць, націсніце і ўтрымлівайце кнопку \"Галоўны экран\"."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Каб адмацаваць гэты экран, націсніце і ўтрымлівайце кнопкі \"Назад\" і \"Агляд\""</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Каб адмацаваць гэты экран, націсніце і ўтрымлівайце кнопкі \"Назад\" і \"Галоўны экран\""</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Каб адмацаваць экран, правядзіце пальцам, утрымліваючы яго на экране"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Зразумела"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Не, дзякуй"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Экран замацаваны"</string> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index a0128ebf74b3..1618e059765d 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Ппоказване на по-малко спешните известия по-долу"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Докоснете отново, за да отворите"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Прекарайте пръст нагоре, за да отключите"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Прекарайте пръст нагоре, за да опитате отново"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Това устройство се управлява от организацията ви"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Това устройство се управлява от <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Плъзнете с пръст от иконата, за да използвате телефона"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Екранът ще се показва, докато не го освободите с докосване и задържане на бутона „Начало“."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"За да освободите този екран, докоснете и задръжте бутона за връщане назад и този за общ преглед"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"За да освободите този екран, докоснете и задръжте бутона за връщане назад и „Начало“"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"За да освободите този екран, прекарайте пръст нагоре и задръжте"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Разбрах"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Не, благодаря"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Екранът е фиксиран"</string> diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml index bf55d520d425..6b7561bdcd3b 100644 --- a/packages/SystemUI/res/values-bn/strings.xml +++ b/packages/SystemUI/res/values-bn/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"নিচে অপেক্ষাকৃত কম জরুরী বিজ্ঞপ্তিগুলি"</string> <string name="notification_tap_again" msgid="7590196980943943842">"খোলার জন্য আবার আলতো চাপুন"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"খোলার জন্য উপরে সোয়াইপ করুন"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"আবার চেষ্টা করতে উপরের দিকে সোয়াইপ করুন"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"আপনার সংস্থা এই ডিভাইসটি পরিচালনা করছে"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"এই ডিভাইসটি <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> এর দ্বারা পরিচালিত"</string> <string name="phone_hint" msgid="4872890986869209950">"ফোনের জন্য আইকন থেকে সোয়াইপ করুন"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"এর ফলে আপনি এটি আনপিন না করা পর্যন্ত এটি দেখানো হতে থাকবে। আনপিন করতে \"হোম\" বোতামটি ট্যাপ করে ধরে রাখুন।"</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"এই স্ক্রিনটি আনপিন করতে \"ফিরে যান\" এবং \"এক নজরে\" বোতামদুটি ট্যাপ করে ধরে রাখুন"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"এই স্ক্রিনটি আনপিন করতে \"ফিরে যান\" এবং \"হোম\" বোতামদুটি ট্যাপ করে ধরে রাখুন"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"আনপিন করতে এই স্ক্রিনটি উপরের দিকে সোয়াইপ করে ধরে রাখুন"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"বুঝেছি"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"না থাক"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"স্ক্রিন পিন করা হয়েছে"</string> diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml index d7e5c230e833..c22ddfd56e9f 100644 --- a/packages/SystemUI/res/values-bs/strings.xml +++ b/packages/SystemUI/res/values-bs/strings.xml @@ -403,6 +403,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Prikaži manje važna obavještenja ispod"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Dodirnite ponovo da otvorite"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Prevucite da otvorite"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Prevucite prema gore da pokušate ponovo"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Ovim uređajem upravlja vaša organizacija"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Ovim uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Prevucite preko ikone da otvorite telefon"</string> @@ -547,6 +548,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Na ovaj način ekran ostaje prikazan dok ga ne otkačite. Da okačite ekran, dodirnite ili držite dugme Početna."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Dodirnite i držite dugmad Nazad i Pregled da otkačite ekran"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Dodirnite i držite dugmad Nazad i Početna da otkačite ekran."</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Da otkačite ovaj ekran, prevucite prema gore i zadržite"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Razumijem"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Ne, hvala"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Ekran je zakačen"</string> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index 23d5d5c15c2f..d4147bad6c34 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Notificacions menys urgents a continuació"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Torna a tocar per obrir-la."</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Llisca cap amunt per obrir"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Llisca cap a dalt per tornar-ho a provar"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"La teva organització gestiona aquest dispositiu"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> gestiona aquest dispositiu"</string> <string name="phone_hint" msgid="4872890986869209950">"Llisca des de la icona per obrir el telèfon"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Aquest element es continuarà mostrant fins que deixis de fixar-lo. Per fer-ho, mantén premut el botó d\'inici."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Per deixar de fixar aquesta pantalla, mantén premuts els botons Enrere i Aplicacions recents"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Per deixar de fixar aquesta pantalla, mantén premuts els botons Enrere i Inici"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Per deixar de fixar aquesta pantalla, fes-la lliscar cap a dalt i mantén-la premuda"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Entesos"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"No, gràcies"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"S\'ha fitxat la pantalla"</string> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index 9c765d910752..87aaa94d1dd3 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -405,6 +405,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Méně urgentní oznámení níže"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Oznámení otevřete opětovným klepnutím"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Otevřete přejetím prstem nahoru"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Přejetím nahoru to zkusíte znovu"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Toto zařízení spravuje vaše organizace"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Toto zařízení je spravováno organizací <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Telefon otevřete přejetím prstem od ikony"</string> @@ -550,6 +551,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Obsah bude připnut v zobrazení, dokud ho neuvolníte. Uvolníte ho podržením tlačítka Plocha."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Chcete-li tuto obrazovku uvolnit, podržte tlačítka Zpět a Přehled"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Chcete-li tuto obrazovku uvolnit, podržte tlačítka Zpět a Plocha"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Chcete-li tuto obrazovku odepnout, přejeďte prstem nahoru a podržte"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Rozumím"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Ne, děkuji"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Obrazovka připnuta"</string> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index 90ead3514b1d..57c934e5657d 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -215,7 +215,7 @@ <skip /> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notifikationen er annulleret."</string> <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Notifikationspanel."</string> - <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Hurtige indstillinger."</string> + <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Kvikmenu."</string> <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"Låseskærm."</string> <string name="accessibility_desc_settings" msgid="3417884241751434521">"Indstillinger"</string> <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Oversigt."</string> @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Mindre presserende notifikationer nedenfor"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Tryk igen for at åbne"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Stryg opad for at åbne"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Stryg opad for at prøve igen"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Denne enhed administreres af din organisation"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Denne enhed administreres af <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Stryg fra telefonikonet"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Dette fastholder skærmen i visningen, indtil du frigør den. Hold Startskærm nede for at frigøre skærmen."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Hold knapperne Tilbage og Oversigt nede for at frigøre skærmen"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Hold knapperne Tilbage og Startskærm nede for at frigøre skærmen"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Stryg opad, og hold fingeren nede for at frigøre denne skærm"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"OK, det er forstået"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Nej tak"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Skærmen blev fastgjort"</string> @@ -586,7 +588,7 @@ <string name="system_ui_tuner" msgid="708224127392452018">"System UI Tuner"</string> <string name="show_battery_percentage" msgid="5444136600512968798">"Vis procent for det indbyggede batteri"</string> <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Vis procenttallet for batteriniveauet i ikonet for statusbjælken, når der ikke oplades"</string> - <string name="quick_settings" msgid="10042998191725428">"Hurtige indstillinger"</string> + <string name="quick_settings" msgid="10042998191725428">"Kvikmenu"</string> <string name="status_bar" msgid="4877645476959324760">"Statusbjælke"</string> <string name="overview" msgid="4018602013895926956">"Oversigt"</string> <string name="demo_mode" msgid="2532177350215638026">"Demotilstand for systemets brugerflade"</string> @@ -602,7 +604,7 @@ <string name="zen_alarm_warning" msgid="444533119582244293">"Du vil ikke kunne høre din næste alarm <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template" msgid="3980063409350522735">"kl. <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template_far" msgid="4242179982586714810">"på <xliff:g id="WHEN">%1$s</xliff:g>"</string> - <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Hurtige indstillinger <xliff:g id="TITLE">%s</xliff:g>."</string> + <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Kvikmenu <xliff:g id="TITLE">%s</xliff:g>."</string> <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Hotspot"</string> <string name="accessibility_managed_profile" msgid="6613641363112584120">"Arbejdsprofil"</string> <string name="tuner_warning_title" msgid="7094689930793031682">"Sjovt for nogle, men ikke for alle"</string> @@ -615,8 +617,8 @@ <string name="activity_not_found" msgid="348423244327799974">"Applikationen er ikke installeret på din enhed."</string> <string name="clock_seconds" msgid="7689554147579179507">"Vis sekunder"</string> <string name="clock_seconds_desc" msgid="6282693067130470675">"Vis sekunder i statuslinjen. Dette kan påvirke batteriets levetid."</string> - <string name="qs_rearrange" msgid="8060918697551068765">"Omarranger Hurtige indstillinger"</string> - <string name="show_brightness" msgid="6613930842805942519">"Vis lysstyrke i Hurtige indstillinger"</string> + <string name="qs_rearrange" msgid="8060918697551068765">"Omarranger Kvikmenu"</string> + <string name="show_brightness" msgid="6613930842805942519">"Vis lysstyrke i Kvikmenu"</string> <string name="experimental" msgid="6198182315536726162">"Eksperimentel"</string> <string name="enable_bluetooth_title" msgid="5027037706500635269">"Vil du slå Bluetooth til?"</string> <string name="enable_bluetooth_message" msgid="9106595990708985385">"Bluetooth skal være slået til, før du kan knytte dit tastatur til din tablet."</string> @@ -811,15 +813,15 @@ <string name="accessibility_qs_edit_remove_tile" msgid="7484493384665907197">"Fjern <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> <string name="accessibility_qs_edit_tile_add" msgid="3520406665865985109">"Føj <xliff:g id="TILE_NAME">%1$s</xliff:g> til position <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_move" msgid="3108103090006972938">"Flyt <xliff:g id="TILE_NAME">%1$s</xliff:g> til position <xliff:g id="POSITION">%2$d</xliff:g>"</string> - <string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Redigeringsværktøj for Hurtige indstillinger."</string> + <string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Redigeringsværktøj til Kvikmenu."</string> <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"<xliff:g id="ID_1">%1$s</xliff:g>-notifikation: <xliff:g id="ID_2">%2$s</xliff:g>"</string> <string name="dock_forced_resizable" msgid="5914261505436217520">"Appen fungerer muligvis ikke i opdelt skærm."</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Appen understøtter ikke opdelt skærm."</string> <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Appen fungerer muligvis ikke på sekundære skærme."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Appen kan ikke åbnes på sekundære skærme."</string> <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"Åbn Indstillinger."</string> - <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"Åbn Hurtige indstillinger."</string> - <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"Luk Hurtige indstillinger."</string> + <string name="accessibility_quick_settings_expand" msgid="2375165227880477530">"Åbn Kvikmenu."</string> + <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"Luk Kvikmenu."</string> <string name="accessibility_quick_settings_alarm_set" msgid="1863000242431528676">"Alarmen er indstillet."</string> <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Logget ind som <xliff:g id="ID_1">%s</xliff:g>"</string> <string name="data_connection_no_internet" msgid="4503302451650972989">"Intet internet"</string> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index 9b3974b423ba..e1fd8db11b3a 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -405,6 +405,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Weniger dringende Benachrichtigungen unten"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Erneut tippen, um Benachrichtigung zu öffnen"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Zum Öffnen nach oben wischen"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Zum Wiederholen nach oben wischen"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Dieses Gerät wird von deiner Organisation verwaltet"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Dieses Gerät wird von <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> verwaltet"</string> <string name="phone_hint" msgid="4872890986869209950">"Zum Öffnen des Telefons vom Symbol wegwischen"</string> @@ -548,6 +549,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Der Bildschirm wird so lange angezeigt, bis du die Fixierung aufhebst. Berühre und halte dazu \"Startbildschirm\"."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Um die Fixierung für diesen Bildschirm aufzuheben, berühre und halte \"Zurück\" und \"Übersicht\""</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Um die Fixierung für diesen Bildschirm aufzuheben, berühre und halte \"Zurück\" und \"Startbildschirm\""</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Zum Loslösen des Bildschirms nach oben wischen und halten"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Ok"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Nein danke"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Der Bildschirm ist angepinnt"</string> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index 0ceef42a9dc3..dfb5edf97d67 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Λιγότερο επείγουσες ειδοποιήσεις παρακάτω"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Πατήστε ξανά για να ανοίξετε"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Σύρετε προς τα επάνω για άνοιγμα"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Σύρετε προς τα πάνω για να δοκιμάσετε ξανά"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Αυτή η συσκευή είναι διαχειριζόμενη από τον οργανισμό σας"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Τη συσκευή διαχειρίζεται ο οργανισμός <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Σύρετε προς τα έξω για τηλέφωνο"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Με αυτόν τον τρόπο, παραμένει σε προβολή μέχρι να το ξεκαρφιτσώσετε. Αγγίξτε παρατεταμένα το στοιχείο \"Αρχική οθόνη\" για ξεκαρφίτσωμα."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Για να ξεκαρφιτσώσετε αυτήν την οθόνη, αγγίξτε παρατεταμένα τα κουμπιά \"Πίσω\" και \"Επισκόπηση\""</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Για να ξεκαρφιτσώσετε αυτήν την οθόνη, αγγίξτε παρατεταμένα τα κουμπιά \"Πίσω\" και \"Αρχική οθόνη\""</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Για να ξεκαρφιτσώσετε αυτήν την οθόνη, σύρετε προς τα πάνω και κρατήστε παρατεταμένα"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Το κατάλαβα"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Όχι"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Η οθόνη καρφιτσώθηκε"</string> diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index dc661dd14a4e..4fd8ed9c7c09 100644 --- a/packages/SystemUI/res/values-en-rAU/strings.xml +++ b/packages/SystemUI/res/values-en-rAU/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Less urgent notifications below"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Tap again to open"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Swipe up to open"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Swipe up to try again"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"This device is managed by your organisation"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"This device is managed by <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Swipe from icon for phone"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"This keeps it in view until you unpin. Touch & hold Home to unpin."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"To unpin this screen, touch & hold Back and Overview buttons"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"To unpin this screen, touch & hold Back and Home buttons"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"To unpin this screen, swipe up & hold"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Got it"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"No, thanks"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Screen pinned"</string> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index dc661dd14a4e..4fd8ed9c7c09 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Less urgent notifications below"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Tap again to open"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Swipe up to open"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Swipe up to try again"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"This device is managed by your organisation"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"This device is managed by <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Swipe from icon for phone"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"This keeps it in view until you unpin. Touch & hold Home to unpin."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"To unpin this screen, touch & hold Back and Overview buttons"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"To unpin this screen, touch & hold Back and Home buttons"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"To unpin this screen, swipe up & hold"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Got it"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"No, thanks"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Screen pinned"</string> diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index dc661dd14a4e..4fd8ed9c7c09 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Less urgent notifications below"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Tap again to open"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Swipe up to open"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Swipe up to try again"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"This device is managed by your organisation"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"This device is managed by <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Swipe from icon for phone"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"This keeps it in view until you unpin. Touch & hold Home to unpin."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"To unpin this screen, touch & hold Back and Overview buttons"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"To unpin this screen, touch & hold Back and Home buttons"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"To unpin this screen, swipe up & hold"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Got it"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"No, thanks"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Screen pinned"</string> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index d6c8d090b97b..6adf6d5d43b1 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Notificaciones menos urgentes abajo"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Presionar de nuevo para abrir"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Desliza el dedo hacia arriba para abrir"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Desliza el dedo hacia arriba para volver a intentarlo"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Tu organización administra este dispositivo"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> administra este dispositivo"</string> <string name="phone_hint" msgid="4872890986869209950">"Desliza el dedo para desbloquear el teléfono."</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Esta función mantiene la pantalla visible hasta que dejes de fijarla. Para ello, mantén presionado el botón de inicio."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Para dejar de fijar esta pantalla, mantén presionados los botones Atrás y Recientes"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Para dejar de fijar esta pantalla, mantén presionados los botones de inicio y Atrás"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Para no fijar esta pantalla, desliza el dedo hacia arriba y mantén presionado"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Entendido"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"No, gracias"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Pantalla fija"</string> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index bcb25f5e905f..c4f34456003a 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Notificaciones menos urgente abajo"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Toca de nuevo para abrir"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Desliza el dedo hacia arriba para abrir"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Desliza el dedo hacia arriba para volverlo a intentar"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Este dispositivo está administrado por tu organización"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Este dispositivo está administrado por <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Desliza desde el icono para abrir el teléfono"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"La pantalla se mantiene visible hasta que dejas de fijarla. Para ello, mantén pulsado el botón Inicio."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Mantén pulsado el botón Atrás y el de aplicaciones recientes para dejar de fijar esta pantalla"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Mantén pulsado el botón Atrás y el de Inicio para dejar de fijar esta pantalla"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Para dejar de fijar esta pantalla, desliza el dedo hacia arriba y mantenla pulsada"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Entendido"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"No, gracias"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Pantalla fijada"</string> diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml index 729bba4872bb..a8ad1ec6b9ea 100644 --- a/packages/SystemUI/res/values-et/strings.xml +++ b/packages/SystemUI/res/values-et/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Vähem kiireloomulised märguanded on allpool"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Avamiseks puudutage uuesti"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Pühkige avamiseks üles"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Uuesti proovimiseks pühkige üles"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Seda seadet haldab teie organisatsioon"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Seda seadet haldab <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Telefoni kasutamiseks pühkige ikoonilt eemale"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"See hoitakse kuval, kuni selle vabastate. Vabastamiseks puudutage pikalt nuppu Avakuva."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Ekraanikuva vabastamiseks puudutage pikalt nuppe Tagasi ja Ülevaade"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Ekraanikuva vabastamiseks puudutage pikalt nuppe Tagasi ja Avakuva"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Ekraanikuva vabastamiseks pühkige üles ja hoidke sõrme ekraanil"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Selge"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Tänan, ei"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Ekraanikuva on kinnitatud"</string> diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml index 7b2d7936d5ef..799d773fe82b 100644 --- a/packages/SystemUI/res/values-eu/strings.xml +++ b/packages/SystemUI/res/values-eu/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Horren premiazkoak ez diren jakinarazpenak daude behean"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Irekitzeko, ukitu berriro"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Pasatu hatza gora irekitzeko"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Berriro saiatzeko, pasatu hatza gora"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Zure erakundeak kudeatzen du gailua"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> erakundeak kudeatzen du gailu hau"</string> <string name="phone_hint" msgid="4872890986869209950">"Pasatu hatza ikonotik, telefonoa irekitzeko"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Horrela, ikusgai egongo da aingura kendu arte. Aingura kentzeko, eduki sakatuta Hasiera botoia."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Pantailari aingura kentzeko, eduki sakatuta Atzera eta Ikuspegi orokorra botoiak"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Pantailari aingura kentzeko, eduki sakatuta Atzera eta Hasiera botoiak"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Pantailari aingura kentzeko, pasatu hatza gora eta eduki sakatuta"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Ados"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Ez, eskerrik asko"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Ainguratu da pantaila"</string> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index ae76409bbf77..eeb30a05de4d 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"اعلانهای کمتر فوری در زیر"</string> <string name="notification_tap_again" msgid="7590196980943943842">"دوباره ضربه بزنید تا باز شود"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"برای باز کردن، انگشتتان را تند به بالا بکشید"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"برای امتحان مجدد، انگشتتان را تند به بالا بکشید"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"سازمان شما این دستگاه را مدیریت میکند"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"این دستگاه توسط <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> مدیریت میشود"</string> <string name="phone_hint" msgid="4872890986869209950">"انگشتتان را از نماد تلفن تند بکشید"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"تا برداشتن پین، در نما نگهداشته میشود. برای برداشتن پین، «صفحه اصلی» را لمس کنید و نگهدارید."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"برای برداشتن پین این صفحه، دکمههای «برگشت» و «نمای کلی» را لمس کنید و نگهدارید"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"برای برداشتن پین این صفحه، دکمههای «برگشت» و «صفحه اصلی» را لمس کنید و نگهدارید"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"برای برداشتن پین این صفحهنمایش، صفحه را تند بالا بکشید و نگهدارید"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"متوجه شدم"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"نه متشکرم"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"صفحه پین شد"</string> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index 2a4f70eef78a..7be438a40e3b 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Vähemmän kiireelliset ilmoitukset ovat alla"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Avaa napauttamalla uudelleen"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Avaa pyyhkäisemällä ylös"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Yritä uudelleen pyyhkäisemällä ylös"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Organisaatiosi hallinnoi laitetta"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Tätä laitetta hallinnoi <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>."</string> <string name="phone_hint" msgid="4872890986869209950">"Avaa puhelu pyyhkäisemällä."</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Pysyy näkyvissä, kunnes irrotat sen. Irrota painamalla pitkään Aloitusnäyttö."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Irrota näyttö koskettamalla pitkään Takaisin- ja Viimeisimmät-painikkeita"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Irrota näyttö koskettamalla pitkään Takaisin- ja Aloitusnäyttö-painikkeita"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Irrota näyttö pyyhkäisemällä ylös ja painamalla pitkään"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Selvä"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Ei kiitos"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Näyttö kiinnitetty"</string> diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index 3ded0a5c0a48..e8e4232063e3 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Notifications moins urgentes affichées ci-dessous"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Touchez à nouveau pour ouvrir"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Balayez l\'écran vers le haut pour ouvrir"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Balayez l\'écran vers le haut pour réessayer"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Cet appareil est géré par votre organisation"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Cet appareil est géré par <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Balayez à partir de l\'icône pour accéder au téléphone"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Cet écran est épinglé jusqu\'à ce que vous annuliez l\'opération. Pour annuler l\'épinglage, maintenez le doigt sur la touche Accueil."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Pour annuler l\'épinglage de cet écran, maintenez le doigt sur les touches Retour et Aperçu."</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Pour annuler l\'épinglage de cet écran, maintenez le doigt sur les touches Retour et Accueil."</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Pour annuler l\'épinglage de cet écran, balayez-le vers le haut et gardez le doigt dessus"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"OK"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Non, merci"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Écran épinglé"</string> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index 75a76ae66093..3bc937807277 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Notifications moins urgentes ci-dessous"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Appuyer à nouveau pour ouvrir"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Balayer vers le haut pour ouvrir"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Balayez l\'écran vers le haut pour réessayer"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Cet appareil est géré par votre entreprise"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Cet appareil est géré par <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Balayer pour téléphoner"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Cet écran est épinglé jusqu\'à l\'annulation de l\'opération. Pour annuler l\'épinglage, appuyez de manière prolongée sur le bouton \"Accueil\"."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Pour annuler l\'épinglage de l\'écran, appuyez de manière prolongée sur les boutons \"Retour\" et \"Aperçu\""</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Pour annuler l\'épinglage de l\'écran, appuyez de manière prolongée sur les boutons \"Retour\" et \"Accueil\""</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Pour retirer cet écran, balayez vers le haut et continuez d\'appuyer"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"OK"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Non, merci"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Écran épinglé"</string> diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml index 3268ed06ff56..5480eab8cf65 100644 --- a/packages/SystemUI/res/values-gl/strings.xml +++ b/packages/SystemUI/res/values-gl/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Notificacións menos urxentes abaixo"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Toca de novo para abrir"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Pasa o dedo cara arriba para abrir"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Pasa o dedo cara arriba para tentalo de novo"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Este dispositivo está xestionado pola túa organización"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Este dispositivo está xestionado por <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Pasa o dedo desde a icona para acceder ao teléfono"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"A pantalla manterase visible ata que deixes de fixala. Para facelo, mantén premido Inicio."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Para deixar de fixar a pantalla, mantén premidos os botóns Volver e Visión xeral"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Para deixar de fixar a pantalla, mantén premidos os botóns Atrás e Inicio"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Para soltar esta pantalla, pasa o dedo cara arriba e mantena premida"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"De acordo"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Non, grazas"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Fixouse a pantalla"</string> @@ -597,7 +599,7 @@ <string name="status_bar_work" msgid="6022553324802866373">"Perfil de traballo"</string> <string name="status_bar_airplane" msgid="7057575501472249002">"Modo avión"</string> <string name="add_tile" msgid="2995389510240786221">"Engade un atallo"</string> - <string name="broadcast_tile" msgid="3894036511763289383">"Atallo de emisión"</string> + <string name="broadcast_tile" msgid="3894036511763289383">"Atallo de difusión"</string> <string name="zen_alarm_warning_indef" msgid="3482966345578319605">"Non escoitarás a alarma seguinte <xliff:g id="WHEN">%1$s</xliff:g> a menos que desactives esta opción antes desa hora"</string> <string name="zen_alarm_warning" msgid="444533119582244293">"Non escoitarás a alarma seguinte <xliff:g id="WHEN">%1$s</xliff:g>"</string> <string name="alarm_template" msgid="3980063409350522735">"ás <xliff:g id="WHEN">%1$s</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml index 3dd5004eae4c..1a15cf705d91 100644 --- a/packages/SystemUI/res/values-gu/strings.xml +++ b/packages/SystemUI/res/values-gu/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"નીચે ઓછી તાકીદની સૂચનાઓ"</string> <string name="notification_tap_again" msgid="7590196980943943842">"ખોલવા માટે ફરીથી ટૅપ કરો"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"ખોલવા માટે ઉપરની તરફ સ્વાઇપ કરો"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"ફરી પ્રયાસ કરવા માટે ઉપરની તરફ સ્વાઇપ કરો"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"આ ઉપકરણ તમારી સંસ્થા દ્વારા સંચાલિત છે"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"આ ઉપકરણ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> દ્વારા સંચાલિત થાય છે"</string> <string name="phone_hint" msgid="4872890986869209950">"ફોન માટે આયકનમાંથી સ્વાઇપ કરો"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"તમે જ્યાં સુધી અનપિન કરશો નહીં ત્યાં સુધી આ તેને દૃશ્યક્ષમ રાખે છે. અનપિન કરવા માટે હોમને સ્પર્શ કરી રાખો."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"આ સ્ક્રીનને અનપિન કરવા માટે, પાછળ અને ઝલક બટનને સ્પર્શ કરી રાખો"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"આ સ્ક્રીનને અનપિન કરવા માટે, પાછળ અને હોમ બટનને સ્પર્શ કરી રાખો"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"આ સ્ક્રીનને અનપિન કરવા માટે, ઉપર સ્વાઇપ કરીને બટન દબાવી રાખો"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"સમજાઈ ગયું"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"ના, આભાર"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"સ્ક્રીન પિન કરી"</string> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index 3fa2a48188c9..3c18b0de807b 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"कम अत्यावश्यक सूचनाएं नीचे दी गई हैं"</string> <string name="notification_tap_again" msgid="7590196980943943842">"खोलने के लिए फिर से टैप करें"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"खोलने के लिए ऊपर स्वाइप करें"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"फिर से कोशिश करने के लिए स्वाइप करें"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"इस डिवाइस का प्रबंधन आपका संगठन करता है"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"इस डिवाइस के प्रबंधक <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> हैं"</string> <string name="phone_hint" msgid="4872890986869209950">"फ़ोन के लिए आइकॉन से स्वाइप करें"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"इससे वह तब तक दिखाई देती है जब तक आप उसे अनपिन नहीं कर देते. अनपिन करने के लिए, होम बटन को दबाकर रखें."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"इस स्क्रीन को अनपिन करने के लिए, खास जानकारी और वापस जाएं वाले बटन को दबाकर रखें"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"इस स्क्रीन को अनपिन करने के लिए, होम और वापस जाएं वाले बटन को दबाकर रखें"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"इस स्क्रीन को अनपिन करने के लिए, ऊपर की ओर स्वाइप करें और बटन को दबाकर रखें"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"ठीक है"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"नहीं, रहने दें"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"स्क्रीन पिन की गई"</string> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index 2954de21b334..052a0d2b07c5 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -403,6 +403,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Manje hitne obavijesti pri dnu"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Dodirnite opet za otvaranje"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Prijeđite prstom prema gore da biste otvorili"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Prijeđite prstom prema gore za ponovni pokušaj"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Ovim uređajem upravlja vaša organizacija"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Ovim uređajem upravlja <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Prijeđite prstom od ikone za telefon"</string> @@ -547,6 +548,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Zaslon će tako ostati u prvom planu dok ga ne otkvačite. Dodirnite gumb Početna i zadržite pritisak da biste ga otkvačili."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Da biste otkvačili ovaj zaslon, dodirnite gumbe Natrag i Pregled i zadržite pritisak"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Da biste otkvačili ovaj zaslon, dodirnite gumbe Natrag i Početna i zadržite pritisak"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Da biste otkvačili ovaj zaslon, prijeđite prstom i zadržite pritisak"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Shvaćam"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Ne, hvala"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Zaslon je pričvršćen"</string> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index e7e039e930cb..3e3696b45ad9 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"A kevésbé sürgős értesítések lentebb vannak"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Koppintson ismét a megnyitáshoz"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Csúsztasson felfelé a megnyitáshoz"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Az újrapróbálkozáshoz csúsztassa felfelé az ujját"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Az eszközt az Ön szervezete kezeli"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Az eszközt a(z) <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> felügyeli."</string> <string name="phone_hint" msgid="4872890986869209950">"A telefonhoz csúsztasson az ikonról"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Megjelenítve tartja addig, amíg Ön fel nem oldja a rögzítést. A feloldáshoz tartsa lenyomva a Kezdőképernyő elemet."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"A képernyő rögzítésének feloldásához tartsa lenyomva a Vissza és az Áttekintés gombot"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"A képernyő rögzítésének feloldásához tartsa lenyomva a Vissza és a Kezdőképernyő gombot"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"A képernyő rögzítésének feloldásához csúsztassa felfelé ujját, majd tartsa lenyomva"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Értem"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Nem, köszönöm"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Képernyő rögzítve"</string> @@ -645,7 +647,7 @@ <string name="inline_minimize_button" msgid="966233327974702195">"Kis méret"</string> <string name="inline_silent_button_silent" msgid="5315879183296940969">"Néma"</string> <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"Néma megjelenítés"</string> - <string name="inline_silent_button_alert" msgid="6008435419895088034">"Értesítések"</string> + <string name="inline_silent_button_alert" msgid="6008435419895088034">"Figyelemfelkeltő"</string> <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"Értesítések folytatása"</string> <string name="inline_turn_off_notifications" msgid="8635596135532202355">"Az értesítések kikapcsolása"</string> <string name="inline_keep_showing_app" msgid="1723113469580031041">"Továbbra is megjelenjenek az alkalmazás értesítései?"</string> diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml index 3156a6f6fda2..4d19cec90b46 100644 --- a/packages/SystemUI/res/values-hy/strings.xml +++ b/packages/SystemUI/res/values-hy/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Պակաս հրատապ ծանուցումները ստորև"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Կրկին հպեք՝ բացելու համար"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Բացելու համար սահեցրեք վերև"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Սահեցրեք վերև՝ նորից փորձելու համար"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Այս սարքը կառավարում է ձեր կազմակերպությունը"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Այս սարքը կառավարվում է <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>-ի կողմից"</string> <string name="phone_hint" msgid="4872890986869209950">"Սահահարվածեք հեռախոսի պատկերակից"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Էկրանը կցուցադրվի այնքան ժամանակ, մինչև որ չապամրացնեք այն: Ապամրացնելու համար հպեք և պահեք գլխավոր էկրանի կոճակը:"</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Էկրանն ապամրացնելու համար հպեք և պահեք Հետ և Համատեսք կոճակները"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Էկրանն ապամրացնելու համար հպեք և պահեք Հետ և գլխավոր էկրանի կոճակները"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Էկրանն ապամրացնելու համար մատը սահեցրեք վերև և պահեք"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Եղավ"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Ոչ"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Էկրանն ամրացված է"</string> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index 19b2b99344a6..b18beedefcba 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Notifikasi kurang darurat di bawah"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Ketuk lagi untuk membuka"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Geser ke atas untuk membuka"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Geser ke atas untuk mencoba lagi"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Perangkat ini dikelola oleh organisasi"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Perangkat ini dikelola oleh <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Geser dari ikon untuk telepon"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Ini akan terus ditampilkan sampai Anda melepas pin. Sentuh lama tombol Beranda untuk melepas pin."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Untuk melepas pin layar ini, sentuh lama tombol Kembali dan Ringkasan"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Untuk melepas pin layar ini, sentuh lama tombol Kembali dan Beranda"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Untuk melepas pin layar ini, geser ke atas & tahan"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Mengerti"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Lain kali"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Layar dipasangi pin"</string> diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml index 0076add53045..129319da76d3 100644 --- a/packages/SystemUI/res/values-is/strings.xml +++ b/packages/SystemUI/res/values-is/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Minna áríðandi tilkynningar fyrir neðan"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Ýttu aftur til að opna"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Strjúktu upp til að opna"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Strjúktu upp til að reyna aftur"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Þessu tæki er stýrt af fyrirtækinu þínu"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Þessu tæki er stýrt af <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Strjúktu frá tákninu fyrir síma"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Þetta heldur þessu opnu þangað til það er losað. Haltu heimahnappinum inni til að losa."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Til að losa þessa skjámynd skaltu halda inni bakkhnappinum og yfirlitshnappinum"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Til að losa þessa skjámynd skaltu halda inni bakkhnappinum og heimahnappinum"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Til að losa þennan skjá skaltu strjúka upp og halda"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Ég skil"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Nei, takk"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Skjámynd fest"</string> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index 78d3d8a0aaa6..a9427e52d6ee 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Notifiche meno urgenti in basso"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Tocca ancora per aprire"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Scorri verso l\'alto per aprire"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Scorri verso l\'alto per riprovare"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Questo dispositivo è gestito dalla tua organizzazione"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Questo dispositivo è gestito da <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Scorri per accedere al telefono"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"La schermata rimane visibile finché non viene disattivato il blocco su schermo. Per disattivarlo, tocca e tieni premuto Home."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Per disattivare il blocco su schermo, tocca e tieni premuti i pulsanti Indietro e Panoramica"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Per disattivare il blocco su schermo, tocca e tieni premuti i pulsanti Indietro e Home"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Per sbloccare questa schermata, scorri verso l\'alto e tieni premuto"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"OK"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"No, grazie"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Blocco su schermo attivato"</string> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index 3a1525ccc981..52d4a13420c9 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -405,6 +405,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"התראות בדחיפות נמוכה יותר בהמשך"</string> <string name="notification_tap_again" msgid="7590196980943943842">"הקש שוב כדי לפתוח"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"צריך להחליק כדי לפתוח"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"יש להחליק למעלה כדי לנסות שוב"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"מכשיר זה מנוהל על ידי הארגון שלך"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"המכשיר הזה מנוהל על ידי <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"החלק מהסמל כדי להפעיל את הטלפון"</string> @@ -550,6 +551,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"נשאר בתצוגה עד לביטול ההצמדה. יש ללחוץ לחיצה ארוכה על הלחצן \'דף הבית\' כדי לבטל את ההצמדה."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"כדי לבטל את ההצמדה של מסך זה, יש ללחוץ לחיצה ארוכה על הלחצנים \'הקודם\' ו\'סקירה\'"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"כדי לבטל את ההצמדה של מסך זה, יש ללחוץ לחיצה ארוכה על הלחצנים \'הקודם\' ו\'דף הבית\'"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"לביטול ההצמדה של המסך הזה יש להחליק מעלה ולהחזיק"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"הבנתי"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"לא, תודה"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"המסך מוצמד"</string> diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index 51e19a2955b2..05f254f0f80f 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"緊急度の低い通知を下に表示"</string> <string name="notification_tap_again" msgid="7590196980943943842">"開くにはもう一度タップしてください"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"開くには上にスワイプします"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"上にスワイプしてもう一度お試しください"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"このデバイスは組織によって管理されています"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"このデバイスは <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> が管理しています"</string> <string name="phone_hint" msgid="4872890986869209950">"右にスワイプして通話"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"固定を解除するまで画面が常に表示されるようになります。[ホーム] を押し続けると固定が解除されます。"</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"この画面の固定を解除するには [戻る] ボタンと [最近] ボタンを押し続けます"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"この画面の固定を解除するには [戻る] ボタンと [ホーム] ボタンを押し続けます"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"この画面の固定を解除するには、上にスワイプして長押しします"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"はい"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"いいえ"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"画面を固定しました"</string> diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml index 058f23351bd8..6a7460dd9f16 100644 --- a/packages/SystemUI/res/values-ka/strings.xml +++ b/packages/SystemUI/res/values-ka/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"ქვემოთ მითითებულია ნაკლებად სასწრაფო შეტყობინებები"</string> <string name="notification_tap_again" msgid="7590196980943943842">"შეეხეთ ისევ გასახსნელად"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"გასახსნელად გადაფურცლეთ ზემოთ"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"ხელახლა საცდელად გადაფურცლეთ ზემოთ"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"ამ მოწყობილობას მართავს თქვენი ორგანიზაცია"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"ამ მოწყობილობას მართავს <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"ტელეფონისთვის გადაფურცლეთ ხატულადან"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"ამით ის დარჩება ხედში ჩამაგრების მოხსნამდე. ჩამაგრების მოსახსნელად, ხანგრძლივად შეეხეთ „მთავარ გვერდს“."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"ამ ეკრანის ჩამაგრების მოსახსნელად, ხანგრძლივად შეეხეთ ღილაკებს „უკან“ და „მიმოხილვა“"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"ამ ეკრანის ჩამაგრების მოსახსნელად, ხანგრძლივად შეეხეთ ღილაკებს „უკან“ და „მთავარი გვერდი“"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"ამ ეკრანის ჩამაგრების მოსახსნელად გადაფურცლეთ ზემოთ და არ აუშვათ"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"გასაგებია"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"არა, გმადლობთ"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"ეკრანი ჩამაგრებულია"</string> diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml index 1b201ddf37dc..6e0fca774809 100644 --- a/packages/SystemUI/res/values-kk/strings.xml +++ b/packages/SystemUI/res/values-kk/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Шұғылдығы азырақ хабарландырулар төменде"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Ашу үшін қайта түртіңіз"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Ашу үшін жоғары қарай сырғытыңыз."</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Әрекетті қайталау үшін жоғары сырғытыңыз."</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Бұл құрылғыны ұйым басқарады"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Бұл құрылғыны <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> басқарады"</string> <string name="phone_hint" msgid="4872890986869209950">"Телефонды ашу үшін белгішеден әрі қарай сырғытыңыз"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Экран босатылғанға дейін көрсетіліп тұрады. Оны босату үшін \"Негізгі бет\" түймесін түртіп, ұстап тұрыңыз."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Бұл экранды босату үшін \"Артқа\" және \"Шолу\" түймелерін түртіп, ұстап тұрыңыз"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Бұл экранды босату үшін \"Артқа\" және \"Негізгі бет\" түймелерін түртіп, ұстап тұрыңыз"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Бұл экранды босату үшін жоғары сырғытып, ұстап тұрыңыз."</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Түсінікті"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Жоқ, рақмет"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Экран бекітілді"</string> diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml index a9ff164e5cd3..16272fc77b2d 100644 --- a/packages/SystemUI/res/values-km/strings.xml +++ b/packages/SystemUI/res/values-km/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"ការជូនដំណឹងមិនសូវបន្ទាន់ខាងក្រោម"</string> <string name="notification_tap_again" msgid="7590196980943943842">"ប៉ះម្ដងទៀត ដើម្បីបើក"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"អូសឡើងលើដើម្បីបើក"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"អូសឡើងលើ ដើម្បីព្យាយាមម្ដងទៀត"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"ឧបករណ៍នេះស្ថិតក្រោមការគ្រប់គ្រងរបស់ស្ថាប័នអ្នក"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"ឧបករណ៍នេះស្ថិតក្រោមការគ្រប់គ្រងរបស់ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"អូសចេញពីរូបតំណាងដើម្បីប្រើទូរស័ព្ទ"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"វានឹងនៅតែបង្ហាញ រហូតទាល់តែអ្នកដកការដៅ។ សូមចុចប៊ូតុងទំព័រដើមឱ្យជាប់ ដើម្បីដកការដៅ។"</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"ដើម្បីដកការដៅអេក្រង់នេះ សូមចុចប៊ូតុងថយក្រោយ និងប៊ូតុងទិដ្ឋភាពរួមឱ្យជាប់"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"ដើម្បីដកការដៅអេក្រង់នេះ សូមចុចប៊ូតុងថយក្រោយ និងប៊ូតុងទំព័រដើមឱ្យជាប់"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"អូសឡើងលើឱ្យជាប់ ដើម្បីដកការដៅអេក្រង់នេះ"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"យល់ហើយ"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"ទេ អរគុណ"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"បានដៅអេក្រង់"</string> diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml index e3f387992976..79c4f2da77d3 100644 --- a/packages/SystemUI/res/values-kn/strings.xml +++ b/packages/SystemUI/res/values-kn/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"ಕೆಳಗೆ ಕಡಿಮೆ ಅವಸರದ ಅಧಿಸೂಚನೆಗಳು"</string> <string name="notification_tap_again" msgid="7590196980943943842">"ತೆರೆಯಲು ಮತ್ತೆ ಟ್ಯಾಪ್ ಮಾಡಿ"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"ತೆರೆಯಲು ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಲು ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"ಈ ಸಾಧನವನ್ನು ನಿಮ್ಮ ಸಂಸ್ಥೆ ನಿರ್ವಹಿಸುತ್ತಿದೆ"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"ಈ ಸಾಧನವನ್ನು <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ರಿಂದ ನಿರ್ವಹಿಸಲಾಗಿದೆ"</string> <string name="phone_hint" msgid="4872890986869209950">"ಫೋನ್ಗಾಗಿ ಐಕಾನ್ನಿಂದ ಸ್ವೈಪ್ ಮಾಡಿ"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"ನೀವು ಅನ್ಪಿನ್ ಮಾಡುವವರೆಗೆ ಅದನ್ನು ವೀಕ್ಷಣೆಯಲ್ಲಿಡುತ್ತದೆ. ಅನ್ಪಿನ್ ಮಾಡಲು ಮುಖಪುಟವನ್ನು ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಒತ್ತಿಹಿಡಿಯಿರಿ."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"ಈ ಪರದೆಯನ್ನು ಅನ್ಪಿನ್ ಮಾಡಲು, ಹಿಂದಕ್ಕೆ ಮತ್ತು ಸಮಗ್ರ ನೋಟ ಬಟನ್ಗಳನ್ನು ಸ್ಪರ್ಶಿಸಿ ಒತ್ತಿಹಿಡಿಯಿರಿ"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"ಈ ಪರದೆಯನ್ನು ಅನ್ಪಿನ್ ಮಾಡಲು, ಹಿಂದಕ್ಕೆ ಮತ್ತು ಮುಖಪುಟ ಬಟನ್ಗಳನ್ನು ಸ್ಪರ್ಶಿಸಿ ಒತ್ತಿಹಿಡಿಯಿರಿ"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"ಈ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಅನ್ಪಿನ್ ಮಾಡಲು, ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ & ಒತ್ತಿ ಹಿಡಿದುಕೊಳ್ಳಿ"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"ತಿಳಿಯಿತು"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"ಧನ್ಯವಾದಗಳು"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"ಪರದೆಯನ್ನು ಪಿನ್ ಮಾಡಲಾಗಿದೆ"</string> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index 75af4f142ae9..b0a1671e4aa8 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"아래에 덜 급한 알림 표시"</string> <string name="notification_tap_again" msgid="7590196980943943842">"다시 탭하여 열기"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"위로 스와이프하여 열기"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"위로 스와이프하여 다시 시도해 주세요."</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"조직에서 관리하는 기기입니다."</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>에서 관리하는 기기입니다."</string> <string name="phone_hint" msgid="4872890986869209950">"전화 기능을 사용하려면 아이콘에서 스와이프하세요."</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"고정 해제할 때까지 계속 표시됩니다. 고정 해제하려면 홈을 길게 터치하세요."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"이 화면을 고정 해제하려면 뒤로 및 최근 사용 버튼을 길게 터치하세요."</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"이 화면을 고정 해제하려면 뒤로 및 홈 버튼을 길게 터치하세요."</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"이 화면을 고정 해제하려면 위로 스와이프하고 유지하세요."</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"확인"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"거부"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"화면 고정됨"</string> diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml index b094746730bf..dd985c6a40c5 100644 --- a/packages/SystemUI/res/values-ky/strings.xml +++ b/packages/SystemUI/res/values-ky/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Анчейин шашылыш эмес эскертмелер төмөндө"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Ачуу үчүн кайра таптап коюңуз"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Ачуу үчүн өйдө сүрүңүз"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Кайра аракет кылуу үчүн экранды өйдө сүрүңүз"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Бул түзмөк уюмуңуз тарабынан башкарылат"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Бул түзмөк <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> тарабынан башкарылат"</string> <string name="phone_hint" msgid="4872890986869209950">"Сүрөтчөнү серпип телефонго өтүңүз"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Ал бошотулмайынча көрүнө берет. Бошотуу үчүн, \"Башкы бет\" баскычын басып, кармап туруңуз."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Бул экранды бошотуу үчүн \"Артка\" жана \"Сереп салуу\" баскычтарын басып, кармап туруңуз"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Бул экранды бошотуу үчүн \"Артка\" жана \"Башкы бет\" баскычтарын басып, кармап туруңуз"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Бул экранды бошотуу үчүн аны өйдө сүрүп, кармап туруңуз"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Түшүндүм"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Жок, рахмат"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Экран кадалды"</string> diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml index 7bf95b19b748..d99db74c1fc4 100644 --- a/packages/SystemUI/res/values-lo/strings.xml +++ b/packages/SystemUI/res/values-lo/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"ການແຈ້ງເຕືອນທີ່ສຳຄັນໜ້ອຍກວ່າຢູ່ດ້ານລຸ່ມ"</string> <string name="notification_tap_again" msgid="7590196980943943842">"ແຕະອີກຄັ້ງເພື່ອເປີດ"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"ປັດຂຶ້ນເພື່ອເປີດ"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"ປັດຂຶ້ນເພື່ອລອງໃໝ່"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"ອຸປະກອນນີ້ແມ່ນຈັດການໂດຍອົງກອນຂອງທ່ານ"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"ອຸປະກອນນີ້ຖືກຈັດການໂດຍ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"ປັດຈາກໄອຄອນສຳລັບໂທລະສັບ"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"ນີ້ຈະສະແດງມັນໃນໜ້າຈໍຈົນກວ່າທ່ານຈະເຊົາປັກໝຸດ. ໃຫ້ແຕະປຸ່ມພາບຮວມຄ້າງໄວ້ເພື່ອຍົກເລີກການປັກໝຸດ."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"ເພື່ອຍົກເລີກການປັກໝຸດໜ້າຈໍນີ້, ໃຫ້ແຕະປຸ່ມກັບຄືນ ແລະ ປຸ່ມພາບຮວມຄ້າງໄວ້"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"ເພື່ອຍົກເລີກການປັກໝຸດໜ້າຈໍນີ້, ໃຫ້ແຕະປຸ່ມກັບຄືນ ແລະ ປຸ່ມພາບຮວມຄ້າງໄວ້"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"ເພື່ອເຊົາປັກໝຸດໜ້າຈໍນີ້, ໃຫ້ປັດຂຶ້ນຄ້າງໄວ້"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"ເຂົ້າໃຈແລ້ວ"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"ບໍ່, ຂອບໃຈ"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"ປັກໝຸດໜ້າຈໍແລ້ວ"</string> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index fb5ec206ca7d..0355fc0e0e0c 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -405,6 +405,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Mažiau skubūs pranešimai toliau"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Palieskite dar kartą, kad atidarytumėte"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Perbraukite aukštyn, kad atidarytumėte"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Jei norite bandyti dar kartą, perbraukite aukštyn"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Šį įrenginį tvarko jūsų organizacija"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Šį įrenginį tvarko <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Perbraukite iš telefono piktogramos"</string> @@ -550,6 +551,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Tai bus rodoma, kol atsegsite. Palieskite ir palaikykite „Pagrindinis ekranas“, kad atsegtumėte."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Kad atsegtumėte šį ekraną, palieskite ir palaikykite mygtukus „Atgal“ ir „Apžvalga“"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Kad atsegtumėte šį ekraną, palieskite ir palaikykite mygtukus „Atgal“ ir „Pagrindinis ekranas“"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Kad atsegtumėte šį ekraną, perbraukite aukštyn ir palaikykite"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Supratau"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Ne, ačiū"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Ekranas prisegtas"</string> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index 581b68a02c64..e6ac23579597 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -403,6 +403,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Mazāk steidzami paziņojumi tiek rādīti tālāk"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Pieskarieties vēlreiz, lai atvērtu"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Velciet augšup, lai atvērtu"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Velciet augšup, lai mēģinātu vēlreiz"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Šo ierīci pārvalda jūsu organizācija"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Šo ierīci pārvalda <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Lai lietotu tālruni, velciet no ikonas"</string> @@ -547,6 +548,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Šādi tas būs redzams līdz brīdim, kad to atspraudīsiet. Lai atspraustu, pieskarieties pogai “Sākums” un turiet to."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Lai atspraustu šo ekrānu, pieskarieties pogām “Atpakaļ” un “Pārskats” un turiet tās."</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Lai atspraustu šo ekrānu, pieskarieties pogām “Atpakaļ” un “Sākums” un turiet tās."</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Lai atspraustu šo ekrānu, velciet augšup un turiet."</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Sapratu!"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Nē, paldies"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Ekrāns ir piesprausts"</string> diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml index d745f8a021e8..a529dfe6a098 100644 --- a/packages/SystemUI/res/values-mk/strings.xml +++ b/packages/SystemUI/res/values-mk/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Долу се помалку итни известувања"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Допрете повторно за да се отвори"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Повлечете за да отворите"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Повлечете нагоре за да се обидете повторно"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Вашата организација управува со уредов"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Уредов го управува <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Повлечете од иконата за телефонот"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Ќе се гледа сѐ додека не го откачите. Допрете и задржете „Почетен екран“ за откачување."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"За откачување на екранов, допрете и задржете ги копчињата „Назад“ и „Краток преглед“"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"За откачување на екранов, допрете и задржете ги копчињата „Назад“ и „Почетен екран“"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"За да го откачите екранов, повлечете нагоре и задржете"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Сфатив"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Не, фала"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Екранот е прикачен"</string> diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml index eeaf0f9d3367..181eb4a16942 100644 --- a/packages/SystemUI/res/values-ml/strings.xml +++ b/packages/SystemUI/res/values-ml/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"ആവശ്യം കുറഞ്ഞ അറിയിപ്പുകൾ ചുവടെ നൽകിയിരിക്കുന്നു"</string> <string name="notification_tap_again" msgid="7590196980943943842">"തുറക്കുന്നതിന് വീണ്ടും ടാപ്പുചെയ്യുക"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"തുറക്കാൻ മുകളിലോട്ട് സ്വൈപ്പ് ചെയ്യുക"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"വീണ്ടും ശ്രമിക്കാൻ മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്യുക"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"ഈ ഉപകരണം മാനേജുചെയ്യുന്നത് നിങ്ങളുടെ സ്ഥാപനമാണ്"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> മാനേജുചെയ്യുന്ന ഉപകരണമാണിത്"</string> <string name="phone_hint" msgid="4872890986869209950">"ഫോൺ ഐക്കണിൽ നിന്ന് സ്വൈപ്പുചെയ്യുക"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"നിങ്ങൾ അൺപിൻ ചെയ്യുന്നതുവരെ ഇത് കാണുന്ന വിധത്തിൽ നിലനിർത്തും. അൺപിൻ ചെയ്യാൻ \'ഹോം\' ബട്ടൺ സ്പർശിച്ച് പിടിക്കുക."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"ഈ സ്ക്രീൻ അൺപിൻ ചെയ്യാൻ, \'തിരികെ പോവുക\', \'അവലോകനം\' ബട്ടണുകൾ സ്പർശിച്ച് പിടിക്കുക"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"ഈ സ്ക്രീൻ അൺപിൻ ചെയ്യാൻ, \'തിരികെ പോവുക\', \'ഹോം\' ബട്ടണുകൾ സ്പർശിച്ച് പിടിക്കുക"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"ഈ സ്ക്രീൻ അൺപിൻ ചെയ്യാൻ മുകളിലേക്ക് സ്വെെപ്പ് ചെയ്ത് പിടിക്കുക"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"മനസ്സിലായി"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"വേണ്ട, നന്ദി"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"സ്ക്രീൻ പിൻ ചെയ്തു"</string> diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml index bd733ff048a0..085a0aeeb80e 100644 --- a/packages/SystemUI/res/values-mn/strings.xml +++ b/packages/SystemUI/res/values-mn/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Яаралтай биш мэдэгдлүүдийг доор"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Нээхийн тулд дахин товшино уу"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Нээхийн тулд дээш шударна уу"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Дахин оролдохын тулд дээш шударна уу"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Энэ төхөөрөмжийг таны байгууллага удирдаж байна"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Энэ төхөөрөмжийг <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> удирддаг"</string> <string name="phone_hint" msgid="4872890986869209950">"Утсыг гаргахын тулд дүрс тэмдгээс шудрах"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Таныг тогтоосныг болиулах хүртэл үүнийг харуулсан хэвээр байна. Тогтоосныг болиулахын тулд Нүүр хуудас товчлуурыг дараад хүлээнэ үү."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Энэ дэлгэцийг тогтоосныг болиулахын тулд Буцах, Тойм товчлуурыг дараад хүлээнэ үү"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Энэ дэлгэцийг тогтоосныг болиулахын тулд Буцах, Нүүр хуудас товчлуурыг дараад хүлээнэ үү"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Энэ дэлгэцийг тогтоосныг болиулахын тулд дээш шудраад хүлээнэ үү"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Ойлголоо"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Үгүй"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Дэлгэцийг тогтоосон"</string> diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml index 676208bb02f7..4722ae9ef037 100644 --- a/packages/SystemUI/res/values-mr/strings.xml +++ b/packages/SystemUI/res/values-mr/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"खाली कमी तातडीच्या सूचना"</string> <string name="notification_tap_again" msgid="7590196980943943842">"उघडण्यासाठी पुन्हा टॅप करा"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"उघडण्यासाठी वर स्वाइप करा"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"पुन्हा प्रयत्न करण्यासाठी वर स्वाइप करा"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"हे डिव्हाइस तुमची संस्था व्यवस्थापित करते"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"हे डिव्हाइस <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ने व्यवस्थापित केले आहे"</string> <string name="phone_hint" msgid="4872890986869209950">"फोनसाठी चिन्हावरून स्वाइप करा"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"तुम्ही अनपिन करेपर्यंत हे त्यास दृश्यामध्ये ठेवते. अनपिन करण्यासाठी होमला स्पर्श करा आणि धरून ठेवा."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"हा स्क्रीन अनपिन करण्यासाठी, मागे आणि अवलोकन बटणांना स्पर्श करून धरून ठेवा"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"हा स्क्रीन अनपिन करण्यासाठी, मागे आणि होम बटणांना स्पर्श करून धरून ठेवा"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"हा स्क्रीन अनपिन करण्यासाठी, वर स्वाइप करा आणि धरून ठेवा"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"समजले"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"नाही, नको"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"स्क्रीन पिन केला"</string> diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml index f58ea18619e1..1bc7ca94792c 100644 --- a/packages/SystemUI/res/values-ms/strings.xml +++ b/packages/SystemUI/res/values-ms/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Pemberitahuan kurang penting di bawah"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Ketik lagi untuk membuka"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Leret ke atas untuk buka"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Leret ke atas untuk mencuba lagi"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Peranti ini diurus oleh organisasi anda"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Peranti ini diurus oleh <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Leret dari ikon untuk telefon"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Tindakan ini memastikan skrin kelihatan sehingga anda menyahsemat. Sentuh & tahan Skrin Utama untuk menyahsemat."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Untuk menyahsemat skrin ini, sentuh & tahan butang Kembali dan Ikhtisar"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Untuk menyahsemat skrin ini, sentuh & tahan butang Kembali dan Skrin Utama"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Untuk menyahsemat skrin ini, leret ke atas & tahan"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Faham"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Tidak"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Skrin disemat"</string> diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml index 19a9d1c96c2b..51aaaa2ae954 100644 --- a/packages/SystemUI/res/values-my/strings.xml +++ b/packages/SystemUI/res/values-my/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"အရေးပါမှု နည်းသည့် အကြောင်းကြားချက်များ အောက်မှာ"</string> <string name="notification_tap_again" msgid="7590196980943943842">"ဖွင့်ရန် ထပ်ပြီး ပုတ်ပါ"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"ဖွင့်ရန် အပေါ်သို့ပွတ်ဆွဲပါ"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"ထပ်စမ်းကြည့်ရန် အပေါ်သို့ပွတ်ဆွဲပါ"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"ဤစက်ပစ္စည်းကို သင်၏အဖွဲ့အစည်းက စီမံခန့်ခွဲထားပါသည်"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"ဤစက်ပစ္စည်းကို <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> က စီမံခန့်ခွဲထားပါသည်"</string> <string name="phone_hint" msgid="4872890986869209950">"ဖုန်းအတွက် သင်္ကေတပုံအား ပွတ်ဆွဲပါ"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"သင်က ပင်မဖြုတ်မချင်း ၎င်းကိုပြသထားပါမည်။ ပင်ဖြုတ်ရန် \'ပင်မ\' ခလုတ်ကို တို့၍ဖိထားပါ။"</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"ဤမျက်နှာပြင်ကို ပင်ဖြုတ်ရန်အတွက် \'နောက်သို့\' နှင့် \'အနှစ်ချုပ်\' ခလုတ်တို့ကို တို့၍ဖိထားပါ"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"ဤမျက်နှာပြင်ကို ပင်ဖြုတ်ရန်အတွက် \'နောက်သို့\' နှင့် \'ပင်မ\' ခလုတ်တို့ကို တို့၍ဖိထားပါ"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"ဤမျက်နှာပြင်ကို ပင်ဖြုတ်ရန် အပေါ်သို့ ပွတ်ဆွဲပြီး ဖိထားပါ"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"ရပါပြီ"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"မလိုတော့ပါ"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"မျက်နှာပြင်ကို ပင်ထိုးထားသည်"</string> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index 4288f3489891..ce611e03ad6a 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Mindre presserende varsler nedenfor"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Trykk på nytt for å åpne"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Sveip opp for å åpne"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Sveip opp for å prøve igjen"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Denne enheten administreres av organisasjonen din"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Denne enheten administreres av <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Sveip ikonet for å åpne telefon"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"På denne måten blir skjermen synlig frem til du løsner den. Trykk og hold inne Startside for å løsne den."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"For å løsne denne skjermen, trykk på og hold inne Tilbake- og Oversikt-knappene"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"For å løsne denne skjermen, trykk på og hold inne Tilbake- og Startside-knappene"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"For å løsne denne skjermen, sveip opp og hold"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Skjønner"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Nei takk"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Skjermen er festet"</string> diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml index 70ebfd8ee60c..6ef85b59ea34 100644 --- a/packages/SystemUI/res/values-ne/strings.xml +++ b/packages/SystemUI/res/values-ne/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"तल कम जरुरी सूचनाहरू"</string> <string name="notification_tap_again" msgid="7590196980943943842">"खोल्न पुनः ट्याप गर्नुहोस्"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"खोल्न माथितिर स्वाइप गर्नुहोस्"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"फेरि प्रयास गर्न माथितिर स्वाइप गर्नुहोस्"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"तपाईंको संगठनले यस यन्त्रलाई व्यवस्थापन गर्दछ"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"यो यन्त्र <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> द्वारा व्यवस्थापन गरिएको छ"</string> <string name="phone_hint" msgid="4872890986869209950">"फोनको लागि आइकनबाट स्वाइप गर्नुहोस्"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"तपाईंले अनपिन नगरेसम्म यसले त्यसलाई दृश्यमा कायम राख्छ। अनपिन गर्न गृह नामक बटनलाई छोइराख्नुहोस्।"</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"यस स्क्रिनलाई अनपनि गर्न पछाडि र परिदृश्य नामक बटनहरूलाई छोइराख्नुहोस्"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"यस स्क्रिनलाई अनपनि गर्न पछाडि र गृह नामक बटनहरूलाई छोइराख्नुहोस्"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"यो स्क्रिन अनपिन गर्न माथितिर स्वाइप गरी थिचिराख्नुहोस्"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"बुझेँ"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"धन्यवाद पर्दैन"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"स्क्रिन पिन गरियो"</string> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index 88f5bd4e87bf..305b46a2feb6 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Minder urgente meldingen onderaan"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Tik nog eens om te openen"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Veeg omhoog om te openen"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Veeg omhoog om het opnieuw te proberen"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Dit apparaat wordt beheerd door je organisatie"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Dit apparaat wordt beheerd door <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Vegen voor telefoon"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Het scherm blijft zichtbaar totdat je het losmaakt. Tik op Home en houd dit vast om het scherm los te maken."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Tik op Terug en Overzicht en houd deze knoppen vast om dit scherm los te maken"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Tik op Terug en Home en houd deze knoppen vast om dit scherm los te maken"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Veeg omhoog en houd vast om dit scherm los te maken"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Ik snap het"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Nee, bedankt"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Scherm vastgezet"</string> diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml index 83221a62fe7d..e9b150c1a66e 100644 --- a/packages/SystemUI/res/values-or/strings.xml +++ b/packages/SystemUI/res/values-or/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"ନିମ୍ନରେ କମ୍ ଜରୁରୀ ବିଜ୍ଞପ୍ତି"</string> <string name="notification_tap_again" msgid="7590196980943943842">"ଖୋଲିବା ପାଇଁ ପୁଣି ଟାପ୍ କରନ୍ତୁ"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"ଖୋଲିବା ପାଇଁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"ପୁଣି ଚେଷ୍ଟା କରିବା ପାଇଁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"ଏହି ଡିଭାଇସ୍ ଆପଣଙ୍କ ସଂସ୍ଥା ଦ୍ୱାରା ପରିଚାଳିତ।"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"ଏହି ଡିଭାଇସ୍ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ଦ୍ୱାରା ପରିଚାଳିତ ହେଉଛି"</string> <string name="phone_hint" msgid="4872890986869209950">"ଫୋନ୍ ପାଇଁ ଆଇକନରୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"ଆପଣ ଅନପିନ୍ ନକରିବା ପର୍ଯ୍ୟନ୍ତ ଏହା ଦେଖାଉଥିବ। ଅନପିନ୍ କରିବା ପର୍ଯ୍ୟନ୍ତ ହୋମ୍କୁ ଦାବିଧରନ୍ତୁ।"</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"ଏହି ସ୍କ୍ରୀନ୍କୁ ଅନପିନ୍ କରିବା ପାଇଁ, ବ୍ୟାକ୍ ଏବଂ ଓଭରଭ୍ୟୁ ବଟନ୍କୁ ଦାବିଧରନ୍ତୁ"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"ଏହି ସ୍କ୍ରୀନ୍କୁ ଅନପିନ୍ କରିବା ପାଇଁ, ବ୍ୟାକ୍ ଏବଂ ହୋମ୍ ବଟନ୍କୁ ଦାବିଧରନ୍ତୁ"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"ଏହି ସ୍କ୍ରୀନ୍କୁ ଅନପିନ୍ କରିବା ପାଇଁ, ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ ଏବଂ ଧରି ରଖନ୍ତୁ"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"ବୁଝିଲି"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"ନାହିଁ, ଥାଉ"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"ସ୍କ୍ରୀନ୍କୁ ପିନ୍ କରାଗଲା"</string> diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml index 64e2d098c598..742080c12338 100644 --- a/packages/SystemUI/res/values-pa/strings.xml +++ b/packages/SystemUI/res/values-pa/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"ਹੇਠਾਂ ਘੱਟ ਲਾਜ਼ਮੀ ਸੂਚਨਾਵਾਂ"</string> <string name="notification_tap_again" msgid="7590196980943943842">"ਖੋਲ੍ਹਣ ਲਈ ਦੁਬਾਰਾ ਟੈਪ ਕਰੋ"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"ਖੋਲ੍ਹਣ ਲਈ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰਨ ਲਈ ਸਵਾਈਪ ਕਰੋ"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"ਇਸ ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ ਤੁਹਾਡੇ ਸੰਗਠਨ ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"ਇਹ ਡੀਵਾਈਸ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ਵੱਲੋਂ ਪ੍ਰਬੰਧਿਤ ਕੀਤਾ ਗਿਆ ਹੈ"</string> <string name="phone_hint" msgid="4872890986869209950">"ਫ਼ੋਨ ਲਈ ਪ੍ਰਤੀਕ ਤੋਂ ਸਵਾਈਪ ਕਰੋ"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਅਨਪਿੰਨ ਨਾ ਕੀਤੇ ਜਾਣ ਤੱਕ ਇਸਨੂੰ ਦਿਖਾਇਆ ਜਾਂਦਾ ਹੈ। ਅਨਪਿੰਨ ਕਰਨ ਲਈ \'ਹੋਮ\' ਨੂੰ ਸਪੱਰਸ਼ ਕਰਕੇ ਦਬਾਈ ਰੱਖੋ।"</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"ਇਸ ਸਕ੍ਰੀਨ ਨੂੰ ਅਨਪਿੰਨ ਕਰਨ ਲਈ, \'ਪਿੱਛੇ\' ਅਤੇ \'ਰੂਪ-ਰੇਖਾ\' ਬਟਨਾਂ ਨੂੰ ਸਪੱਰਸ਼ ਕਰਕੇ ਦਬਾਈ ਰੱਖੋ"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"ਇਸ ਸਕ੍ਰੀਨ ਨੂੰ ਅਨਪਿੰਨ ਕਰਨ ਲਈ, \'ਪਿੱਛੇ\' ਅਤੇ \'ਹੋਮ\' ਬਟਨਾਂ ਨੂੰ ਸਪੱਰਸ਼ ਕਰੋ ਅਤੇ ਦਬਾਈ ਰੱਖੋ"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"ਇਸ ਸਕ੍ਰੀਨ ਨੂੰ ਅਨਪਿੰਨ ਕਰਨ ਲਈ, ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰਕੇ ਰੱਖੋ"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"ਸਮਝ ਲਿਆ"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"ਨਹੀਂ ਧੰਨਵਾਦ"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"ਸਕ੍ਰੀਨ ਪਿੰਨ ਕੀਤੀ ਗਈ"</string> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index 8463773316a1..4be1a0f3aa17 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -407,6 +407,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Poniżej widać mniej pilne powiadomienia"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Kliknij ponownie, by otworzyć"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Przesuń w górę, by otworzyć"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Przesuń w górę, by spróbować ponownie"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Tym urządzeniem zarządza Twoja organizacja"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Tym urządzeniem zarządza <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Aby włączyć telefon, przesuń palcem od ikony"</string> @@ -464,10 +465,10 @@ <string name="media_projection_dialog_service_text" msgid="3075544489835858258">"Podczas nagrywania lub przesyłania usługa udostępniająca tę funkcję może rejestrować wszelkie informacje poufne wyświetlane na ekranie lub odtwarzane na urządzeniu takie jak dźwięki czy podawane hasła, informacje o płatnościach, zdjęcia i wiadomości."</string> <string name="media_projection_dialog_title" msgid="8124184308671641248">"Ujawnianie poufnych informacji podczas przesyłania/nagrywania"</string> <string name="media_projection_remember_text" msgid="3103510882172746752">"Nie pokazuj ponownie"</string> - <string name="clear_all_notifications_text" msgid="814192889771462828">"Ukryj wszystkie"</string> + <string name="clear_all_notifications_text" msgid="814192889771462828">"Usuń wszystkie"</string> <string name="manage_notifications_text" msgid="2386728145475108753">"Zarządzaj"</string> - <string name="notification_section_header_gentle" msgid="4372438504154095677">"Powiadomienia ciche"</string> - <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Wyczyść wszystkie ciche powiadomienia"</string> + <string name="notification_section_header_gentle" msgid="4372438504154095677">"Ciche powiadomienia"</string> + <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Usuń wszystkie ciche powiadomienia"</string> <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Powiadomienia wstrzymane przez tryb Nie przeszkadzać"</string> <string name="media_projection_action_text" msgid="8470872969457985954">"Rozpocznij teraz"</string> <string name="empty_shade_text" msgid="708135716272867002">"Brak powiadomień"</string> @@ -552,6 +553,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Ekran będzie widoczny, dopóki go nie odepniesz. Aby to zrobić, naciśnij i przytrzymaj Ekran główny."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Aby odpiąć ten ekran, naciśnij i przytrzymaj przyciski Wstecz oraz Przegląd"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Aby odpiąć ten ekran, naciśnij i przytrzymaj przyciski Wstecz oraz Ekran główny"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Aby odpiąć ten ekran, przesuń w górę i przytrzymaj"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"OK"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Nie, dziękuję"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Ekran przypięty"</string> diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml index c7e526371573..7a57049009c0 100644 --- a/packages/SystemUI/res/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Notificações menos urgentes abaixo"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Toque novamente para abrir"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Deslize para cima para abrir"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Deslize para cima para tentar novamente"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Este dispositivo é gerenciado pela sua organização"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Este dispositivo é gerenciado por <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Deslize a partir do ícone do telefone"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Ela é mantida à vista até que seja liberada. Toque em Início e mantenha essa opção pressionada para liberar."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Para liberar esta tela, mantenha os botões Voltar e Visão geral pressionados"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Para liberar essa tela, toque nos botões Voltar e Início e mantenha-os pressionados"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Para liberar esta tela, deslize para cima e pressione"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Entendi"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Não, obrigado"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Tela fixada"</string> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index f60dcac34b53..fb45ea77ac78 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Notificações menos urgentes abaixo"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Toque novamente para abrir"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Deslize rapidamente para cima para abrir"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Deslize rapidamente para cima para tentar novamente."</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Este dispositivo é gerido pela sua entidade"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Este dispositivo é gerido por <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Deslize rapid. a partir do ícone para aceder ao telemóvel"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Esta opção mantém o item visível até o soltar. Toque sem soltar em Página inicial para soltar."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Para soltar este ecrã, toque sem soltar nos botões Anterior e Vista geral."</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Para soltar este ecrã, toque sem soltar nos botões Anterior e Página inicial."</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Para soltar este ecrã, deslize rapidamente para cima sem soltar."</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Compreendi"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Não, obrigado"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Ecrã fixo"</string> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index c7e526371573..7a57049009c0 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Notificações menos urgentes abaixo"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Toque novamente para abrir"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Deslize para cima para abrir"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Deslize para cima para tentar novamente"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Este dispositivo é gerenciado pela sua organização"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Este dispositivo é gerenciado por <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Deslize a partir do ícone do telefone"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Ela é mantida à vista até que seja liberada. Toque em Início e mantenha essa opção pressionada para liberar."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Para liberar esta tela, mantenha os botões Voltar e Visão geral pressionados"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Para liberar essa tela, toque nos botões Voltar e Início e mantenha-os pressionados"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Para liberar esta tela, deslize para cima e pressione"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Entendi"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Não, obrigado"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Tela fixada"</string> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index e070fd4fa75f..e897f1645a45 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -403,6 +403,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Notificările mai puțin urgente mai jos"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Atingeți din nou pentru a deschide"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Glisați în sus pentru a deschide"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Glisați pentru a încerca din nou"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Acest dispozitiv este gestionat de organizația dvs."</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Acest dispozitiv este gestionat de <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Glisați dinspre telefon"</string> @@ -547,6 +548,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Astfel rămâne afișat până anulați fixarea. Atingeți lung opțiunea Acasă pentru a anula fixarea."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Pentru a anula fixarea acestui ecran, atingeți lung butoanele Înapoi și Recente"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Pentru a anula fixarea acestui ecran, atingeți lung butoanele Înapoi și Acasă"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Pentru a anula fixarea acestui ecran, glisați în sus și mențineți"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Am înțeles"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Nu, mulțumesc"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Ecran fixat"</string> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index f895c02a7f53..c68f81e87039 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -405,6 +405,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Показать менее важные уведомления"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Нажмите ещё раз, чтобы открыть"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Проведите вверх, чтобы открыть"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Чтобы повторить попытку, проведите по экрану вверх."</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Этим устройством управляет ваша организация"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Этим устройством управляет компания \"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>\""</string> <string name="phone_hint" msgid="4872890986869209950">"Телефон: проведите от значка"</string> @@ -550,6 +551,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Приложение останется активным, пока вы не отмените блокировку, нажав и удерживая кнопку \"Главный экран\"."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Чтобы отменить блокировку, нажмите и удерживайте кнопки \"Назад\" и \"Обзор\""</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Чтобы отменить блокировку, нажмите и удерживайте кнопки \"Назад\" и \"Главный экран\""</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Чтобы открепить этот экран, проведите по нему вверх и задержите руку в крайнем положении."</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"ОК"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Нет, спасибо"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Блокировка включена"</string> diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml index 9e002152383e..2c54218778b9 100644 --- a/packages/SystemUI/res/values-si/strings.xml +++ b/packages/SystemUI/res/values-si/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"හදිසිය අඩු දැනුම් දීම් පහත"</string> <string name="notification_tap_again" msgid="7590196980943943842">"විවෘත කිරීමට නැවත තට්ටු කරන්න"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"විවෘත කිරීමට ස්වයිප් කරන්න"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"නැවත උත්සාහ කිරීමට ඉහළට ස්වයිප් කරන්න"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"මෙම උපාංගය ඔබගේ සංවිධානය විසින් කළමනාකරණය කරනු ලැබේ"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"මෙම උපාංගය <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> මගින් කළමනාකරණය කෙරේ"</string> <string name="phone_hint" msgid="4872890986869209950">"දුරකථනය සඳහා නිරූපකය වෙතින් ස්වයිප් කරන්න"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"මෙය ඔබ ගලවන තෙක් එය දසුන තුළ තබයි. ගැලවීමට මුල් පිටුව ස්පර්ශ කර අල්ලාගෙන සිටින්න."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"මෙම තිර ඇමුණුම ගැලවීමට, දළ විශ්ලේෂණය බොත්තම් ස්පර්ශ කර අල්ලා ගෙන සිටින්න"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"මෙම තිරය ඇමුණුම ගැලවීමට, මුල් පිටුව බොත්තම් ස්පර්ශ කර අල්ලා ගෙන සිටින්න"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"මෙම තිරය ගැලවීමට, ඉහළට ස්වයිප් කර අල්ලාගෙන සිටින්න"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"හරි, තේරුණා"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"එපා ස්තූතියි"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"තිරය අමුණා ඇත"</string> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index dabe3308235f..d14f928f75a1 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -405,6 +405,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Menej naliehavé upozornenia sa nachádzajú nižšie"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Upozornenie otvoríte opätovným klepnutím"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Otvorte potiahnutím prstom nahor"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Potiahnutím nahor to skúsite znova"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Toto zariadenie spravuje vaša organizácia"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Toto zariadenie spravuje organizácia <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Telefón otvoríte prejdením prstom od ikony"</string> @@ -550,6 +551,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Obsah bude pripnutý v zobrazení, dokým ho neuvoľníte. Uvoľníte ho pridržaním tlačidla Domov."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Ak chcete odopnúť túto obrazovku, pridržte tlačidlá Späť a Prehľad"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Ak chcete odopnúť túto obrazovku, pridržte tlačidlá Späť a Prehľad"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Túto obrazovku odopnete potiahnutím prsta nahor a pridržaním"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Dobre"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Nie, vďaka"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Obrazovka bola pripnutá"</string> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index 2958dc870feb..63358babeb13 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -405,6 +405,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Manj nujna obvestila spodaj"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Znova se dotaknite, da odprete"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Povlecite navzgor, da odprete"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Povlecite navzgor za vnovičen poskus"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"To napravo upravlja vaša organizacija"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"To napravo upravlja <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Povlecite z ikone za telefon"</string> @@ -550,6 +551,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"S tem ostane zaslon viden, dokler ga ne odpnete. Če ga želite odpeti, pridržite gumb za začetni zaslon."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Če želite odpeti ta zaslon, hkrati pridržite gumba za nazaj in za pregled."</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Če želite odpeti ta zaslon, hkrati pridržite gumba za nazaj in za začetni zaslon."</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Če želite odpeti ta zaslon, povlecite navzgor in pridržite"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Razumem"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Ne, hvala"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Zaslon je pripet"</string> diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml index 1f75490ebe5d..c948328f76cc 100644 --- a/packages/SystemUI/res/values-sq/strings.xml +++ b/packages/SystemUI/res/values-sq/strings.xml @@ -298,7 +298,7 @@ <string name="dessert_case" msgid="1295161776223959221">"\"Kutia e ëmbëlsirës\""</string> <string name="start_dreams" msgid="5640361424498338327">"Mbrojtësi i ekranit"</string> <string name="ethernet_label" msgid="7967563676324087464">"Eternet"</string> - <string name="quick_settings_header_onboarding_text" msgid="8030309023792936283">"Trokit dhe mbaj prekur ikonat për më shumë opsione"</string> + <string name="quick_settings_header_onboarding_text" msgid="8030309023792936283">"Trokit dhe mbaj të shtypur ikonat për më shumë opsione"</string> <string name="quick_settings_dnd_label" msgid="7112342227663678739">"Mos shqetëso"</string> <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Vetëm me prioritet"</string> <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Vetëm alarmet"</string> @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Njoftimet më pak urgjente, më poshtë!"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Trokit përsëri për ta hapur"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Rrëshqit lart për ta hapur"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Rrëshqit lart për të provuar përsëri"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Kjo pajisje menaxhohet nga organizata jote"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Kjo pajisje menaxhohet nga <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Rrëshqit për të hapur telefonin"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Kjo e ruan në pamje deri sa ta heqësh nga gozhdimi. Prek dhe mbaj të shtypur \"Kreu\" për ta hequr nga gozhdimi."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Për të hequr gozhdimin e këtij ekrani, prek dhe mbaj butonat \"Prapa\" dhe \"Përmbledhja\"."</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Për të hequr gozhdimin e këtij ekrani, prek dhe mbaj butonat \"Prapa\" dhe \"Kreu\"."</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Për të hequr gozhdimin e këtij ekrani, rrëshqit shpejt lart dhe mbaje të shtypur"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"E kuptova"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Jo, faleminderit!"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Ekrani u gozhdua"</string> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index f1bf3c9e356d..4d289dc2b428 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -403,6 +403,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Мање хитна обавештења су у наставку"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Додирните поново да бисте отворили"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Превуците нагоре да бисте отворили"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Превуците нагоре да бисте пробали поново"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Овим уређајем управља организација"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Овим уређајем управља <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Превуците од иконе за телефон"</string> @@ -547,6 +548,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"На овај начин се ово стално приказује док га не откачите. Додирните и задржите Почетна да бисте га откачили."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Да бисте откачили овај екран, додирните и задржите дугмад Назад и Преглед"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Да бисте откачили овај екран, додирните и задржите дугмад Назад и Почетна"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Да бисте откачили овај екран, превуците нагоре и задржите"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Важи"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Не, хвала"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Екран је закачен"</string> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index 764ad50b69db..b891b9382268 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Mindre brådskande aviseringar nedan"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Tryck igen för att öppna"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Öppna genom att svepa uppåt"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Svep uppåt om du vill försöka igen"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Den här enheten hanteras av organisationen"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Den här enheten hanteras av <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Svep från ikonen och öppna telefonen"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Skärmen visas tills du lossar den. Tryck länge på Startsida om du vill lossa skärmen."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Om du vill lossa skärmen trycker du länge på knapparna Tillbaka och Översikt"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Om du vill lossa skärmen trycker du länge på knapparna Tillbaka och Startsida"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Svep uppåt och håll kvar fingret om du vill lossa skärmen"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"OK"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Nej tack"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Skärmen är fäst"</string> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index 640bbda0d2a3..b37405aa19eb 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Arifa zisizo za dharura sana ziko hapo chini"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Gusa tena ili ufungue"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Telezesha kidole juu ili ufungue"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Telezesha kidole juu ili ujaribu tena"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Kifaa hiki kinasimamiwa na shirika lako"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Kifaa hiki kinadhibitiwa na <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Telezesha kidole kutoka kwa aikoni ili ufikie simu"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Hali hii huifanya ionekane hadi utakapoibandua. Gusa na ushikilie kitufe cha Mwanzo ili ubandue."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Ili ubandue skrini hii, gusa na ushikilie kitufe cha Nyuma na Muhtasari"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Ili ubandue skrini hii, gusa na ushikilie vitufe vya Nyuma na Mwanzo"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Ili ubandue skrini hii, telezesha kidole juu na ushikilie"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Nimeelewa"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Hapana, asante"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Skrini imebandikwa"</string> diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml index 6e8b0974087a..2b12149e06ad 100644 --- a/packages/SystemUI/res/values-ta/strings.xml +++ b/packages/SystemUI/res/values-ta/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"அவசர நிலைக் குறைவான அறிவிப்புகள் கீழே உள்ளன"</string> <string name="notification_tap_again" msgid="7590196980943943842">"திறக்க, மீண்டும் தட்டவும்"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"திறப்பதற்கு மேல் நோக்கி ஸ்வைப் செய்யவும்"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"மீண்டும் முயல மேல்நோக்கி ஸ்வைப் செய்யவும்"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"இந்தச் சாதனத்தை உங்கள் நிறுவனம் நிர்வகிக்கிறது"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"இந்தச் சாதனத்தை நிர்வகிப்பது: <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"ஃபோனிற்கு ஐகானிலிருந்து ஸ்வைப் செய்யவும்"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"இதற்கான பின்னை அகற்றும் வரை, இந்தப் பயன்முறை செயல்பாட்டிலேயே இருக்கும். அகற்றுவதற்கு, முகப்புப் பொத்தானைத் தொட்டுப் பிடிக்கவும்."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"இந்தத் திரையின் பின்னை அகற்ற, முந்தையது மற்றும் மேலோட்டப் பார்வைப் பொத்தான்களைத் தொட்டுப் பிடிக்கவும்"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"இந்தத் திரையின் பின்னை அகற்ற, முந்தையது மற்றும் முகப்புப் பொத்தான்களைத் தொட்டுப் பிடிக்கவும்"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"இந்தத் திரையை அகற்ற மேல்நோக்கி ஸ்வைப் செய்தவாறு பிடித்திருக்கவும்"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"புரிந்தது"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"வேண்டாம்"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"திரை பின் செய்யப்பட்டது"</string> @@ -843,7 +845,7 @@ <string name="pip_skip_to_prev" msgid="1955311326688637914">"முந்தையதற்குச் செல்"</string> <string name="thermal_shutdown_title" msgid="4458304833443861111">"வெப்பத்தினால் ஃபோன் ஆஃப் செய்யப்பட்டது"</string> <string name="thermal_shutdown_message" msgid="9006456746902370523">"இப்போது உங்கள் ஃபோன் இயல்புநிலையில் இயங்குகிறது"</string> - <string name="thermal_shutdown_dialog_message" msgid="566347880005304139">"உங்கள் ஃபோன் அதிகமாகச் சூடானதால், அதன் சூட்டைக் குறைக்க, ஆஃப் செய்யப்பட்டது. இப்போது உங்கள் ஃபோன் இயல்புநிலையில் இயங்குகிறது.\n\nபின்வருவனவற்றைச் செய்தால், ஃபோன் சூடாகலாம்:\n • அதிகளவு தரவைப் பயன்படுத்தும் பயன்பாடுகளை (எ.கா: கேமிங், வீடியோ (அ) வழிகாட்டுதல் பயன்பாடுகள்) பயன்படுத்துவது\n • பெரிய கோப்புகளைப் பதிவிறக்குவது/பதிவேற்றுவது\n • அதிக வெப்பநிலையில் ஃபோனைப் பயன்படுத்துவது"</string> + <string name="thermal_shutdown_dialog_message" msgid="566347880005304139">"உங்கள் ஃபோன் அதிகமாகச் சூடானதால், அதன் சூட்டைக் குறைக்க, ஆஃப் செய்யப்பட்டது. இப்போது உங்கள் ஃபோன் இயல்புநிலையில் இயங்குகிறது.\n\nபின்வருவனவற்றைச் செய்தால், ஃபோன் சூடாகலாம்:\n • அதிகளவு தரவைப் பயன்படுத்தும் ஆப்ஸை (எ.கா: கேமிங், வீடியோ (அ) வழிகாட்டுதல் பயன்பாடுகள்) பயன்படுத்துவது\n • பெரிய கோப்புகளைப் பதிவிறக்குவது/பதிவேற்றுவது\n • அதிக வெப்பநிலையில் ஃபோனைப் பயன்படுத்துவது"</string> <string name="high_temp_title" msgid="4589508026407318374">"மொபைல் சூடாகிறது"</string> <string name="high_temp_notif_message" msgid="5642466103153429279">"மொபைலின் வெப்ப அளவு குறையும் போது, சில அம்சங்களைப் பயன்படுத்த முடியாது"</string> <string name="high_temp_dialog_message" msgid="6840700639374113553">"உங்கள் மொபைலின் வெப்ப அளவு தானாகவே குறையும். தொடர்ந்து நீங்கள் மொபைலைப் பயன்படுத்தலாம், ஆனால் அதன் வேகம் குறைவாக இருக்கக்கூடும்.\n\nமொபைலின் வெப்ப அளவு குறைந்தவுடன், அது இயல்பு நிலையில் இயங்கும்."</string> diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml index 5717e02f0877..350ccc6e2787 100644 --- a/packages/SystemUI/res/values-te/strings.xml +++ b/packages/SystemUI/res/values-te/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"తక్కువ అత్యవసర నోటిఫికేషన్లు దిగువన"</string> <string name="notification_tap_again" msgid="7590196980943943842">"తెరవడానికి మళ్లీ నొక్కండి"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"తెరవడానికి, పైకి స్వైప్ చేయండి"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"మళ్ళీ ప్రయత్నించడానికి పైకి స్వైప్ చేయండి"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"ఈ పరికరాన్ని మీ సంస్థ నిర్వహిస్తోంది"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"ఈ పరికరం <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> నిర్వహణలో ఉంది"</string> <string name="phone_hint" msgid="4872890986869209950">"ఫోన్ కోసం చిహ్నాన్ని స్వైప్ చేయండి"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"దీని వలన మీరు అన్పిన్ చేసే వరకు ఇది వీక్షణలో ఉంచబడుతుంది. అన్పిన్ చేయడానికి హోమ్ని తాకి & అలాగే పట్టుకోండి."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"ఈ స్క్రీన్ను అన్పిన్ చేయడానికి, వెనుకకు మరియు అవలోకనం బటన్లను తాకి & అలాగే పట్టుకోండి"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"ఈ స్క్రీన్ను అన్పిన్ చేయడానికి, వెనుకకు మరియు హోమ్ బటన్లను తాకి & అలాగే పట్టుకోండి"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"ఈ స్క్రీన్ను అన్పిన్ చేయడానికి, పైకి స్వైప్ చేసి & అలాగే పట్టుకోండి"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"అర్థమైంది"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"వద్దు, ధన్యవాదాలు"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"స్క్రీన్ పిన్ చేయబడింది"</string> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index ce123a5d9736..9d39859c27a0 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"การแจ้งเตือนที่เร่งด่วนน้อยด้านล่าง"</string> <string name="notification_tap_again" msgid="7590196980943943842">"แตะอีกครั้งเพื่อเปิด"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"เลื่อนขึ้นเพื่อเปิด"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"เลื่อนขึ้นเพื่อลองอีกครั้ง"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"อุปกรณ์นี้จัดการโดยองค์กรของคุณ"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"อุปกรณ์เครื่องนี้จัดการโดย <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"เลื่อนไอคอนโทรศัพท์"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"การดำเนินการนี้จะแสดงหน้าจอนี้ไว้เสมอจนกว่าคุณจะเลิกตรึง แตะ \"หน้าแรก\" ค้างไว้เพื่อเลิกตรึง"</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"หากต้องการเลิกตรึงหน้าจอนี้ ให้แตะปุ่ม \"กลับ\" และ \"ภาพรวม\" ค้างไว้"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"หากต้องการเลิกตรึงหน้าจอนี้ ให้แตะปุ่ม \"กลับ\" และ \"หน้าแรก\" ค้างไว้"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"หากต้องการเลิกตรึงหน้าจอนี้ ให้เลื่อนขึ้นค้างไว้"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"รับทราบ"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"ไม่เป็นไร ขอบคุณ"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"ตรึงหน้าจอแล้ว"</string> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index 0ab01d8858e1..56da2329ab5c 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Nasa ibaba ang mga notification na hindi masyadong mahalaga"</string> <string name="notification_tap_again" msgid="7590196980943943842">"I-tap ulit upang buksan"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Mag-swipe pataas para buksan"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Mag-swipe pataas para subukan ulit"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Ang device na ito ay pinamamahalaan ng iyong organisasyon"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Pinamamahalaan ng <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ang device na ito"</string> <string name="phone_hint" msgid="4872890986869209950">"Mag-swipe mula sa icon para sa telepono"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Pinapanatili nitong nakikita ito hanggang sa mag-unpin ka. Pindutin nang matagal ang Home upang mag-unpin."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Upang i-unpin ang screen na ito, pindutin nang matagal ang mga button na Bumalik at Overview"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Upang i-unpin ang screen na ito, pindutin nang matagal ang mga button na Bumalik at Home"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Para i-unpin ang screen na ito, mag-swipe pataas at pumindot nang matagal"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Nakuha ko"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Hindi, salamat na lang"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Na-pin ang screen"</string> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index 4e2a8913d307..257b9decaeb2 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Daha az acil bildirimler aşağıdadır"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Açmak için tekrar dokunun"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Açmak için yukarı kaydırın"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Tekrar denemek için yukarı kaydırın"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Bu cihaz kuruluşunuz tarafından yönetiliyor"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Bu cihaz <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> tarafından yönetilmektedir."</string> <string name="phone_hint" msgid="4872890986869209950">"Telefon için, simgeden hızlıca kaydırın"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Bu işlem, siz sabitlemeyi kaldırana kadar ekranı görünür durumda tutar. Sabitlemeyi kaldırmak için Ana sayfaya dokunup basılı tutun."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Bu ekranın sabitlemesini kaldırmak için Geri ve Genel Bakış düğmelerine dokunup basılı tutun"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Bu ekranın sabitlemesini kaldırmak için Geri ve Ana sayfa düğmelerine dokunup basılı tutun"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Bu ekranın sabitlemesini kaldırmak için hızlıca yukarı kaydırıp tutun"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Anladım"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Hayır, teşekkürler"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Ekran sabitlendi"</string> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index 56521f6eb1aa..d82acf7de9af 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -405,6 +405,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Менше термінових сповіщень нижче"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Торкніться знову, щоб відкрити"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Проведіть пальцем угору, щоб відкрити"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Проведіть пальцем угору, щоб повторити спробу"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Цим пристроєм керує адміністратор вашої організації"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Цим пристроєм керує організація <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Телефон: проведіть пальцем від значка"</string> @@ -550,6 +551,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Ви бачитимете цей екран, доки не відкріпите його. Для цього натисніть і утримуйте кнопку \"Головний екран\"."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Щоб відкріпити цей екран, натисніть і утримуйте кнопки \"Назад\" та \"Огляд\""</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Щоб відкріпити цей екран, натисніть і утримуйте кнопки \"Назад\" та \"Головний екран\""</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Щоб відкріпити цей екран, проведіть пальцем вгору й утримуйте"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Зрозуміло"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Ні, дякую"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Екран закріплено"</string> diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml index b698fe468673..7d4f177b6c1c 100644 --- a/packages/SystemUI/res/values-ur/strings.xml +++ b/packages/SystemUI/res/values-ur/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"کم اہم اطلاعات ذیل میں ہیں"</string> <string name="notification_tap_again" msgid="7590196980943943842">"کھولنے کیلئے دوبارہ تھپتھپائیں"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"کھولنے کے لیے اوپر سوائپ کريں"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"دوبارہ کوشش کرنے کے لیے اوپر سوائپ کريں"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"یہ آلہ آپ کی تنظیم کے زیر انتظام ہے"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"یہ آلہ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> کے زیر انتظام ہے"</string> <string name="phone_hint" msgid="4872890986869209950">"فون کیلئے آئیکن سے سوائپ کریں"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"یہ اس کو اس وقت تک مد نظر رکھتا ہے جب تک آپ اس سے پن نہیں ہٹا دیتے۔ پن ہٹانے کیلئے \"ہوم\" بٹن کو ٹچ کریں اور دبائے رکھیں۔"</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"اس اسکرین سے پن ہٹانے کیلئے، \"پیچھے\" اور \"مجموعی جائزہ\" بٹنز کو ٹچ کریں اور دبائے رکھیں"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"اس اسکرین سے پن ہٹانے کیلئے، \"پیچھے\" اور \"ہوم\" بٹنز کو ٹچ کریں اور دبائے رکھیں"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"اس اسکرین سے پن ہٹانے کے لیے، اوپر کی طرف سوائپ کریں: دبائیں رکھیں"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"سمجھ آ گئی"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"نہیں شکریہ"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"اسکرین کو پن کر دیا گیا"</string> diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml index c732d4c460e4..eaca944ec22d 100644 --- a/packages/SystemUI/res/values-uz/strings.xml +++ b/packages/SystemUI/res/values-uz/strings.xml @@ -60,7 +60,7 @@ <string name="usb_debugging_always" msgid="303335496705863070">"Doimo ushbu kompyuterdan ruxsat berilsin"</string> <string name="usb_debugging_allow" msgid="2272145052073254852">"Ruxsat berish"</string> <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"USB orqali nosozliklarni tuzatishga ruxsat berilmagan"</string> - <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Ayni paytda ushbu qurilmaga o‘z hisobi bilan kirgan foydalanuvchi USB orqali nosozliklarni tuzatish funksiyasini yoqa olmaydi. Bu funksiyadan foydalanish uchun asosiy foydalanuvchi profiliga o‘ting."</string> + <string name="usb_debugging_secondary_user_message" msgid="6067122453571699801">"Ayni paytda ushbu qurilmaga o‘z hisobi bilan kirgan foydalanuvchi USB orqali nosozliklarni aniqlash funksiyasini yoqa olmaydi. Bu funksiyadan foydalanish uchun asosiy foydalanuvchi profiliga o‘ting."</string> <string name="usb_contaminant_title" msgid="206854874263058490">"USB port faolsizlashtirildi"</string> <string name="usb_contaminant_message" msgid="7379089091591609111">"Qurilmangizni suyuqlik va turli parchalardan himoya qilish uchun USB port faolsizlashtiriladi va hech qanday aksessuarni aniqlay olmaydi.\n\nUSB portdan xavfsiz foydalanish mumkin boʻlganda, sizga xabar beriladi."</string> <string name="usb_port_enabled" msgid="7906141351687694867">"Quvvatlash moslamalari va aksessuarlarni aniqlash uchun USB port yoqildi"</string> @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Kam ahamiyatli bildirishnomalarni pastda ko‘rsatish"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Ochish uchun yana bosing"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Ochish uchun tepaga suring"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Tepaga suring va qayta urining"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Bu – tashkilotingiz tomonidan boshqariladigan qurilma"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Bu – <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> tomonidan boshqariladigan qurilma"</string> <string name="phone_hint" msgid="4872890986869209950">"Telefonni ochish uchun suring"</string> @@ -458,7 +459,7 @@ <string name="media_projection_remember_text" msgid="3103510882172746752">"Boshqa ko‘rsatilmasin"</string> <string name="clear_all_notifications_text" msgid="814192889771462828">"Hammasini tozalash"</string> <string name="manage_notifications_text" msgid="2386728145475108753">"Boshqarish"</string> - <string name="notification_section_header_gentle" msgid="4372438504154095677">"Ovozsiz bildirishnomalar"</string> + <string name="notification_section_header_gentle" msgid="4372438504154095677">"Sokin bildirishnomalar"</string> <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"Barcha tovushsiz bildirishnomalarni tozalash"</string> <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Bezovta qilinmasin rejimida bildirishnomalar pauza qilingan"</string> <string name="media_projection_action_text" msgid="8470872969457985954">"Boshlash"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Ekran yechib olinmagunicha u mahkamlangan holatda qoladi. Uni yechish uchun Orqaga va Asosiy tugmlarni birga bosib turing."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Bu ekrandan chiqish uchun Orqaga va Menyu tugmalarini bosib turing"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Bu ekrandan chiqish uchun Orqaga va Boshi tugmalarini bosib turing"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Bu ekrandan chiqish uchun tepaga surib, bosib turing"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"OK"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Yo‘q, kerakmas"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Ekran mahkamlandi"</string> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index 7a1897aec569..d3caa2b2c75d 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Thông báo ít khẩn cấp hơn bên dưới"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Nhấn lại để mở"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Vuốt lên để mở"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Vuốt lên để thử lại"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Thiết bị này do tổ chức của bạn quản lý"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Thiết bị này được <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> quản lý"</string> <string name="phone_hint" msgid="4872890986869209950">"Vuốt từ biểu tượng để mở điện thoại"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Thao tác này sẽ duy trì hiển thị màn hình cho đến khi bạn bỏ ghim. Hãy chạm và giữ nút Màn hình chính để bỏ ghim."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Để bỏ ghim màn hình này, hãy chạm và giữ nút Quay lại và nút Tổng quan"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Để bỏ ghim màn hình này, hãy chạm và giữ nút Quay lại và nút Màn hình chính"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Để bỏ ghim màn hình này, hãy vuốt lên và giữ"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Ok"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Không, cảm ơn"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Đã ghim màn hình"</string> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index b3bf97366c15..ca72b08231c2 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"不太紧急的通知会显示在下方"</string> <string name="notification_tap_again" msgid="7590196980943943842">"再次点按即可打开"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"向上滑动即可打开"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"向上滑动即可重试"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"此设备由您所属单位管理"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"此设备是由<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>托管"</string> <string name="phone_hint" msgid="4872890986869209950">"滑动图标即可拨打电话"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"这将会固定显示此屏幕,直到您取消固定为止。触摸并按住“主屏幕”即可取消固定屏幕。"</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"要取消固定此屏幕,请触摸并按住“返回”和“概览”按钮"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"要取消固定此屏幕,请触摸并按住“返回”和“主屏幕”按钮"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"要取消固定此屏幕,请向上滑动并按住"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"知道了"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"不用了"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"已固定屏幕"</string> diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index 59480a9d99ee..128e1ca76fb0 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"不太緊急的通知會在下方顯示"</string> <string name="notification_tap_again" msgid="7590196980943943842">"再次輕按即可開啟"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"向上滑動即可開啟"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"請向上滑動以再試一次"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"此裝置由您的機構管理"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"此裝置由<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>管理"</string> <string name="phone_hint" msgid="4872890986869209950">"從圖示滑動即可使用手機功能"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"畫面將會繼續顯示,直至您取消固定為止。按住主按鈕即可取消固定。"</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"如要取消固定此畫面,請按住 [返回] 按鈕和 [概覽] 按鈕"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"如要取消固定此畫面,請按住 [返回] 按鈕和主按鈕"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"如要取消固定此畫面,請向上滑動然後按住"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"知道了"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"不用了,謝謝"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"已固定畫面"</string> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index c26da4f0dd5b..457206dc9dc1 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -69,13 +69,13 @@ <string name="compat_mode_on" msgid="6623839244840638213">"放大為全螢幕"</string> <string name="compat_mode_off" msgid="4434467572461327898">"放大為全螢幕"</string> <string name="global_action_screenshot" msgid="8329831278085426283">"擷取螢幕畫面"</string> - <string name="screenshot_saving_ticker" msgid="7403652894056693515">"正在儲存螢幕擷取畫面…"</string> - <string name="screenshot_saving_title" msgid="8242282144535555697">"正在儲存螢幕擷取畫面…"</string> - <string name="screenshot_saved_title" msgid="5637073968117370753">"螢幕擷取畫面已儲存"</string> - <string name="screenshot_saved_text" msgid="7574667448002050363">"輕觸即可查看螢幕擷取畫面"</string> - <string name="screenshot_failed_title" msgid="7612509838919089748">"無法儲存螢幕擷取畫面"</string> - <string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"請再次嘗試拍攝螢幕擷取畫面"</string> - <string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"由於儲存空間有限,因此無法儲存螢幕擷取畫面"</string> + <string name="screenshot_saving_ticker" msgid="7403652894056693515">"正在儲存螢幕截圖…"</string> + <string name="screenshot_saving_title" msgid="8242282144535555697">"正在儲存螢幕截圖…"</string> + <string name="screenshot_saved_title" msgid="5637073968117370753">"螢幕截圖已儲存"</string> + <string name="screenshot_saved_text" msgid="7574667448002050363">"輕觸即可查看螢幕截圖"</string> + <string name="screenshot_failed_title" msgid="7612509838919089748">"無法儲存螢幕截圖"</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"請再次嘗試拍攝螢幕截圖"</string> + <string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"由於儲存空間有限,因此無法儲存螢幕截圖"</string> <string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"這個應用程式或貴機構不允許擷取螢幕畫面"</string> <string name="screenrecord_name" msgid="4196719243134204796">"錄製螢幕畫面"</string> <string name="screenrecord_channel_description" msgid="4630777331970993858">"持續顯示螢幕畫面錄製工作階段通知"</string> @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"較不緊急的通知會顯示在下方"</string> <string name="notification_tap_again" msgid="7590196980943943842">"再次輕觸即可開啟"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"向上滑動即可開啟"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"向上滑動即可重試"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"這個裝置是由貴機構所管理"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"這個裝置是由 <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> 所管理"</string> <string name="phone_hint" msgid="4872890986869209950">"滑動手機圖示即可啟用"</string> @@ -458,8 +459,8 @@ <string name="media_projection_remember_text" msgid="3103510882172746752">"不要再顯示"</string> <string name="clear_all_notifications_text" msgid="814192889771462828">"全部清除"</string> <string name="manage_notifications_text" msgid="2386728145475108753">"管理"</string> - <string name="notification_section_header_gentle" msgid="4372438504154095677">"無聲通知"</string> - <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"清除所有無聲通知"</string> + <string name="notification_section_header_gentle" msgid="4372438504154095677">"靜音通知"</string> + <string name="accessibility_notification_section_header_gentle_clear_all" msgid="4286716295850400959">"清除所有靜音通知"</string> <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"「零打擾」模式已將通知設為暫停"</string> <string name="media_projection_action_text" msgid="8470872969457985954">"立即開始"</string> <string name="empty_shade_text" msgid="708135716272867002">"沒有通知"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"這會讓應用程式顯示在螢幕上,直到取消固定為止。按住主螢幕按鈕即可取消固定。"</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"如要取消固定這個螢幕畫面,請按住「返回」按鈕和「總覽」按鈕"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"如要取消固定這個螢幕畫面,請按住「返回」按鈕和主螢幕按鈕"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"如要取消固定畫面,請向上滑動並按住"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"知道了"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"不用了,謝謝"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"已固定螢幕畫面"</string> @@ -643,7 +645,7 @@ <string name="inline_block_button" msgid="8735843688021655065">"封鎖"</string> <string name="inline_keep_button" msgid="6665940297019018232">"繼續顯示"</string> <string name="inline_minimize_button" msgid="966233327974702195">"最小化"</string> - <string name="inline_silent_button_silent" msgid="5315879183296940969">"無聲"</string> + <string name="inline_silent_button_silent" msgid="5315879183296940969">"靜音"</string> <string name="inline_silent_button_stay_silent" msgid="6308371431217601009">"繼續顯示通知但不發出音效"</string> <string name="inline_silent_button_alert" msgid="6008435419895088034">"快訊"</string> <string name="inline_silent_button_keep_alerting" msgid="327696842264359693">"繼續顯示通知"</string> @@ -866,7 +868,7 @@ <string name="tuner_app" msgid="3507057938640108777">"「<xliff:g id="APP">%1$s</xliff:g>」應用程式"</string> <string name="notification_channel_alerts" msgid="4496839309318519037">"快訊"</string> <string name="notification_channel_battery" msgid="5786118169182888462">"電池"</string> - <string name="notification_channel_screenshot" msgid="6314080179230000938">"螢幕擷取畫面"</string> + <string name="notification_channel_screenshot" msgid="6314080179230000938">"螢幕截圖"</string> <string name="notification_channel_general" msgid="4525309436693914482">"一般訊息"</string> <string name="notification_channel_storage" msgid="3077205683020695313">"儲存空間"</string> <string name="notification_channel_hints" msgid="7323870212489152689">"提示"</string> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index 74b9143bbcce..2306e4ab23fa 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -401,6 +401,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Izaziso ezingasheshi kakhulu ezingezansi"</string> <string name="notification_tap_again" msgid="7590196980943943842">"Thepha futhi ukuze uvule"</string> <string name="keyguard_unlock" msgid="6035822649218712063">"Swayiphela phezulu ukuze uvule"</string> + <string name="keyguard_retry" msgid="5221600879614948709">"Swayiphela phezulu ukuze uzame futhi"</string> <string name="do_disclosure_generic" msgid="5615898451805157556">"Le divayisi iphethwe inhlangano yakho"</string> <string name="do_disclosure_with_name" msgid="5640615509915445501">"Le divayisi iphethwe yi-<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string> <string name="phone_hint" msgid="4872890986869209950">"Swayiphela ifoni kusukela kusithonjana"</string> @@ -544,6 +545,7 @@ <string name="screen_pinning_description_recents_invisible_accessible" msgid="6134833683151189507">"Lokhu kuyigcina ibukeka uze ususe ukuphina. Thinta uphinde ubambe okuthi Ekhaya ukuze ususe ukuphina."</string> <string name="screen_pinning_toast" msgid="2266705122951934150">"Ukuze ususe ukuphina lesi sikrini, thinta uphinde ubambe izinkinobho zokubuyela emuva nezokubuka konke"</string> <string name="screen_pinning_toast_recents_invisible" msgid="8252402309499161281">"Ukuze ususe ukuphina lesi sikrini, thinta uphinde ubambe izinkinobho nezithi Emuva nethi Ekhaya"</string> + <string name="screen_pinning_toast_gesture_nav" msgid="5070548776081664958">"Ukuze ususe ukuphina lesi sikrini, swayiphela phezulu futhi ubambe"</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Ngiyitholile"</string> <string name="screen_pinning_negative" msgid="3741602308343880268">"Cha ngiyabonga"</string> <string name="screen_pinning_start" msgid="1022122128489278317">"Isikrini siphiniwe"</string> diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index 340cb3ad7358..78318cb7e858 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -196,9 +196,6 @@ <!-- Doze: duration to avoid false pickup gestures triggered by notification vibrations --> <integer name="doze_pickup_vibration_threshold">2000</integer> - <!-- Doze: can we assume the pickup sensor includes a proximity check? --> - <bool name="doze_pickup_performs_proximity_check">false</bool> - <!-- Type of a sensor that provides a low-power estimate of the desired display brightness, suitable to listen to while the device is asleep (e.g. during always-on display) --> @@ -276,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> @@ -307,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/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index bef1fc2f271c..be815e13e68e 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -385,22 +385,16 @@ <!-- The width of the panel that holds the quick settings. --> <dimen name="qs_panel_width">@dimen/notification_panel_width</dimen> - <dimen name="volume_dialog_panel_transparent_padding_right">8dp</dimen> + <dimen name="volume_dialog_panel_transparent_padding_right">4dp</dimen> <dimen name="volume_dialog_panel_transparent_padding">20dp</dimen> <dimen name="volume_dialog_stream_padding">8dp</dimen> - <!-- the amount the volume panel should be offset at the end from the view next to it (or - the screen edge, in portrait--> - <dimen name="volume_dialog_base_margin">8dp</dimen> - <dimen name="volume_dialog_panel_width">64dp</dimen> <dimen name="volume_dialog_slider_height">116dp</dimen> - <dimen name="volume_dialog_row_height">252dp</dimen> - <dimen name="volume_dialog_ringer_size">64dp</dimen> <dimen name="volume_dialog_ringer_icon_padding">20dp</dimen> @@ -417,8 +411,6 @@ <dimen name="volume_dialog_row_margin_bottom">8dp</dimen> - <dimen name="volume_dialog_settings_icon_size">16dp</dimen> - <dimen name="volume_dialog_elevation">9dp</dimen> <dimen name="volume_tool_tip_right_margin">76dp</dimen> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 7feacb469f81..19e682b4b6a4 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -958,6 +958,9 @@ <!-- Message shown when lock screen is tapped or face authentication fails. [CHAR LIMIT=60] --> <string name="keyguard_unlock">Swipe up to open</string> + <!-- Message shown when face authentication fails and the pin pad is visible. [CHAR LIMIT=60] --> + <string name="keyguard_retry">Swipe up to try again</string> + <!-- Text on keyguard screen and in Quick Settings footer indicating that the device is enterprise-managed by a Device Owner [CHAR LIMIT=60] --> <string name="do_disclosure_generic">This device is managed by your organization</string> @@ -1383,6 +1386,8 @@ buttons</string> <string name="screen_pinning_toast_recents_invisible">To unpin this screen, touch & hold Back and Home buttons</string> + <!-- Notify (in toast) user how to unpin screen in gesture navigation mode [CHAR LIMIT=NONE] --> + <string name="screen_pinning_toast_gesture_nav">To unpin this screen, swipe up & hold</string> <!-- Screen pinning positive response. --> <string name="screen_pinning_positive">Got it</string> <!-- Screen pinning negative response. --> diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java index 328116dc3c1b..13fc702aa0a0 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java @@ -236,7 +236,8 @@ public class ActivityManagerWrapper { @Override public void onAnimationCanceled(boolean deferredWithScreenshot) { - animationHandler.onAnimationCanceled(deferredWithScreenshot); + animationHandler.onAnimationCanceled( + deferredWithScreenshot ? new ThumbnailData() : null); } }; } diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationListener.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationListener.java index 5850fda617fc..579858a4f9b4 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationListener.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationListener.java @@ -18,6 +18,8 @@ package com.android.systemui.shared.system; import android.graphics.Rect; +import com.android.systemui.shared.recents.model.ThumbnailData; + public interface RecentsAnimationListener { /** @@ -29,5 +31,5 @@ public interface RecentsAnimationListener { /** * Called when the animation into Recents was canceled. This call is made on the binder thread. */ - void onAnimationCanceled(boolean deferredWithScreenshot); + void onAnimationCanceled(ThumbnailData thumbnailData); } 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 a4b6958498c8..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; @@ -253,6 +254,7 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout protected void onUserInput() { if (mCallback != null) { mCallback.userActivity(); + mCallback.onUserInput(); } mSecurityMessageDisplay.setMessage(""); } 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 55ddfc30d774..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; @@ -274,6 +275,7 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit @Override public void onPatternCellAdded(List<LockPatternView.Cell> pattern) { mCallback.userActivity(); + mCallback.onUserInput(); } @Override @@ -336,6 +338,7 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit }); if (pattern.size() > MIN_PATTERN_BEFORE_POKE_WAKELOCK) { mCallback.userActivity(); + mCallback.onUserInput(); } } 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/KeyguardSecurityCallback.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityCallback.java index cbfbffbe50a4..49dcfffb0d72 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityCallback.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityCallback.java @@ -55,4 +55,9 @@ public interface KeyguardSecurityCallback { default void onCancelClicked() { // No-op } + + /** + * Invoked whenever users are typing their password or drawing a pattern. + */ + void onUserInput(); } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java index 8059dcf33df7..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; @@ -596,6 +597,11 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe } } + @Override + public void onUserInput() { + mUpdateMonitor.cancelFaceAuth(); + } + public void dismiss(boolean authenticated, int targetId) { mSecurityCallback.dismiss(authenticated, targetId); } @@ -640,6 +646,8 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe @Override public void dismiss(boolean securityVerified, int targetUserId) { } @Override + public void onUserInput() { } + @Override public void reset() {} }; 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 109f270063d6..8d858dcb25df 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; @@ -844,11 +845,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { getCurrentUser()); } - // The face timeout message is not very actionable, let's ask the user to - // manually retry. - if (msgId == FaceManager.FACE_ERROR_TIMEOUT) { - errString = mContext.getString(R.string.keyguard_unlock); - } for (int i = 0; i < mCallbacks.size(); i++) { KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); if (cb != null) { @@ -1408,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++) { @@ -1443,7 +1440,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { } private void handleScreenTurnedOff() { - mLockIconPressed = false; mHardwareFingerprintUnavailableRetryCount = 0; mHardwareFaceUnavailableRetryCount = 0; final int count = mCallbacks.size(); @@ -1646,6 +1642,13 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { updateFaceListeningState(); } + /** + * In case face auth is running, cancel it. + */ + public void cancelFaceAuth() { + stopListeningForFace(); + } + private void updateFaceListeningState() { // If this message exists, we should not authenticate again until this message is // consumed by the handler @@ -1685,7 +1688,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { return shouldListen; } - private boolean shouldListenForFace() { + /** + * If face auth is allows to scan on this exact moment. + */ + public boolean shouldListenForFace() { final boolean awakeKeyguard = mKeyguardIsVisible && mDeviceInteractive && !mGoingToSleep; final int user = getCurrentUser(); final int strongAuth = mStrongAuthTracker.getStrongAuthForUser(user); 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/ContextComponentHelper.java b/packages/SystemUI/src/com/android/systemui/ContextComponentHelper.java new file mode 100644 index 000000000000..8fabe7aa9eb6 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/ContextComponentHelper.java @@ -0,0 +1,25 @@ +/* + * 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; + +/** + * Interface necessary to make Dagger happy. See {@link ContextComponentResolver}. + */ +public interface ContextComponentHelper { + /** Turns a classname into an instance of the class or returns null. */ + <T> T resolve(String className); +} diff --git a/packages/SystemUI/src/com/android/systemui/ContextComponentResolver.java b/packages/SystemUI/src/com/android/systemui/ContextComponentResolver.java new file mode 100644 index 000000000000..09bccd993f39 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/ContextComponentResolver.java @@ -0,0 +1,48 @@ +/* + * 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 java.util.Map; + +import javax.inject.Inject; +import javax.inject.Provider; + +/** + * Used during Service and Activity instantiation to make them injectable. + */ +public class ContextComponentResolver implements ContextComponentHelper { + private final Map<Class<?>, Provider<Object>> mCreators; + + @Inject + ContextComponentResolver(Map<Class<?>, Provider<Object>> creators) { + mCreators = creators; + } + + /** + * Looks up the class name to see if Dagger has an instance of it. + */ + @Override + public <T> T resolve(String className) { + for (Map.Entry<Class<?>, Provider<Object>> p : mCreators.entrySet()) { + if (p.getKey().getName().equals(className)) { + return (T) p.getValue().get(); + } + } + + return null; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/CornerHandleView.java b/packages/SystemUI/src/com/android/systemui/CornerHandleView.java index a94952c5bc19..6209c2c36206 100644 --- a/packages/SystemUI/src/com/android/systemui/CornerHandleView.java +++ b/packages/SystemUI/src/com/android/systemui/CornerHandleView.java @@ -19,6 +19,7 @@ package com.android.systemui; import android.animation.ArgbEvaluator; import android.content.Context; import android.graphics.Canvas; +import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.RectF; @@ -27,6 +28,7 @@ import android.util.DisplayMetrics; import android.view.ContextThemeWrapper; import android.view.View; +import com.android.internal.graphics.ColorUtils; import com.android.settingslib.Utils; /** @@ -107,6 +109,7 @@ public class CornerHandleView extends View { mPaint.setColor((int) ArgbEvaluator.getInstance().evaluate(darkIntensity, mLightColor, mDarkColor)); + updateShadow(); if (getVisibility() == VISIBLE) { invalidate(); } @@ -118,6 +121,21 @@ public class CornerHandleView extends View { canvas.drawPath(mPath, mPaint); } + private void updateShadow() { + if (ColorUtils.calculateLuminance(mPaint.getColor()) > 0.7f) { + mPaint.setShadowLayer(/** radius */ 5,/** shadowDx */ 0, /** shadowDy */ -1, + /** color */ ColorUtils.setAlphaComponent(/** color */ Color.BLACK, + /** alpha */ 102)); + } else { + mPaint.setShadowLayer(/** radius */ 0, /** shadowDx */ 0, /** shadowDy */ 0, + /** color */ Color.TRANSPARENT); + } + + if (getVisibility() == VISIBLE) { + invalidate(); + } + } + private static float convertDpToPixel(float dp, Context context) { return dp * ((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT); 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/ForegroundServiceNotificationListener.java b/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java index 96b62ac918ab..46e08661cd70 100644 --- a/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java +++ b/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java @@ -16,14 +16,20 @@ package com.android.systemui; +import android.annotation.NonNull; import android.app.Notification; import android.app.NotificationManager; import android.content.Context; import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; import android.service.notification.StatusBarNotification; +import android.util.ArraySet; import android.util.Log; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.statusbar.NotificationVisibility; +import com.android.systemui.statusbar.NotificationLifetimeExtender; import com.android.systemui.statusbar.notification.NotificationEntryListener; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; @@ -66,6 +72,9 @@ public class ForegroundServiceNotificationListener { removeNotification(entry.notification); } }); + + notificationEntryManager.addNotificationLifetimeExtender( + new ForegroundServiceNotificationListener.ForegroundServiceLifetimeExtender()); } /** @@ -144,4 +153,65 @@ public class ForegroundServiceNotificationListener { }, true /* create if not found */); } + + /** + * Extends the lifetime of foreground notification services such that they show for at least + * five seconds + */ + public static class ForegroundServiceLifetimeExtender implements NotificationLifetimeExtender { + + private static final String TAG = "FGSLifetimeExtender"; + @VisibleForTesting + static final int MIN_FGS_TIME_MS = 5000; + + private NotificationSafeToRemoveCallback mNotificationSafeToRemoveCallback; + private ArraySet<NotificationEntry> mManagedEntries = new ArraySet<>(); + private Handler mHandler = new Handler(Looper.getMainLooper()); + + public ForegroundServiceLifetimeExtender() { + } + + @Override + public void setCallback(@NonNull NotificationSafeToRemoveCallback callback) { + mNotificationSafeToRemoveCallback = callback; + } + + @Override + public boolean shouldExtendLifetime(@NonNull NotificationEntry entry) { + if ((entry.notification.getNotification().flags + & Notification.FLAG_FOREGROUND_SERVICE) == 0) { + return false; + } + + long currentTime = System.currentTimeMillis(); + return currentTime - entry.notification.getPostTime() < MIN_FGS_TIME_MS; + } + + @Override + public boolean shouldExtendLifetimeForPendingNotification( + @NonNull NotificationEntry entry) { + return shouldExtendLifetime(entry); + } + + @Override + public void setShouldManageLifetime( + @NonNull NotificationEntry entry, boolean shouldManage) { + if (!shouldManage) { + mManagedEntries.remove(entry); + return; + } + + mManagedEntries.add(entry); + + Runnable r = () -> { + if (mManagedEntries.contains(entry)) { + if (mNotificationSafeToRemoveCallback != null) { + mNotificationSafeToRemoveCallback.onSafeToRemove(entry.key); + } + mManagedEntries.remove(entry); + } + }; + mHandler.postDelayed(r, MIN_FGS_TIME_MS); + } + } } 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/ServiceBinder.java b/packages/SystemUI/src/com/android/systemui/ServiceBinder.java new file mode 100644 index 000000000000..6282c6e5282f --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/ServiceBinder.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; + +import com.android.systemui.doze.DozeService; + +import dagger.Binds; +import dagger.Module; +import dagger.multibindings.ClassKey; +import dagger.multibindings.IntoMap; + +/** + * Services and Activities that are injectable should go here. + */ +@Module +public abstract class ServiceBinder { + + @Binds + public abstract ContextComponentHelper bindComponentHelper( + ContextComponentResolver componentHelper); + + @Binds + @IntoMap + @ClassKey(DozeService.class) + public abstract Object bindDozeService(DozeService service); + +} diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java index 84e0238fdd3a..58c52a1fc50e 100644 --- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java +++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java @@ -34,7 +34,6 @@ import android.view.View; import android.view.ViewConfiguration; import android.view.accessibility.AccessibilityEvent; -import com.android.systemui.classifier.FalsingManagerFactory; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; import com.android.systemui.statusbar.FlingAnimationUtils; @@ -98,7 +97,8 @@ public class SwipeHelper implements Gefingerpoken { private final ArrayMap<View, Animator> mDismissPendingMap = new ArrayMap<>(); - public SwipeHelper(int swipeDirection, Callback callback, Context context) { + public SwipeHelper( + int swipeDirection, Callback callback, Context context, FalsingManager falsingManager) { mContext = context; mCallback = callback; mHandler = new Handler(); @@ -113,7 +113,7 @@ public class SwipeHelper implements Gefingerpoken { mDensityScale = res.getDisplayMetrics().density; mFalsingThreshold = res.getDimensionPixelSize(R.dimen.swipe_helper_falsing_threshold); mFadeDependingOnAmountSwiped = res.getBoolean(R.bool.config_fadeDependingOnAmountSwiped); - mFalsingManager = FalsingManagerFactory.getInstance(context); + mFalsingManager = falsingManager; mFlingAnimationUtils = new FlingAnimationUtils(context, getMaxEscapeAnimDuration() / 1000f); } diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactory.java new file mode 100644 index 000000000000..00ae99295768 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactory.java @@ -0,0 +1,76 @@ +/* + * 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 android.app.Application; +import android.app.Service; +import android.content.Intent; + +import androidx.core.app.CoreComponentFactory; + +import javax.inject.Inject; + +/** + * Implementation of AppComponentFactory that injects into constructors. + */ +public class SystemUIAppComponentFactory extends CoreComponentFactory { + + @Inject + public ContextComponentHelper mComponentHelper; + + public SystemUIAppComponentFactory() { + super(); + } + + @Override + public Application instantiateApplication(ClassLoader cl, String className) + throws InstantiationException, IllegalAccessException, ClassNotFoundException { + Application app = super.instantiateApplication(cl, className); + if (app instanceof SystemUIApplication) { + ((SystemUIApplication) app).setContextAvailableCallback( + context -> { + SystemUIFactory.createFromConfig(context); + SystemUIFactory.getInstance().getRootComponent().inject( + SystemUIAppComponentFactory.this); + } + ); + } + + return app; + } + + @Override + public Service instantiateService(ClassLoader cl, String className, Intent intent) + throws InstantiationException, IllegalAccessException, ClassNotFoundException { + Service service = mComponentHelper.resolve(className); + if (service != null) { + return checkCompatWrapper(service); + } + return super.instantiateService(cl, className, intent); + } + + static <T> T checkCompatWrapper(T obj) { + if (obj instanceof CompatWrapped) { + T wrapper = (T) ((CompatWrapped) obj).getWrapper(); + if (wrapper != null) { + return wrapper; + } + } + + return obj; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java index e89e6cb269f8..48127a75b86e 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java @@ -60,17 +60,30 @@ public class SystemUIApplication extends Application implements SysUiServiceProv private boolean mServicesStarted; private boolean mBootCompleted; 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); - SystemUIFactory.createFromConfig(this); - if (Process.myUserHandle().equals(UserHandle.SYSTEM)) { IntentFilter bootCompletedFilter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED); bootCompletedFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); @@ -134,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> */ @@ -155,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"); + } } } @@ -269,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) { @@ -286,4 +302,12 @@ public class SystemUIApplication extends Application implements SysUiServiceProv public SystemUI[] getServices() { return mServices; } + + void setContextAvailableCallback(ContextAvailableCallback callback) { + mContextAvailableCallback = callback; + } + + interface ContextAvailableCallback { + void onContextAvailable(Context context); + } } 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..262b5ec50d83 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/SystemUIDefaultModule.java @@ -0,0 +1,85 @@ +/* + * 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 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); + } + + @Singleton + @Provides + @Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME) + static boolean provideAllowNotificationLongPress() { + return true; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java index 0d85a3f77270..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,63 +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.classifier.FalsingManagerFactory; -import com.android.systemui.dock.DockManager; -import com.android.systemui.fragments.FragmentService; 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.util.InjectionInflationController; -import com.android.systemui.util.leak.GarbageMonitor; import com.android.systemui.volume.VolumeDialogComponent; import java.util.function.Consumer; -import javax.inject.Named; -import javax.inject.Singleton; - -import dagger.Component; 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; @@ -114,9 +86,16 @@ public class SystemUIFactory { public SystemUIFactory() {} - protected void init(Context context) { - mRootComponent = DaggerSystemUIFactory_SystemUIRootComponent.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(); @@ -132,12 +111,12 @@ public class SystemUIFactory { } public KeyguardBouncer createKeyguardBouncer(Context context, ViewMediatorCallback callback, - LockPatternUtils lockPatternUtils, ViewGroup container, + LockPatternUtils lockPatternUtils, ViewGroup container, DismissCallbackRegistry dismissCallbackRegistry, KeyguardBouncer.BouncerExpansionCallback expansionCallback, - KeyguardBypassController bypassController) { + FalsingManager falsingManager, KeyguardBypassController bypassController) { return new KeyguardBouncer(context, callback, lockPatternUtils, container, - dismissCallbackRegistry, FalsingManagerFactory.getInstance(context), + dismissCallbackRegistry, falsingManager, expansionCallback, UnlockMethodCache.getInstance(context), KeyguardUpdateMonitor.getInstance(context), bypassController, new Handler(Looper.getMainLooper())); @@ -171,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) { @@ -269,29 +163,4 @@ public class SystemUIFactory { return mContext; } } - - @Singleton - @Component(modules = {SystemUIFactory.class, DependencyProvider.class, DependencyBinder.class, - ContextHolder.class}) - public interface SystemUIRootComponent { - @Singleton - Dependency.DependencyInjector createDependency(); - - @Singleton - StatusBar.StatusBarInjector getStatusBarInjector(); - - /** - * FragmentCreator generates all Fragments that need injection. - */ - @Singleton - FragmentService.FragmentCreator createFragmentCreator(); - - /** - * ViewCreator generates all Views that need injection. - */ - InjectionInflationController.ViewCreator createViewCreator(); - - @Singleton - GarbageMonitor createGarbageMonitor(); - } } 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..edd2463984c8 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/SystemUIModule.java @@ -0,0 +1,50 @@ +/* + * 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 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.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); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIRootComponent.java b/packages/SystemUI/src/com/android/systemui/SystemUIRootComponent.java new file mode 100644 index 000000000000..f18c8b2c3da6 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/SystemUIRootComponent.java @@ -0,0 +1,82 @@ +/* + * 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 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; + +/** + * Root component for Dagger injection. + */ +@Singleton +@Component(modules = { + DependencyProvider.class, + DependencyBinder.class, + ServiceBinder.class, + SystemUIFactory.ContextHolder.class, + SystemUIModule.class, + SystemUIDefaultModule.class}) +public interface SystemUIRootComponent { + /** + * Main dependency providing module. + */ + @Singleton + Dependency.DependencyInjector createDependency(); + + /** + * Injects the StatusBar. + */ + @Singleton + StatusBar.StatusBarInjector getStatusBarInjector(); + + /** + * FragmentCreator generates all Fragments that need injection. + */ + @Singleton + FragmentService.FragmentCreator createFragmentCreator(); + + /** + * ViewCreator generates all Views that need injection. + */ + InjectionInflationController.ViewCreator createViewCreator(); + + /** + * Creatse a GarbageMonitor. + */ + @Singleton + 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..bdc666de4bc7 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; } @@ -365,11 +372,18 @@ final class AssistHandleReminderExpBehavior implements BehaviorController { long currentTimestamp = SystemClock.uptimeMillis(); mLearningTimeElapsed += currentTimestamp - mLastLearningTimestamp; mLastLearningTimestamp = currentTimestamp; - Settings.Secure.putLong( - mContext.getContentResolver(), LEARNING_TIME_ELAPSED_KEY, mLearningTimeElapsed); mIsLearned = mLearningCount >= getLearningCount() || mLearningTimeElapsed >= getLearningTimeMs(); + + mHandler.post(this::recordLearnTimeElapsed); + } + + private void recordLearnTimeElapsed() { + if (mContext != null) { + Settings.Secure.putLong( + mContext.getContentResolver(), LEARNING_TIME_ELAPSED_KEY, mLearningTimeElapsed); + } } private void resetConsecutiveTaskSwitches() { diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java index 4a4feada3c65..ffe3cc04a150 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java +++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java @@ -19,6 +19,7 @@ import android.os.AsyncTask; import android.os.Binder; import android.os.Bundle; import android.os.Handler; +import android.os.HandlerThread; import android.os.RemoteException; import android.os.SystemClock; import android.os.UserHandle; @@ -48,9 +49,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 +102,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 +154,7 @@ public class AssistManager implements ConfigurationChangedReceiver { } }; + @Inject public AssistManager(DeviceProvisionedController controller, Context context) { mContext = context; mDeviceProvisionedController = controller; @@ -154,8 +162,10 @@ public class AssistManager implements ConfigurationChangedReceiver { mAssistUtils = new AssistUtils(context); mAssistDisclosure = new AssistDisclosure(context, new Handler()); mPhoneStateMonitor = new PhoneStateMonitor(context); - mHandleController = - new AssistHandleBehaviorController(context, mAssistUtils, new Handler()); + final HandlerThread assistHandleThread = new HandlerThread("AssistHandleThread"); + assistHandleThread.start(); + mHandleController = new AssistHandleBehaviorController( + context, mAssistUtils, assistHandleThread.getThreadHandler()); registerVoiceInteractionSessionListener(); mInterestingConfigChanges = new InterestingConfigChanges(ActivityInfo.CONFIG_ORIENTATION @@ -204,6 +214,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 +290,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/assist/ui/InvocationLightsView.java b/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java index bc782a7d62eb..bb3bd781df66 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java +++ b/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java @@ -100,7 +100,9 @@ public class InvocationLightsView extends View int cornerRadiusBottom = DisplayUtils.getCornerRadiusBottom(context); int cornerRadiusTop = DisplayUtils.getCornerRadiusTop(context); - mViewHeight = Math.max(cornerRadiusBottom, cornerRadiusTop); + // ensure that height is non-zero even for square corners + mViewHeight = Math.max(Math.max(cornerRadiusBottom, cornerRadiusTop), + DisplayUtils.convertDpToPx(LIGHT_HEIGHT_DP, context)); final int dualToneDarkTheme = Utils.getThemeAttr(mContext, R.attr.darkIconTheme); final int dualToneLightTheme = Utils.getThemeAttr(mContext, R.attr.lightIconTheme); diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java index 923ca20b3925..de08a8c9c1b3 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java @@ -182,7 +182,7 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList mActivityView = new ActivityView(mContext, null /* attrs */, 0 /* defStyle */, true /* singleTaskInstance */); - + // Set ActivityView's alpha value as zero, since there is no view content to be shown. setContentVisibility(false); addView(mActivityView); diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFactory.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFactory.java deleted file mode 100644 index 01921f0d9a60..000000000000 --- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFactory.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2015 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.classifier; - -import android.content.Context; - -import com.android.systemui.Dependency; -import com.android.systemui.plugins.FalsingManager; - -/** - * When the phone is locked, listens to touch, sensor and phone events and sends them to - * DataCollector and HumanInteractionClassifier. - * - * It does not collect touch events when the bouncer shows up. - * - * TODO: FalsingManager supports dependency injection. Use it. - */ -public class FalsingManagerFactory { - private static FalsingManager sInstance = null; - - private FalsingManagerFactory() {} - - public static FalsingManager getInstance(Context context) { - if (sInstance == null) { - sInstance = Dependency.get(FalsingManager.class); - } - return sInstance; - } - -} diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java new file mode 100644 index 000000000000..ea175edf0be1 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java @@ -0,0 +1,246 @@ +/* + * 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.classifier; + +import android.net.Uri; +import android.view.MotionEvent; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.systemui.plugins.FalsingManager; + +import java.io.PrintWriter; + +/** + * Simple Fake for testing where {@link FalsingManager} is required. + */ +public class FalsingManagerFake implements FalsingManager { + private boolean mIsFalseTouch; + private boolean mIsUnlockingDisabled; + private boolean mIsClassiferEnabled; + private boolean mShouldEnforceBouncer; + private boolean mIsReportingEnabled; + + @Override + public void onSucccessfulUnlock() { + + } + + @Override + public void onNotificationActive() { + + } + + @Override + public void setShowingAod(boolean showingAod) { + + } + + @Override + public void onNotificatonStartDraggingDown() { + + } + + @VisibleForTesting + public void setIsUnlockingDisabled(boolean isUnlockingDisabled) { + mIsUnlockingDisabled = isUnlockingDisabled; + } + + @Override + public boolean isUnlockingDisabled() { + return mIsUnlockingDisabled; + } + + @VisibleForTesting + public void setIsFalseTouch(boolean isFalseTouch) { + mIsFalseTouch = isFalseTouch; + } + + @Override + public boolean isFalseTouch() { + return mIsFalseTouch; + } + + @Override + public void onNotificatonStopDraggingDown() { + + } + + @Override + public void setNotificationExpanded() { + + } + + @VisibleForTesting + public void setIsClassiferEnabled(boolean isClassiferEnabled) { + mIsClassiferEnabled = isClassiferEnabled; + } + + @Override + public boolean isClassiferEnabled() { + return mIsClassiferEnabled; + } + + @Override + public void onQsDown() { + + } + + @Override + public void setQsExpanded(boolean expanded) { + + } + + @VisibleForTesting + public void setShouldEnforceBouncer(boolean shouldEnforceBouncer) { + mShouldEnforceBouncer = shouldEnforceBouncer; + } + + @Override + public boolean shouldEnforceBouncer() { + return mShouldEnforceBouncer; + } + + @Override + public void onTrackingStarted(boolean secure) { + + } + + @Override + public void onTrackingStopped() { + + } + + @Override + public void onLeftAffordanceOn() { + + } + + @Override + public void onCameraOn() { + + } + + @Override + public void onAffordanceSwipingStarted(boolean rightCorner) { + + } + + @Override + public void onAffordanceSwipingAborted() { + + } + + @Override + public void onStartExpandingFromPulse() { + + } + + @Override + public void onExpansionFromPulseStopped() { + + } + + @Override + public Uri reportRejectedTouch() { + return null; + } + + @Override + public void onScreenOnFromTouch() { + + } + + + @VisibleForTesting + public void setIsReportingEnabled(boolean isReportingEnabled) { + mIsReportingEnabled = isReportingEnabled; + } + + @Override + public boolean isReportingEnabled() { + return mIsReportingEnabled; + } + + @Override + public void onUnlockHintStarted() { + + } + + @Override + public void onCameraHintStarted() { + + } + + @Override + public void onLeftAffordanceHintStarted() { + + } + + @Override + public void onScreenTurningOn() { + + } + + @Override + public void onScreenOff() { + + } + + @Override + public void onNotificatonStopDismissing() { + + } + + @Override + public void onNotificationDismissed() { + + } + + @Override + public void onNotificatonStartDismissing() { + + } + + @Override + public void onNotificationDoubleTap(boolean accepted, float dx, float dy) { + + } + + @Override + public void onBouncerShown() { + + } + + @Override + public void onBouncerHidden() { + + } + + @Override + public void onTouchEvent(MotionEvent ev, int width, int height) { + + } + + @Override + public void dump(PrintWriter pw) { + + } + + @Override + public void cleanup() { + } +} 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/doze/DozeAuthRemover.java b/packages/SystemUI/src/com/android/systemui/doze/DozeAuthRemover.java index e6a9e47be71c..e5a54b816ec6 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeAuthRemover.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeAuthRemover.java @@ -25,7 +25,7 @@ import com.android.keyguard.KeyguardUpdateMonitor; */ public class DozeAuthRemover implements DozeMachine.Part { - KeyguardUpdateMonitor mKeyguardUpdateMonitor; + private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; public DozeAuthRemover(Context context) { mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(context); diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java index d22d2c3fd47f..90cb05a8e6ee 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java @@ -28,8 +28,9 @@ import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.SystemUIApplication; -import com.android.systemui.classifier.FalsingManagerFactory; import com.android.systemui.dock.DockManager; +import com.android.systemui.keyguard.WakefulnessLifecycle; +import com.android.systemui.plugins.FalsingManager; import com.android.systemui.statusbar.phone.BiometricUnlockController; import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.util.AsyncSensorManager; @@ -42,11 +43,12 @@ public class DozeFactory { } /** Creates a DozeMachine with its parts for {@code dozeService}. */ - public DozeMachine assembleMachine(DozeService dozeService) { + public DozeMachine assembleMachine(DozeService dozeService, FalsingManager falsingManager) { Context context = dozeService; SensorManager sensorManager = Dependency.get(AsyncSensorManager.class); AlarmManager alarmManager = context.getSystemService(AlarmManager.class); DockManager dockManager = Dependency.get(DockManager.class); + WakefulnessLifecycle wakefulnessLifecycle = Dependency.get(WakefulnessLifecycle.class); DozeHost host = getHost(dozeService); AmbientDisplayConfiguration config = new AmbientDisplayConfiguration(context); @@ -61,10 +63,11 @@ public class DozeFactory { wrappedService = DozeSuspendScreenStatePreventingAdapter.wrapIfNeeded(wrappedService, params); - DozeMachine machine = new DozeMachine(wrappedService, config, wakeLock); + DozeMachine machine = new DozeMachine(wrappedService, config, wakeLock, + wakefulnessLifecycle); machine.setParts(new DozeMachine.Part[]{ new DozePauser(handler, machine, alarmManager, params.getPolicy()), - new DozeFalsingManagerAdapter(FalsingManagerFactory.getInstance(context)), + new DozeFalsingManagerAdapter(falsingManager), createDozeTriggers(context, sensorManager, host, alarmManager, config, params, handler, wakeLock, machine, dockManager), createDozeUi(context, host, wakeLock, machine, handler, alarmManager, params), diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java index 8bf2256a4f80..93a51cc20db2 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java @@ -24,6 +24,8 @@ import android.util.Log; import android.view.Display; import com.android.internal.util.Preconditions; +import com.android.systemui.keyguard.WakefulnessLifecycle; +import com.android.systemui.keyguard.WakefulnessLifecycle.Wakefulness; import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.util.Assert; import com.android.systemui.util.wakelock.WakeLock; @@ -118,6 +120,7 @@ public class DozeMachine { private final Service mDozeService; private final WakeLock mWakeLock; private final AmbientDisplayConfiguration mConfig; + private final WakefulnessLifecycle mWakefulnessLifecycle; private Part[] mParts; private final ArrayList<State> mQueuedRequests = new ArrayList<>(); @@ -126,9 +129,10 @@ public class DozeMachine { private boolean mWakeLockHeldForCurrentState = false; public DozeMachine(Service service, AmbientDisplayConfiguration config, - WakeLock wakeLock) { + WakeLock wakeLock, WakefulnessLifecycle wakefulnessLifecycle) { mDozeService = service; mConfig = config; + mWakefulnessLifecycle = wakefulnessLifecycle; mWakeLock = wakeLock; } @@ -334,9 +338,18 @@ public class DozeMachine { switch (state) { case INITIALIZED: case DOZE_PULSE_DONE: - transitionTo(mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT) - ? DozeMachine.State.DOZE_AOD : DozeMachine.State.DOZE, - DozeLog.PULSE_REASON_NONE); + final State nextState; + @Wakefulness int wakefulness = mWakefulnessLifecycle.getWakefulness(); + if (wakefulness == WakefulnessLifecycle.WAKEFULNESS_AWAKE + || wakefulness == WakefulnessLifecycle.WAKEFULNESS_WAKING) { + nextState = State.FINISH; + } else if (mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT)) { + nextState = State.DOZE_AOD; + } else { + nextState = State.DOZE; + } + + transitionTo(nextState, DozeLog.PULSE_REASON_NONE); break; default: break; diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java index 092eb46cad5e..026a62528c8d 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java @@ -107,8 +107,7 @@ public class DozeSensors { config.dozePickupSensorAvailable(), DozeLog.REASON_SENSOR_PICKUP, false /* touchCoords */, false /* touchscreen */, - false /* ignoresSetting */, - mDozeParameters.getPickupPerformsProxCheck()), + false /* ignoresSetting */), new TriggerSensor( findSensorWithType(config.doubleTapSensorType()), Settings.Secure.DOZE_DOUBLE_TAP_GESTURE, @@ -205,11 +204,8 @@ public class DozeSensors { public void updateListening() { boolean anyListening = false; for (TriggerSensor s : mSensors) { - // We don't want to be listening while we're PAUSED (prox sensor is covered) - // except when the sensor is already gated by prox. - boolean listen = mListening && (!mPaused || s.performsProxCheck()); - s.setListening(listen); - if (listen) { + s.setListening(mListening); + if (mListening) { anyListening = true; } } @@ -391,7 +387,6 @@ public class DozeSensors { private final boolean mReportsTouchCoordinates; private final boolean mSettingDefault; private final boolean mRequiresTouchscreen; - private final boolean mSensorPerformsProxCheck; protected boolean mRequested; protected boolean mRegistered; @@ -408,14 +403,12 @@ public class DozeSensors { boolean configured, int pulseReason, boolean reportsTouchCoordinates, boolean requiresTouchscreen) { this(sensor, setting, settingDef, configured, pulseReason, reportsTouchCoordinates, - requiresTouchscreen, false /* ignoresSetting */, - false /* sensorPerformsProxCheck */); + requiresTouchscreen, false /* ignoresSetting */); } private TriggerSensor(Sensor sensor, String setting, boolean settingDef, boolean configured, int pulseReason, boolean reportsTouchCoordinates, - boolean requiresTouchscreen, boolean ignoresSetting, - boolean sensorPerformsProxCheck) { + boolean requiresTouchscreen, boolean ignoresSetting) { mSensor = sensor; mSetting = setting; mSettingDefault = settingDef; @@ -424,7 +417,6 @@ public class DozeSensors { mReportsTouchCoordinates = reportsTouchCoordinates; mRequiresTouchscreen = requiresTouchscreen; mIgnoresSetting = ignoresSetting; - mSensorPerformsProxCheck = sensorPerformsProxCheck; } public void setListening(boolean listen) { @@ -498,23 +490,13 @@ public class DozeSensors { screenX = event.values[0]; screenY = event.values[1]; } - mCallback.onSensorPulse(mPulseReason, mSensorPerformsProxCheck, screenX, screenY, - event.values); + mCallback.onSensorPulse(mPulseReason, screenX, screenY, event.values); if (!mRegistered) { updateListening(); // reregister, this sensor only fires once } })); } - /** - * If the sensor itself performs proximity checks, to avoid pocket dialing. - * Gated sensors don't need to be stopped when the {@link DozeMachine} is - * {@link DozeMachine.State#DOZE_AOD_PAUSED}. - */ - public boolean performsProxCheck() { - return mSensorPerformsProxCheck; - } - public void registerSettingsObserver(ContentObserver settingsObserver) { if (mConfigured && !TextUtils.isEmpty(mSetting)) { mResolver.registerContentObserver( @@ -610,8 +592,7 @@ public class DozeSensors { return; } if (DEBUG) Log.d(TAG, "onSensorEvent: " + triggerEventToString(event)); - mCallback.onSensorPulse(mPulseReason, true /* sensorPerformsProxCheck */, -1, -1, - event.getValues()); + mCallback.onSensorPulse(mPulseReason, -1, -1, event.getValues()); })); } } @@ -621,13 +602,11 @@ public class DozeSensors { /** * Called when a sensor requests a pulse * @param pulseReason Requesting sensor, e.g. {@link DozeLog#REASON_SENSOR_PICKUP} - * @param sensorPerformedProxCheck true if the sensor already checked for FAR proximity. * @param screenX the location on the screen where the sensor fired or -1 - * if the sensor doesn't support reporting screen locations. + * if the sensor doesn't support reporting screen locations. * @param screenY the location on the screen where the sensor fired or -1 * @param rawValues raw values array from the event. */ - void onSensorPulse(int pulseReason, boolean sensorPerformedProxCheck, - float screenX, float screenY, float[] rawValues); + void onSensorPulse(int pulseReason, float screenX, float screenY, float[] rawValues); } } diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java index 2db73065fe19..9e1514c31ab1 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java @@ -25,12 +25,15 @@ import android.util.Log; import com.android.systemui.Dependency; import com.android.systemui.plugins.DozeServicePlugin; import com.android.systemui.plugins.DozeServicePlugin.RequestDoze; +import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.PluginListener; import com.android.systemui.shared.plugins.PluginManager; import java.io.FileDescriptor; import java.io.PrintWriter; +import javax.inject.Inject; + public class DozeService extends DreamService implements DozeMachine.Service, RequestDoze, PluginListener<DozeServicePlugin> { private static final String TAG = "DozeService"; @@ -40,6 +43,7 @@ public class DozeService extends DreamService private DozeServicePlugin mDozePlugin; private PluginManager mPluginManager; + @Inject public DozeService() { setDebug(DEBUG); } @@ -56,7 +60,8 @@ public class DozeService extends DreamService } mPluginManager = Dependency.get(PluginManager.class); mPluginManager.addPluginListener(this, DozeServicePlugin.class, false /* allowMultiple */); - mDozeMachine = new DozeFactory().assembleMachine(this); + mDozeMachine = new DozeFactory().assembleMachine( + this, Dependency.get(FalsingManager.class)); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java index 310f04abc36c..bab64db4519c 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java @@ -41,6 +41,7 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.util.Preconditions; import com.android.systemui.Dependency; +import com.android.systemui.R; import com.android.systemui.dock.DockManager; import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.util.Assert; @@ -156,8 +157,7 @@ public class DozeTriggers implements DozeMachine.Part { } @VisibleForTesting - void onSensor(int pulseReason, boolean sensorPerformedProxCheck, - float screenX, float screenY, float[] rawValues) { + void onSensor(int pulseReason, float screenX, float screenY, float[] rawValues) { boolean isDoubleTap = pulseReason == DozeLog.REASON_SENSOR_DOUBLE_TAP; boolean isTap = pulseReason == DozeLog.REASON_SENSOR_TAP; boolean isPickup = pulseReason == DozeLog.REASON_SENSOR_PICKUP; @@ -169,10 +169,11 @@ public class DozeTriggers implements DozeMachine.Part { if (isWakeDisplay) { onWakeScreen(wakeEvent, mMachine.isExecutingTransition() ? null : mMachine.getState()); } else if (isLongPress) { - requestPulse(pulseReason, sensorPerformedProxCheck, null /* onPulseSupressedListener */); + requestPulse(pulseReason, true /* alreadyPerformedProxCheck */, + null /* onPulseSupressedListener */); } else if (isWakeLockScreen) { if (wakeEvent) { - requestPulse(pulseReason, sensorPerformedProxCheck, + requestPulse(pulseReason, true /* alreadyPerformedProxCheck */, null /* onPulseSupressedListener */); } } else { @@ -191,8 +192,7 @@ public class DozeTriggers implements DozeMachine.Part { } else { mDozeHost.extendPulse(pulseReason); } - }, sensorPerformedProxCheck - || (mDockManager != null && mDockManager.isDocked()), pulseReason); + }, true /* alreadyPerformedProxCheck */, pulseReason); } if (isPickup) { @@ -278,7 +278,7 @@ public class DozeTriggers implements DozeMachine.Part { .setType(MetricsEvent.TYPE_OPEN) .setSubtype(DozeLog.REASON_SENSOR_WAKE_UP)); } - }, false /* alreadyPerformedProxCheck */, DozeLog.REASON_SENSOR_WAKE_UP); + }, true /* alreadyPerformedProxCheck */, DozeLog.REASON_SENSOR_WAKE_UP); } else { boolean paused = (state == DozeMachine.State.DOZE_AOD_PAUSED); boolean pausing = (state == DozeMachine.State.DOZE_AOD_PAUSING); @@ -417,6 +417,9 @@ public class DozeTriggers implements DozeMachine.Part { mDozeSensors.dump(pw); } + /** + * @see DozeSensors.ProxSensor + */ private abstract class ProximityCheck implements SensorEventListener, Runnable { private static final int TIMEOUT_DELAY_MS = 500; @@ -428,12 +431,18 @@ public class DozeTriggers implements DozeMachine.Part { private boolean mRegistered; private boolean mFinished; private float mMaxRange; + private boolean mUsingBrightnessSensor; protected abstract void onProximityResult(int result); public void check() { Preconditions.checkState(!mFinished && !mRegistered); - final Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); + Sensor sensor = DozeSensors.findSensorWithType(mSensorManager, + mContext.getString(R.string.doze_brightness_sensor_type)); + mUsingBrightnessSensor = sensor != null; + if (sensor == null) { + sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); + } if (sensor == null) { if (DozeMachine.DEBUG) Log.d(TAG, "ProxCheck: No sensor found"); finishWithResult(RESULT_UNKNOWN); @@ -449,6 +458,9 @@ public class DozeTriggers implements DozeMachine.Part { mRegistered = true; } + /** + * @see DozeSensors.ProxSensor#onSensorChanged(SensorEvent) + */ @Override public void onSensorChanged(SensorEvent event) { if (event.values.length == 0) { @@ -458,7 +470,14 @@ public class DozeTriggers implements DozeMachine.Part { if (DozeMachine.DEBUG) { Log.d(TAG, "ProxCheck: Event: value=" + event.values[0] + " max=" + mMaxRange); } - final boolean isNear = event.values[0] < mMaxRange; + final boolean isNear; + if (mUsingBrightnessSensor) { + // The custom brightness sensor is gated by the proximity sensor and will + // return 0 whenever prox is covered. + isNear = event.values[0] == 0; + } else { + isNear = event.values[0] < mMaxRange; + } finishWithResult(isNear ? RESULT_NEAR : RESULT_FAR); } } diff --git a/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java b/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java index 8dbaf0f681cf..b4cc571be061 100644 --- a/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java +++ b/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java @@ -22,7 +22,7 @@ import android.view.View; import com.android.systemui.ConfigurationChangedReceiver; import com.android.systemui.Dumpable; -import com.android.systemui.SystemUIFactory; +import com.android.systemui.SystemUIRootComponent; import com.android.systemui.qs.QSFragment; import com.android.systemui.statusbar.phone.NavigationBarFragment; @@ -51,7 +51,7 @@ public class FragmentService implements ConfigurationChangedReceiver, Dumpable { private final FragmentCreator mFragmentCreator; @Inject - public FragmentService(SystemUIFactory.SystemUIRootComponent rootComponent) { + public FragmentService(SystemUIRootComponent rootComponent) { mFragmentCreator = rootComponent.createFragmentCreator(); initInjectionMap(); } diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java index 0e4c15576957..ff02e71147fd 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java @@ -614,7 +614,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, mHandler.postDelayed(new Runnable() { @Override public void run() { - mScreenshotHelper.takeScreenshot(1, true, true, mHandler); + mScreenshotHelper.takeScreenshot(1, true, true, mHandler, null); MetricsLogger.action(mContext, MetricsEvent.ACTION_SCREENSHOT_POWER_MENU); } diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java index 7b22a49fc88a..29606347f009 100644 --- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java +++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java @@ -111,7 +111,12 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer, mBitmap = mWallpaperManager.getBitmap(); mWallpaperManager.forgetLoadedWallpaper(); if (mBitmap != null) { - mSurfaceSize.set(0, 0, mBitmap.getWidth(), mBitmap.getHeight()); + float scale = (float) mScissor.height() / mBitmap.getHeight(); + int surfaceHeight = Math.max(mScissor.height(), mBitmap.getHeight()); + int surfaceWidth = scale > 1f + ? Math.round(mBitmap.getWidth() * scale) + : mBitmap.getWidth(); + mSurfaceSize.set(0, 0, surfaceWidth, surfaceHeight); } } return mBitmap != null; diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index e9f99acd8d46..f424a8e5d71f 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -81,10 +81,11 @@ 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; -import com.android.systemui.classifier.FalsingManagerFactory; +import com.android.systemui.plugins.FalsingManager; import com.android.systemui.statusbar.phone.BiometricUnlockController; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.NotificationPanelView; @@ -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 */); @@ -1599,7 +1599,7 @@ public class KeyguardViewMediator extends SystemUI { Trace.beginSection("KeyguardViewMediator#handleMessage START_KEYGUARD_EXIT_ANIM"); StartKeyguardExitAnimParams params = (StartKeyguardExitAnimParams) msg.obj; handleStartKeyguardExitAnimation(params.startTime, params.fadeoutDuration); - FalsingManagerFactory.getInstance(mContext).onSucccessfulUnlock(); + Dependency.get(FalsingManager.class).onSucccessfulUnlock(); Trace.endSection(); break; case KEYGUARD_DONE_PENDING_TIMEOUT: @@ -2071,10 +2071,11 @@ public class KeyguardViewMediator extends SystemUI { public StatusBarKeyguardViewManager registerStatusBar(StatusBar statusBar, ViewGroup container, NotificationPanelView panelView, BiometricUnlockController biometricUnlockController, ViewGroup lockIconContainer, - View notificationContainer, KeyguardBypassController bypassController) { + View notificationContainer, KeyguardBypassController bypassController, + FalsingManager falsingManager) { mStatusBarKeyguardViewManager.registerStatusBar(statusBar, container, panelView, biometricUnlockController, mDismissCallbackRegistry, lockIconContainer, - notificationContainer, bypassController); + notificationContainer, bypassController, falsingManager); return mStatusBarKeyguardViewManager; } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java b/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java index 52a0214c492c..d17f2f621ec8 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java @@ -16,12 +16,15 @@ package com.android.systemui.keyguard; +import android.annotation.IntDef; import android.os.Trace; import com.android.systemui.Dumpable; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import javax.inject.Inject; import javax.inject.Singleton; @@ -33,6 +36,15 @@ import javax.inject.Singleton; public class WakefulnessLifecycle extends Lifecycle<WakefulnessLifecycle.Observer> implements Dumpable { + @IntDef(prefix = { "WAKEFULNESS_" }, value = { + WAKEFULNESS_ASLEEP, + WAKEFULNESS_WAKING, + WAKEFULNESS_AWAKE, + WAKEFULNESS_GOING_TO_SLEEP, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface Wakefulness {} + public static final int WAKEFULNESS_ASLEEP = 0; public static final int WAKEFULNESS_WAKING = 1; public static final int WAKEFULNESS_AWAKE = 2; @@ -44,7 +56,7 @@ public class WakefulnessLifecycle extends Lifecycle<WakefulnessLifecycle.Observe public WakefulnessLifecycle() { } - public int getWakefulness() { + public @Wakefulness int getWakefulness() { return mWakefulness; } @@ -86,7 +98,7 @@ public class WakefulnessLifecycle extends Lifecycle<WakefulnessLifecycle.Observe pw.println(" mWakefulness=" + mWakefulness); } - private void setWakefulness(int wakefulness) { + private void setWakefulness(@Wakefulness int wakefulness) { mWakefulness = wakefulness; Trace.traceCounter(Trace.TRACE_TAG_APP, "wakefulness", wakefulness); } 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/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java index 991d9fa549ac..0403a0505b00 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java +++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java @@ -248,7 +248,9 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout { int numPages = Math.max(nTiles / mPages.get(0).maxTiles(), 1); // Add one more not full page if needed - numPages += (nTiles % mPages.get(0).maxTiles() == 0 ? 0 : 1); + if (nTiles > numPages * mPages.get(0).maxTiles()) { + numPages++; + } final int NP = mPages.size(); for (int i = 0; i < NP; i++) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java index f0413cd6651b..be8a8fd26150 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java @@ -111,13 +111,25 @@ public class QSContainerImpl extends FrameLayout { + mQSPanel.getMeasuredHeight() + getPaddingBottom(); super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); - // QSCustomizer will always be the height of the screen, but do this after // other measuring to avoid changing the height of the QS. mQSCustomizer.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(getDisplayHeight(), MeasureSpec.EXACTLY)); } + + @Override + protected void measureChildWithMargins(View child, int parentWidthMeasureSpec, int widthUsed, + int parentHeightMeasureSpec, int heightUsed) { + // Do not measure QSPanel again when doing super.onMeasure. + // This prevents the pages in PagedTileLayout to be remeasured with a different (incorrect) + // size to the one used for determining the number of rows and then the number of pages. + if (child != mQSPanel) { + super.measureChildWithMargins(child, parentWidthMeasureSpec, widthUsed, + parentHeightMeasureSpec, heightUsed); + } + } + @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java index 83b000dca83b..38153ecd59c9 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java +++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java @@ -38,8 +38,8 @@ import androidx.recyclerview.widget.RecyclerView; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto; -import com.android.systemui.Dependency; import com.android.systemui.R; +import com.android.systemui.keyguard.ScreenLifecycle; import com.android.systemui.plugins.qs.QS; import com.android.systemui.plugins.qs.QSTile; import com.android.systemui.qs.QSDetailClipper; @@ -52,6 +52,8 @@ import com.android.systemui.statusbar.policy.KeyguardMonitor.Callback; import java.util.ArrayList; import java.util.List; +import javax.inject.Inject; + /** * Allows full-screen customization of QS, through show() and hide(). * @@ -66,6 +68,8 @@ public class QSCustomizer extends LinearLayout implements OnMenuItemClickListene private final QSDetailClipper mClipper; private final LightBarController mLightBarController; + private KeyguardMonitor mKeyguardMonitor; + private final ScreenLifecycle mScreenLifecycle; private final TileQueryHelper mTileQueryHelper; private final View mTransparentView; @@ -82,7 +86,11 @@ public class QSCustomizer extends LinearLayout implements OnMenuItemClickListene private boolean mOpening; private boolean mIsShowingNavBackdrop; - public QSCustomizer(Context context, AttributeSet attrs) { + @Inject + public QSCustomizer(Context context, AttributeSet attrs, + LightBarController lightBarController, + KeyguardMonitor keyguardMonitor, + ScreenLifecycle screenLifecycle) { super(new ContextThemeWrapper(context, R.style.edit_theme), attrs); LayoutInflater.from(getContext()).inflate(R.layout.qs_customize_panel_content, this); @@ -115,7 +123,9 @@ public class QSCustomizer extends LinearLayout implements OnMenuItemClickListene DefaultItemAnimator animator = new DefaultItemAnimator(); animator.setMoveDuration(TileAdapter.MOVE_DURATION); mRecyclerView.setItemAnimator(animator); - mLightBarController = Dependency.get(LightBarController.class); + mLightBarController = lightBarController; + mKeyguardMonitor = keyguardMonitor; + mScreenLifecycle = screenLifecycle; updateNavBackDrop(getResources().getConfiguration()); } @@ -177,7 +187,7 @@ public class QSCustomizer extends LinearLayout implements OnMenuItemClickListene queryTiles(); mNotifQsContainer.setCustomizerAnimating(true); mNotifQsContainer.setCustomizerShowing(true); - Dependency.get(KeyguardMonitor.class).addCallback(mKeyguardCallback); + mKeyguardMonitor.addCallback(mKeyguardCallback); updateNavColors(); } } @@ -193,7 +203,7 @@ public class QSCustomizer extends LinearLayout implements OnMenuItemClickListene queryTiles(); mNotifQsContainer.setCustomizerAnimating(false); mNotifQsContainer.setCustomizerShowing(true); - Dependency.get(KeyguardMonitor.class).addCallback(mKeyguardCallback); + mKeyguardMonitor.addCallback(mKeyguardCallback); updateNavColors(); } } @@ -203,16 +213,21 @@ public class QSCustomizer extends LinearLayout implements OnMenuItemClickListene } public void hide() { + final boolean animate = mScreenLifecycle.getScreenState() != ScreenLifecycle.SCREEN_OFF; if (isShown) { MetricsLogger.hidden(getContext(), MetricsProto.MetricsEvent.QS_EDIT); isShown = false; mToolbar.dismissPopupMenus(); setCustomizing(false); save(); - mClipper.animateCircularClip(mX, mY, false, mCollapseAnimationListener); - mNotifQsContainer.setCustomizerAnimating(true); + if (animate) { + mClipper.animateCircularClip(mX, mY, false, mCollapseAnimationListener); + } else { + setVisibility(View.GONE); + } + mNotifQsContainer.setCustomizerAnimating(animate); mNotifQsContainer.setCustomizerShowing(false); - Dependency.get(KeyguardMonitor.class).removeCallback(mKeyguardCallback); + mKeyguardMonitor.removeCallback(mKeyguardCallback); updateNavColors(); } } @@ -268,7 +283,7 @@ public class QSCustomizer extends LinearLayout implements OnMenuItemClickListene public void saveInstanceState(Bundle outState) { if (isShown) { - Dependency.get(KeyguardMonitor.class).removeCallback(mKeyguardCallback); + mKeyguardMonitor.removeCallback(mKeyguardCallback); } outState.putBoolean(EXTRA_QS_CUSTOMIZING, mCustomizing); } @@ -300,7 +315,7 @@ public class QSCustomizer extends LinearLayout implements OnMenuItemClickListene @Override public void onKeyguardShowingChanged() { if (!isAttachedToWindow()) return; - if (Dependency.get(KeyguardMonitor.class).isShowing() && !mOpening) { + if (mKeyguardMonitor.isShowing() && !mOpening) { hide(); } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java index b135f7b27c3f..effea6a877b8 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java +++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java @@ -159,8 +159,11 @@ public class TileLifecycleManager extends BroadcastReceiver implements mBindTryCount++; try { mIsBound = mContext.bindServiceAsUser(mIntent, this, - Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE - | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS, mUser); + Context.BIND_AUTO_CREATE + | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE + | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS + | Context.BIND_WAIVE_PRIORITY, + mUser); } catch (SecurityException e) { Log.e(TAG, "Failed to bind to service", e); mIsBound = false; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java index 20069ead5e8d..4de42cc2e6c7 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java @@ -40,8 +40,10 @@ import com.android.systemui.Prefs; import com.android.systemui.R; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.qs.DetailAdapter; +import com.android.systemui.plugins.qs.QSIconView; import com.android.systemui.plugins.qs.QSTile.SignalState; import com.android.systemui.qs.QSHost; +import com.android.systemui.qs.SignalTileView; import com.android.systemui.qs.tileimpl.QSTileImpl; import com.android.systemui.statusbar.phone.SystemUIDialog; import com.android.systemui.statusbar.policy.NetworkController; @@ -78,6 +80,11 @@ public class CellularTile extends QSTileImpl<SignalState> { } @Override + public QSIconView createTileView(Context context) { + return new SignalTileView(context); + } + + @Override public DetailAdapter getDetailAdapter() { return mDetailAdapter; } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java index 91d38bd075bf..187a3bdec13f 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java @@ -76,8 +76,11 @@ public class UserDetailView extends PseudoGridView { UserSwitcherController.UserRecord item) { UserDetailItemView v = UserDetailItemView.convertOrInflate( mContext, convertView, parent); - if (v != convertView) { + if (!item.isCurrent || item.isGuest) { v.setOnClickListener(this); + } else { + v.setOnClickListener(null); + v.setClickable(false); } String name = getName(mContext, item); if (item.picture == null) { diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java index a9896f51369c..0383dee4f9c3 100644 --- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java +++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java @@ -22,34 +22,34 @@ import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; +import android.content.ContentResolver; +import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; +import android.graphics.Point; import android.graphics.drawable.Icon; import android.hardware.display.DisplayManager; import android.hardware.display.VirtualDisplay; import android.media.MediaRecorder; -import android.media.ThumbnailUtils; import android.media.projection.MediaProjection; import android.media.projection.MediaProjectionManager; import android.net.Uri; -import android.os.Environment; import android.os.IBinder; import android.provider.MediaStore; import android.provider.Settings; import android.util.DisplayMetrics; import android.util.Log; +import android.util.Size; import android.view.Surface; import android.widget.Toast; -import androidx.core.content.FileProvider; - import com.android.systemui.R; import java.io.File; import java.io.IOException; +import java.io.OutputStream; import java.nio.file.Files; -import java.nio.file.Path; import java.text.SimpleDateFormat; import java.util.Date; @@ -76,12 +76,10 @@ public class RecordingService extends Service { private static final String ACTION_DELETE = "com.android.systemui.screenrecord.DELETE"; private static final int TOTAL_NUM_TRACKS = 1; - private static final String RECORD_DIR = "Captures"; // TODO: use a translatable string private static final int VIDEO_BIT_RATE = 6000000; private static final int VIDEO_FRAME_RATE = 30; private static final int AUDIO_BIT_RATE = 16; private static final int AUDIO_SAMPLE_RATE = 44100; - private static final String FILE_PROVIDER = "com.android.systemui.fileprovider"; private MediaProjectionManager mMediaProjectionManager; private MediaProjection mMediaProjection; @@ -117,11 +115,11 @@ public class RecordingService extends Service { @Override public int onStartCommand(Intent intent, int flags, int startId) { - Log.d(TAG, "RecordingService is starting"); if (intent == null) { return Service.START_NOT_STICKY; } String action = intent.getAction(); + Log.d(TAG, "onStartCommand " + action); NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); @@ -157,26 +155,7 @@ public class RecordingService extends Service { case ACTION_STOP: stopRecording(); - - // Move temp file to user directory - File recordDir = new File( - Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES), - RECORD_DIR); - recordDir.mkdirs(); - - String fileName = new SimpleDateFormat("'screen-'yyyyMMdd-HHmmss'.mp4'") - .format(new Date()); - Path path = new File(recordDir, fileName).toPath(); - - try { - Files.move(mTempFile.toPath(), path); - Notification notification = createSaveNotification(path); - notificationManager.notify(NOTIFICATION_ID, notification); - } catch (IOException e) { - e.printStackTrace(); - Toast.makeText(this, R.string.screenrecord_delete_error, Toast.LENGTH_LONG) - .show(); - } + saveRecording(notificationManager); break; case ACTION_PAUSE: @@ -190,8 +169,7 @@ public class RecordingService extends Service { break; case ACTION_SHARE: - File shareFile = new File(intent.getStringExtra(EXTRA_PATH)); - Uri shareUri = FileProvider.getUriForFile(this, FILE_PROVIDER, shareFile); + Uri shareUri = Uri.parse(intent.getStringExtra(EXTRA_PATH)); Intent shareIntent = new Intent(Intent.ACTION_SEND) .setType("video/mp4") @@ -211,20 +189,18 @@ public class RecordingService extends Service { // Close quick shade sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)); - File file = new File(intent.getStringExtra(EXTRA_PATH)); - if (file.delete()) { - Toast.makeText( - this, - R.string.screenrecord_delete_description, - Toast.LENGTH_LONG).show(); + ContentResolver resolver = getContentResolver(); + Uri uri = Uri.parse(intent.getStringExtra(EXTRA_PATH)); + resolver.delete(uri, null, null); - // Remove notification - notificationManager.cancel(NOTIFICATION_ID); - } else { - Log.e(TAG, "Error deleting screen recording!"); - Toast.makeText(this, R.string.screenrecord_delete_error, Toast.LENGTH_LONG) - .show(); - } + Toast.makeText( + this, + R.string.screenrecord_delete_description, + Toast.LENGTH_LONG).show(); + + // Remove notification + notificationManager.cancel(NOTIFICATION_ID); + Log.d(TAG, "Deleted recording " + uri); break; } return Service.START_STICKY; @@ -295,6 +271,7 @@ public class RecordingService extends Service { mMediaRecorder.start(); } catch (IOException e) { + Log.e(TAG, "Error starting screen recording: " + e.getMessage()); e.printStackTrace(); throw new RuntimeException(e); } @@ -352,13 +329,10 @@ public class RecordingService extends Service { notificationManager.notify(NOTIFICATION_ID, mRecordingNotificationBuilder.build()); } - private Notification createSaveNotification(Path path) { - Uri saveUri = FileProvider.getUriForFile(this, FILE_PROVIDER, path.toFile()); - Log.d(TAG, "Screen recording saved to " + path.toString()); - + private Notification createSaveNotification(Uri uri) { Intent viewIntent = new Intent(Intent.ACTION_VIEW) .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION) - .setDataAndType(saveUri, "video/mp4"); + .setDataAndType(uri, "video/mp4"); Notification.Action shareAction = new Notification.Action.Builder( Icon.createWithResource(this, R.drawable.ic_android), @@ -366,7 +340,7 @@ public class RecordingService extends Service { PendingIntent.getService( this, REQUEST_CODE, - getShareIntent(this, path.toString()), + getShareIntent(this, uri.toString()), PendingIntent.FLAG_UPDATE_CURRENT)) .build(); @@ -376,7 +350,7 @@ public class RecordingService extends Service { PendingIntent.getService( this, REQUEST_CODE, - getDeleteIntent(this, path.toString()), + getDeleteIntent(this, uri.toString()), PendingIntent.FLAG_UPDATE_CURRENT)) .build(); @@ -394,8 +368,15 @@ public class RecordingService extends Service { .setAutoCancel(true); // Add thumbnail if available - Bitmap thumbnailBitmap = ThumbnailUtils.createVideoThumbnail(path.toString(), - MediaStore.Video.Thumbnails.MINI_KIND); + Bitmap thumbnailBitmap = null; + try { + ContentResolver resolver = getContentResolver(); + Size size = Point.convert(MediaStore.ThumbnailConstants.MINI_SIZE); + thumbnailBitmap = resolver.loadThumbnail(uri, size, null); + } catch (IOException e) { + Log.e(TAG, "Error creating thumbnail: " + e.getMessage()); + e.printStackTrace(); + } if (thumbnailBitmap != null) { Notification.BigPictureStyle pictureStyle = new Notification.BigPictureStyle() .bigPicture(thumbnailBitmap) @@ -417,6 +398,38 @@ public class RecordingService extends Service { stopSelf(); } + private void saveRecording(NotificationManager notificationManager) { + String fileName = new SimpleDateFormat("'screen-'yyyyMMdd-HHmmss'.mp4'") + .format(new Date()); + + ContentValues values = new ContentValues(); + values.put(MediaStore.Video.Media.DISPLAY_NAME, fileName); + values.put(MediaStore.Video.Media.MIME_TYPE, "video/mp4"); + values.put(MediaStore.Video.Media.DATE_ADDED, System.currentTimeMillis()); + values.put(MediaStore.Video.Media.DATE_TAKEN, System.currentTimeMillis()); + + ContentResolver resolver = getContentResolver(); + Uri collectionUri = MediaStore.Video.Media.getContentUri( + MediaStore.VOLUME_EXTERNAL_PRIMARY); + Uri itemUri = resolver.insert(collectionUri, values); + + try { + // Add to the mediastore + OutputStream os = resolver.openOutputStream(itemUri, "w"); + Files.copy(mTempFile.toPath(), os); + os.close(); + + Notification notification = createSaveNotification(itemUri); + notificationManager.notify(NOTIFICATION_ID, notification); + + mTempFile.delete(); + } catch (IOException e) { + Log.e(TAG, "Error saving screen recording: " + e.getMessage()); + Toast.makeText(this, R.string.screenrecord_delete_error, Toast.LENGTH_LONG) + .show(); + } + } + private void setTapsVisible(boolean turnOn) { int value = turnOn ? 1 : 0; Settings.System.putInt(getApplicationContext().getContentResolver(), diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java index 8385c8e00392..5adee40613e6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java @@ -29,7 +29,6 @@ import com.android.systemui.ExpandHelper; import com.android.systemui.Gefingerpoken; import com.android.systemui.Interpolators; import com.android.systemui.R; -import com.android.systemui.classifier.FalsingManagerFactory; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.statusbar.notification.row.ExpandableView; @@ -59,14 +58,15 @@ public class DragDownHelper implements Gefingerpoken { private FalsingManager mFalsingManager; public DragDownHelper(Context context, View host, ExpandHelper.Callback callback, - DragDownCallback dragDownCallback) { + DragDownCallback dragDownCallback, + FalsingManager falsingManager) { mMinDragDistance = context.getResources().getDimensionPixelSize( R.dimen.keyguard_drag_down_min_distance); mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); mCallback = callback; mDragDownCallback = dragDownCallback; mHost = host; - mFalsingManager = FalsingManagerFactory.getInstance(context); + mFalsingManager = falsingManager; } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java index 4be93df0e81a..6f87b2939cfb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java @@ -562,11 +562,11 @@ public class KeyguardIndicationController implements StateListener, return; } - String message = mContext.getString(R.string.keyguard_unlock); if (mStatusBarKeyguardViewManager.isBouncerShowing()) { + String message = mContext.getString(R.string.keyguard_retry); mStatusBarKeyguardViewManager.showBouncerMessage(message, mInitialTextColorState); } else if (mKeyguardUpdateMonitor.isScreenOn()) { - showTransientIndication(message); + showTransientIndication(mContext.getString(R.string.keyguard_unlock)); hideTransientIndicationDelayed(BaseKeyguardCallback.HIDE_DELAY_MS); } } @@ -650,7 +650,6 @@ public class KeyguardIndicationController implements StateListener, if (!updateMonitor.isUnlockingWithBiometricAllowed()) { return; } - animatePadlockError(); boolean showSwipeToUnlock = msgId == KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED; if (mStatusBarKeyguardViewManager.isBouncerShowing()) { @@ -676,7 +675,11 @@ public class KeyguardIndicationController implements StateListener, return; } animatePadlockError(); - if (mStatusBarKeyguardViewManager.isBouncerShowing()) { + if (msgId == FaceManager.FACE_ERROR_TIMEOUT) { + // The face timeout message is not very actionable, let's ask the user to + // manually retry. + showSwipeUpToUnlock(); + } else if (mStatusBarKeyguardViewManager.isBouncerShowing()) { mStatusBarKeyguardViewManager.showBouncerMessage(errString, mInitialTextColorState); } else if (updateMonitor.isScreenOn()) { showTransientIndication(errString); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLifetimeExtender.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLifetimeExtender.java index 0f295ba75fe4..48e2923c97d9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLifetimeExtender.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLifetimeExtender.java @@ -27,6 +27,18 @@ public interface NotificationLifetimeExtender { boolean shouldExtendLifetime(@NonNull NotificationEntry entry); /** + * It's possible that a notification was canceled before it ever became visible. This callback + * gives lifetime extenders a chance to make sure it shows up. For example if a foreground + * service is canceled too quickly but we still want to make sure a FGS notification shows. + * @param pendingEntry the canceled (but pending) entry + * @return true if the notification lifetime should be extended + */ + default boolean shouldExtendLifetimeForPendingNotification( + @NonNull NotificationEntry pendingEntry) { + return false; + } + + /** * Sets whether or not the lifetime should be managed by the extender. In practice, if * shouldManage is true, this is where the extender starts managing the entry internally and is * now responsible for calling {@link NotificationSafeToRemoveCallback#onSafeToRemove(String)} 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/PulseExpansionHandler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt index 986486ac14d4..276afa7a3a94 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt @@ -27,11 +27,11 @@ import android.os.SystemClock import android.view.MotionEvent import android.view.VelocityTracker import android.view.ViewConfiguration +import com.android.systemui.Dependency import com.android.systemui.Gefingerpoken import com.android.systemui.Interpolators import com.android.systemui.R -import com.android.systemui.classifier.FalsingManagerFactory import com.android.systemui.plugins.FalsingManager import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow @@ -41,7 +41,6 @@ import com.android.systemui.statusbar.notification.stack.NotificationStackScroll import com.android.systemui.statusbar.phone.HeadsUpManagerPhone import com.android.systemui.statusbar.phone.KeyguardBypassController import com.android.systemui.statusbar.phone.ShadeController -import com.android.systemui.statusbar.policy.HeadsUpManager import javax.inject.Inject import javax.inject.Singleton @@ -52,11 +51,13 @@ import kotlin.math.max */ @Singleton class PulseExpansionHandler @Inject -constructor(context: Context, - private val wakeUpCoordinator: NotificationWakeUpCoordinator, - private val bypassController: KeyguardBypassController, - private val headsUpManager: HeadsUpManagerPhone, - private val roundnessManager: NotificationRoundnessManager) : Gefingerpoken { +constructor( + context: Context, + private val wakeUpCoordinator: NotificationWakeUpCoordinator, + private val bypassController: KeyguardBypassController, + private val headsUpManager: HeadsUpManagerPhone, + private val roundnessManager: NotificationRoundnessManager +) : Gefingerpoken { companion object { private val RUBBERBAND_FACTOR_STATIC = 0.25f private val SPRING_BACK_ANIMATION_LENGTH_MS = 375 @@ -115,7 +116,7 @@ constructor(context: Context, mMinDragDistance = context.resources.getDimensionPixelSize( R.dimen.keyguard_drag_down_min_distance) mTouchSlop = ViewConfiguration.get(context).scaledTouchSlop.toFloat() - mFalsingManager = FalsingManagerFactory.getInstance(context) + mFalsingManager = Dependency.get(FalsingManager::class.java) mPowerManager = context.getSystemService(PowerManager::class.java) } @@ -124,8 +125,8 @@ constructor(context: Context, } private fun maybeStartExpansion(event: MotionEvent): Boolean { - if (!wakeUpCoordinator.canShowPulsingHuns || qsExpanded - || bouncerShowing) { + if (!wakeUpCoordinator.canShowPulsingHuns || qsExpanded || + bouncerShowing) { return false } if (velocityTracker == null) { @@ -160,18 +161,18 @@ constructor(context: Context, } MotionEvent.ACTION_UP -> { - recycleVelocityTracker(); + recycleVelocityTracker() } MotionEvent.ACTION_CANCEL -> { - recycleVelocityTracker(); + recycleVelocityTracker() } } return false } private fun recycleVelocityTracker() { - velocityTracker?.recycle(); + velocityTracker?.recycle() velocityTracker = null } @@ -216,7 +217,7 @@ constructor(context: Context, "com.android.systemui:PULSEDRAG") } shadeController.goToLockedShade(mStartingChild) - leavingLockscreen = true; + leavingLockscreen = true isExpanding = false if (mStartingChild is ExpandableNotificationRow) { val row = mStartingChild as ExpandableNotificationRow? @@ -227,7 +228,7 @@ constructor(context: Context, private fun updateExpansionHeight(height: Float) { var expansionHeight = max(height, 0.0f) if (!mReachedWakeUpHeight && height > mWakeUpHeight) { - mReachedWakeUpHeight = true; + mReachedWakeUpHeight = true } if (mStartingChild != null) { val child = mStartingChild!! @@ -317,9 +318,11 @@ constructor(context: Context, } else null } - fun setUp(stackScroller: NotificationStackScrollLayout, - expansionCallback: ExpansionCallback, - shadeController: ShadeController) { + fun setUp( + stackScroller: NotificationStackScrollLayout, + expansionCallback: ExpansionCallback, + shadeController: ShadeController + ) { this.expansionCallback = expansionCallback this.shadeController = shadeController this.stackScroller = stackScroller 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..a37367e4bb25 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(); } @@ -276,10 +281,24 @@ public class NotificationEntryManager implements } final NotificationEntry entry = mNotificationData.get(key); + boolean lifetimeExtended = false; - abortExistingInflation(key); + // Notification was canceled before it got inflated + if (entry == null) { + NotificationEntry pendingEntry = mPendingNotifications.get(key); + if (pendingEntry != null) { + for (NotificationLifetimeExtender extender : mNotificationLifetimeExtenders) { + if (extender.shouldExtendLifetimeForPendingNotification(pendingEntry)) { + extendLifetime(pendingEntry, extender); + lifetimeExtended = true; + } + } + } + } - boolean lifetimeExtended = false; + if (!lifetimeExtended) { + abortExistingInflation(key); + } if (entry != null) { // If a manager needs to keep the notification around for whatever reason, we 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/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java index dca152fbe37a..8d7325118139 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java @@ -33,9 +33,9 @@ import android.view.accessibility.AccessibilityManager; import android.view.animation.Interpolator; import android.view.animation.PathInterpolator; +import com.android.systemui.Dependency; import com.android.systemui.Interpolators; import com.android.systemui.R; -import com.android.systemui.classifier.FalsingManagerFactory; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.statusbar.NotificationShelf; import com.android.systemui.statusbar.notification.FakeShadowView; @@ -130,7 +130,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView private boolean mLastInSection; private boolean mFirstInSection; private boolean mIsBelowSpeedBump; - private FalsingManager mFalsingManager; + private final FalsingManager mFalsingManager; private float mNormalBackgroundVisibilityAmount; private float mDimmedBackgroundFadeInAmount = -1; @@ -164,10 +164,10 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView super(context, attrs); mSlowOutFastInInterpolator = new PathInterpolator(0.8f, 0.0f, 0.6f, 1.0f); mSlowOutLinearInInterpolator = new PathInterpolator(0.8f, 0.0f, 1.0f, 1.0f); + mFalsingManager = Dependency.get(FalsingManager.class); // TODO: inject into a controller. setClipChildren(false); setClipToPadding(false); updateColors(); - mFalsingManager = FalsingManagerFactory.getInstance(context); mAccessibilityManager = AccessibilityManager.getInstance(mContext); mDoubleTapHelper = new DoubleTapHelper(this, (active) -> { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java index ea31be4cf90c..65e744b9e047 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java @@ -74,7 +74,6 @@ import com.android.internal.widget.CachingIconView; import com.android.systemui.Dependency; import com.android.systemui.Interpolators; import com.android.systemui.R; -import com.android.systemui.classifier.FalsingManagerFactory; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.PluginListener; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; @@ -1209,12 +1208,12 @@ public class ExpandableNotificationRow extends ActivatableNotificationView mChildrenContainer.reInflateViews(mExpandClickListener, mEntry.notification); } if (mGuts != null) { - View oldGuts = mGuts; + NotificationGuts oldGuts = mGuts; int index = indexOfChild(oldGuts); removeView(oldGuts); mGuts = (NotificationGuts) LayoutInflater.from(mContext).inflate( R.layout.notification_guts, this, false); - mGuts.setVisibility(oldGuts.getVisibility()); + mGuts.setVisibility(oldGuts.isExposed() ? VISIBLE : GONE); addView(mGuts, index); } View oldMenu = mMenuRow == null ? null : mMenuRow.getMenuView(); @@ -1637,7 +1636,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView public ExpandableNotificationRow(Context context, AttributeSet attrs) { super(context, attrs); - mFalsingManager = FalsingManagerFactory.getInstance(context); + mFalsingManager = Dependency.get(FalsingManager.class); // TODO: inject into a controller. mNotificationInflater = new NotificationContentInflater(this); mMenuRow = new NotificationMenuRow(mContext); mImageResolver = new NotificationInlineImageResolver(context, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index f50790f3013b..688e8eb8f2e3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -86,7 +86,6 @@ import com.android.systemui.ExpandHelper; import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.SwipeHelper; -import com.android.systemui.classifier.FalsingManagerFactory; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.FalsingManager; @@ -516,7 +515,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd ActivityStarter activityStarter, StatusBarStateController statusBarStateController, HeadsUpManagerPhone headsUpManager, - KeyguardBypassController keyguardBypassController) { + KeyguardBypassController keyguardBypassController, + FalsingManager falsingManager) { super(context, attrs, 0, 0); Resources res = getResources(); @@ -531,6 +531,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd mHeadsUpManager.addListener(mRoundnessManager); mHeadsUpManager.setAnimationStateHandler(this::setHeadsUpGoingAwayAnimationsAllowed); mKeyguardBypassController = keyguardBypassController; + mFalsingManager = falsingManager; mSectionsManager = new NotificationSectionsManager( @@ -555,10 +556,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd mExpandHelper.setEventSource(this); mExpandHelper.setScrollAdapter(this); mSwipeHelper = new NotificationSwipeHelper(SwipeHelper.X, mNotificationCallback, - getContext(), mMenuEventListener); + getContext(), mMenuEventListener, mFalsingManager); mStackScrollAlgorithm = createStackScrollAlgorithm(context); initView(context); - mFalsingManager = FalsingManagerFactory.getInstance(context); mShouldDrawNotificationBackground = res.getBoolean(R.bool.config_drawNotificationBackground); mFadeNotificationsOnDismiss = diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java index 4dfc343df283..0968674d31cc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java @@ -28,6 +28,7 @@ import android.view.View; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.SwipeHelper; +import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; @@ -50,9 +51,11 @@ class NotificationSwipeHelper extends SwipeHelper private boolean mIsExpanded; private boolean mPulsing; - public NotificationSwipeHelper(int swipeDirection, NotificationCallback callback, - Context context, NotificationMenuRowPlugin.OnMenuEventListener menuListener) { - super(swipeDirection, callback, context); + NotificationSwipeHelper( + int swipeDirection, NotificationCallback callback, Context context, + NotificationMenuRowPlugin.OnMenuEventListener menuListener, + FalsingManager falsingManager) { + super(swipeDirection, callback, context, falsingManager); mMenuListener = menuListener; mCallback = callback; mFalsingCheck = new Runnable() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java index 10b48e71005d..bb6a38e1dcf5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java @@ -207,10 +207,6 @@ public class DozeParameters implements TunerService.Tunable, return SystemProperties.get(propName, mContext.getString(resId)); } - public boolean getPickupPerformsProxCheck() { - return mContext.getResources().getBoolean(R.bool.doze_pickup_performs_proximity_check); - } - public int getPulseVisibleDurationExtended() { return 2 * getPulseVisibleDuration(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java index 4691a31fad21..66b1dd8db123 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java @@ -27,7 +27,6 @@ import android.view.ViewConfiguration; import com.android.systemui.Interpolators; import com.android.systemui.R; -import com.android.systemui.classifier.FalsingManagerFactory; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.statusbar.FlingAnimationUtils; import com.android.systemui.statusbar.KeyguardAffordanceView; @@ -59,7 +58,7 @@ public class KeyguardAffordanceHelper { private KeyguardAffordanceView mLeftIcon; private KeyguardAffordanceView mRightIcon; private Animator mSwipeAnimator; - private FalsingManager mFalsingManager; + private final FalsingManager mFalsingManager; private int mMinBackgroundRadius; private boolean mMotionCancelled; private int mTouchTargetSize; @@ -80,12 +79,13 @@ public class KeyguardAffordanceHelper { } }; - KeyguardAffordanceHelper(Callback callback, Context context) { + KeyguardAffordanceHelper(Callback callback, Context context, FalsingManager falsingManager) { mContext = context; mCallback = callback; initIcons(); updateIcon(mLeftIcon, 0.0f, mLeftIcon.getRestingAlpha(), false, false, true, false); updateIcon(mRightIcon, 0.0f, mRightIcon.getRestingAlpha(), false, false, true, false); + mFalsingManager = falsingManager; initDimens(); } @@ -102,7 +102,6 @@ public class KeyguardAffordanceHelper { mHintGrowAmount = mContext.getResources().getDimensionPixelSize(R.dimen.hint_grow_amount_sideways); mFlingAnimationUtils = new FlingAnimationUtils(mContext, 0.4f); - mFalsingManager = FalsingManagerFactory.getInstance(mContext); } private void initIcons() { 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 dc9b373de688..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; 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/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java index f689a3eadf58..a2740c8dc322 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.phone; import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON; +import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_HOME_DISABLED; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED; @@ -920,7 +921,8 @@ public class NavigationBarView extends FrameLayout implements } public void showPinningEscapeToast() { - mScreenPinningNotify.showEscapeToast(isRecentsButtonVisible()); + mScreenPinningNotify.showEscapeToast( + mNavBarMode == NAV_BAR_MODE_GESTURAL, isRecentsButtonVisible()); } public boolean isVertical() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java index a0847b62eddb..83c556630538 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -39,6 +39,7 @@ import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.Region; +import android.hardware.biometrics.BiometricSourceType; import android.os.PowerManager; import android.os.SystemClock; import android.util.AttributeSet; @@ -59,11 +60,11 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.keyguard.KeyguardClockSwitch; import com.android.keyguard.KeyguardStatusView; import com.android.keyguard.KeyguardUpdateMonitor; +import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.systemui.DejankUtils; import com.android.systemui.Dependency; import com.android.systemui.Interpolators; import com.android.systemui.R; -import com.android.systemui.classifier.FalsingManagerFactory; import com.android.systemui.fragments.FragmentHostManager; import com.android.systemui.fragments.FragmentHostManager.FragmentListener; import com.android.systemui.plugins.FalsingManager; @@ -165,6 +166,25 @@ public class NotificationPanelView extends PanelView implements R.id.keyguard_hun_animator_start_tag); private static final AnimationProperties KEYGUARD_HUN_PROPERTIES = new AnimationProperties().setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD); + @VisibleForTesting + final KeyguardUpdateMonitorCallback mKeyguardUpdateCallback = + new KeyguardUpdateMonitorCallback() { + @Override + public void onBiometricRunningStateChanged(boolean running, + BiometricSourceType biometricSourceType) { + boolean keyguardOrShadeLocked = mBarState == StatusBarState.KEYGUARD + || mBarState == StatusBarState.SHADE_LOCKED; + if (!running && mFirstBypassAttempt && keyguardOrShadeLocked && !mDozing) { + mFirstBypassAttempt = false; + animateKeyguardStatusBarIn(StackStateAnimator.ANIMATION_DURATION_STANDARD); + } + } + + @Override + public void onFinishedGoingToSleep(int why) { + mFirstBypassAttempt = mKeyguardBypassController.getBypassEnabled(); + } + }; private final InjectionInflationController mInjectionInflationController; private final PowerManager mPowerManager; @@ -172,8 +192,8 @@ public class NotificationPanelView extends PanelView implements private final NotificationWakeUpCoordinator mWakeUpCoordinator; private final PulseExpansionHandler mPulseExpansionHandler; private final KeyguardBypassController mKeyguardBypassController; - private final KeyguardUpdateMonitor mUpdateMonitor; - + @VisibleForTesting + protected KeyguardUpdateMonitor mUpdateMonitor; @VisibleForTesting protected KeyguardAffordanceHelper mAffordanceHelper; private KeyguardUserSwitcher mKeyguardUserSwitcher; @@ -384,6 +404,7 @@ public class NotificationPanelView extends PanelView implements private boolean mShowingKeyguardHeadsUp; private boolean mAllowExpandForSmallExpansion; private Runnable mExpandAfterLayoutRunnable; + private boolean mFirstBypassAttempt; @Inject public NotificationPanelView(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs, @@ -391,11 +412,12 @@ public class NotificationPanelView extends PanelView implements NotificationWakeUpCoordinator coordinator, PulseExpansionHandler pulseExpansionHandler, DynamicPrivacyController dynamicPrivacyController, - KeyguardBypassController bypassController) { + KeyguardBypassController bypassController, + FalsingManager falsingManager) { super(context, attrs); setWillNotDraw(!DEBUG); mInjectionInflationController = injectionInflationController; - mFalsingManager = FalsingManagerFactory.getInstance(context); + mFalsingManager = falsingManager; mPowerManager = context.getSystemService(PowerManager.class); mWakeUpCoordinator = coordinator; mAccessibilityManager = context.getSystemService(AccessibilityManager.class); @@ -413,6 +435,7 @@ public class NotificationPanelView extends PanelView implements mThemeResId = context.getThemeResId(); mKeyguardBypassController = bypassController; mUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext); + mFirstBypassAttempt = mKeyguardBypassController.getBypassEnabled(); dynamicPrivacyController.addListener(this); mBottomAreaShadeAlphaAnimator = ValueAnimator.ofFloat(1f, 0); @@ -485,6 +508,7 @@ public class NotificationPanelView extends PanelView implements Dependency.get(StatusBarStateController.class).addCallback(this); Dependency.get(ZenModeController.class).addCallback(this); Dependency.get(ConfigurationController.class).addCallback(this); + mUpdateMonitor.registerCallback(mKeyguardUpdateCallback); // Theme might have changed between inflating this view and attaching it to the window, so // force a call to onThemeChanged onThemeChanged(); @@ -497,6 +521,7 @@ public class NotificationPanelView extends PanelView implements Dependency.get(StatusBarStateController.class).removeCallback(this); Dependency.get(ZenModeController.class).removeCallback(this); Dependency.get(ConfigurationController.class).removeCallback(this); + mUpdateMonitor.removeCallback(mKeyguardUpdateCallback); } @Override @@ -625,7 +650,7 @@ public class NotificationPanelView extends PanelView implements } private void initBottomArea() { - mAffordanceHelper = new KeyguardAffordanceHelper(this, getContext()); + mAffordanceHelper = new KeyguardAffordanceHelper(this, getContext(), mFalsingManager); mKeyguardBottomArea.setAffordanceHelper(mAffordanceHelper); mKeyguardBottomArea.setStatusBar(mStatusBar); mKeyguardBottomArea.setUserSetupComplete(mUserSetupComplete); @@ -1738,7 +1763,8 @@ public class NotificationPanelView extends PanelView implements private void setQsExpansion(float height) { height = Math.min(Math.max(height, mQsMinExpansionHeight), mQsMaxExpansionHeight); mQsFullyExpanded = height == mQsMaxExpansionHeight && mQsMaxExpansionHeight != 0; - if (height > mQsMinExpansionHeight && !mQsExpanded && !mStackScrollerOverscrolling) { + if (height > mQsMinExpansionHeight && !mQsExpanded && !mStackScrollerOverscrolling + && !mDozing) { setQsExpanded(true); } else if (height <= mQsMinExpansionHeight && mQsExpanded) { setQsExpanded(false); @@ -2237,7 +2263,9 @@ public class NotificationPanelView extends PanelView implements * mKeyguardStatusBarAnimateAlpha; newAlpha *= 1.0f - mKeyguardHeadsUpShowingAmount; mKeyguardStatusBar.setAlpha(newAlpha); - mKeyguardStatusBar.setVisibility(newAlpha != 0f && !mDozing ? VISIBLE : INVISIBLE); + boolean hideForBypass = mFirstBypassAttempt && mUpdateMonitor.shouldListenForFace(); + mKeyguardStatusBar.setVisibility(newAlpha != 0f && !mDozing && !hideForBypass + ? VISIBLE : INVISIBLE); } private void updateKeyguardBottomAreaAlpha() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java index f8e1093e210b..31600e391f34 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java @@ -42,7 +42,6 @@ import com.android.systemui.DejankUtils; import com.android.systemui.Dependency; import com.android.systemui.Interpolators; import com.android.systemui.R; -import com.android.systemui.classifier.FalsingManagerFactory; import com.android.systemui.doze.DozeLog; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.statusbar.StatusBarStateController; @@ -111,7 +110,7 @@ public abstract class PanelView extends FrameLayout { private FlingAnimationUtils mFlingAnimationUtils; private FlingAnimationUtils mFlingAnimationUtilsClosing; private FlingAnimationUtils mFlingAnimationUtilsDismissing; - private FalsingManager mFalsingManager; + private final FalsingManager mFalsingManager; private final VibratorHelper mVibratorHelper; /** @@ -214,7 +213,7 @@ public abstract class PanelView extends FrameLayout { 0.5f /* maxLengthSeconds */, 0.2f /* speedUpFactor */, 0.6f /* x2 */, 0.84f /* y2 */); mBounceInterpolator = new BounceInterpolator(); - mFalsingManager = FalsingManagerFactory.getInstance(context); + mFalsingManager = Dependency.get(FalsingManager.class); // TODO: inject into a controller. mNotificationsDragEnabled = getResources().getBoolean(R.bool.config_enableNotificationShadeDrag); mVibratorHelper = Dependency.get(VibratorHelper.class); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScreenPinningNotify.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScreenPinningNotify.java index f8731b4980d9..071e00d08d67 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScreenPinningNotify.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScreenPinningNotify.java @@ -51,7 +51,7 @@ public class ScreenPinningNotify { } /** Show a toast that describes the gesture the user should use to escape pinned mode. */ - public void showEscapeToast(boolean isRecentsButtonVisible) { + public void showEscapeToast(boolean isGestureNavEnabled, boolean isRecentsButtonVisible) { long showToastTime = SystemClock.elapsedRealtime(); if ((showToastTime - mLastShowToastTime) < SHOW_TOAST_MINIMUM_INTERVAL) { Slog.i(TAG, "Ignore toast since it is requested in very short interval."); @@ -60,9 +60,11 @@ public class ScreenPinningNotify { if (mLastToast != null) { mLastToast.cancel(); } - mLastToast = makeAllUserToastAndShow(isRecentsButtonVisible - ? R.string.screen_pinning_toast - : R.string.screen_pinning_toast_recents_invisible); + mLastToast = makeAllUserToastAndShow(isGestureNavEnabled + ? R.string.screen_pinning_toast_gesture_nav + : isRecentsButtonVisible + ? R.string.screen_pinning_toast + : R.string.screen_pinning_toast_recents_invisible); mLastShowToastTime = showToastTime; } 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 d12bed9d4f6d..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; @@ -147,7 +148,6 @@ import com.android.systemui.assist.AssistManager; import com.android.systemui.bubbles.BubbleController; import com.android.systemui.charging.WirelessChargingAnimation; import com.android.systemui.classifier.FalsingLog; -import com.android.systemui.classifier.FalsingManagerFactory; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.doze.DozeHost; import com.android.systemui.doze.DozeLog; @@ -239,6 +239,7 @@ import java.util.ArrayList; import java.util.Map; import javax.inject.Inject; +import javax.inject.Named; import dagger.Subcomponent; @@ -383,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 @@ -701,6 +705,7 @@ public class StatusBar extends SystemUI implements DemoMode, mRecents = getComponent(Recents.class); mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE); + mFalsingManager = Dependency.get(FalsingManager.class); // Connect in to the status bar manager service mCommandQueue = getComponent(CommandQueue.class); @@ -776,7 +781,6 @@ public class StatusBar extends SystemUI implements DemoMode, putComponent(DozeHost.class, mDozeServiceHost); mScreenPinningRequest = new ScreenPinningRequest(mContext); - mFalsingManager = FalsingManagerFactory.getInstance(mContext); Dependency.get(ActivityStarterDelegate.class).setActivityStarterImpl(this); @@ -1065,7 +1069,7 @@ public class StatusBar extends SystemUI implements DemoMode, final NotificationRowBinderImpl rowBinder = new NotificationRowBinderImpl( mContext, - SystemUIFactory.getInstance().provideAllowNotificationLongPress(), + mAllowNotificationLongPress, mKeyguardBypassController, mStatusBarStateController); @@ -1243,7 +1247,7 @@ public class StatusBar extends SystemUI implements DemoMode, mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this, getBouncerContainer(), mNotificationPanel, mBiometricUnlockController, mStatusBarWindow.findViewById(R.id.lock_icon_container), mStackScroller, - mKeyguardBypassController); + mKeyguardBypassController, mFalsingManager); mKeyguardIndicationController .setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager); mBiometricUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager); @@ -2415,7 +2419,7 @@ public class StatusBar extends SystemUI implements DemoMode, mKeyguardUpdateMonitor.dump(fd, pw, args); } - FalsingManagerFactory.getInstance(mContext).dump(pw); + Dependency.get(FalsingManager.class).dump(pw); FalsingLog.dump(pw); pw.println("SharedPreferences:"); 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 7e86651ffef6..0c47d1468a7f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -44,6 +44,7 @@ import com.android.systemui.Dependency; import com.android.systemui.SystemUIFactory; 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.shared.system.QuickStepContract; import com.android.systemui.statusbar.CommandQueue; @@ -210,7 +211,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb BiometricUnlockController biometricUnlockController, DismissCallbackRegistry dismissCallbackRegistry, ViewGroup lockIconContainer, View notificationContainer, - KeyguardBypassController bypassController) { + KeyguardBypassController bypassController, FalsingManager falsingManager) { mStatusBar = statusBar; mContainer = container; mLockIconContainer = lockIconContainer; @@ -220,7 +221,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb mBiometricUnlockController = biometricUnlockController; mBouncer = SystemUIFactory.getInstance().createKeyguardBouncer(mContext, mViewMediatorCallback, mLockPatternUtils, container, dismissCallbackRegistry, - mExpansionCallback, bypassController); + mExpansionCallback, falsingManager, bypassController); mNotificationPanelView = notificationPanelView; notificationPanelView.addExpansionListener(this); mBypassController = bypassController; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java index a870590c08ac..069219802cc3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java @@ -224,7 +224,7 @@ public class StatusBarNotificationPresenter implements NotificationPresenter, mVisualStabilityManager.setUpWithPresenter(this); mGutsManager.setUpWithPresenter(this, notifListContainer, mCheckSaveListener, mOnSettingsClickListener); - // ForegroundServiceControllerListener adds its listener in its constructor + // ForegroundServiceNotificationListener adds its listener in its constructor // but we need to request it here in order for it to be instantiated. // TODO: figure out how to do this correctly once Dependency.get() is gone. Dependency.get(ForegroundServiceNotificationListener.class); 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/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java index 1081bad9bf1c..6789930ab76e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java @@ -62,7 +62,6 @@ import com.android.internal.widget.FloatingToolbar; import com.android.systemui.Dependency; import com.android.systemui.ExpandHelper; import com.android.systemui.R; -import com.android.systemui.classifier.FalsingManagerFactory; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.DragDownHelper; @@ -157,7 +156,7 @@ public class StatusBarWindowView extends FrameLayout { setMotionEventSplittingEnabled(false); mTransparentSrcPaint.setColor(0); mTransparentSrcPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC)); - mFalsingManager = FalsingManagerFactory.getInstance(context); + mFalsingManager = Dependency.get(FalsingManager.class); // TODO: inject into a controller. mGestureDetector = new GestureDetector(context, mGestureListener); mStatusBarStateController = Dependency.get(StatusBarStateController.class); Dependency.get(TunerService.class).addTunable(mTunable, @@ -291,7 +290,7 @@ public class StatusBarWindowView extends FrameLayout { ExpandHelper.Callback expandHelperCallback = stackScrollLayout.getExpandHelperCallback(); DragDownHelper.DragDownCallback dragDownCallback = stackScrollLayout.getDragDownCallback(); setDragDownHelper(new DragDownHelper(getContext(), this, expandHelperCallback, - dragDownCallback)); + dragDownCallback, mFalsingManager)); } @VisibleForTesting 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..dbfb09f7fc41 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java @@ -21,6 +21,7 @@ import android.database.ContentObserver; import android.net.NetworkCapabilities; import android.os.Handler; import android.os.Looper; +import android.os.Message; import android.provider.Settings.Global; import android.telephony.NetworkRegistrationInfo; import android.telephony.PhoneStateListener; @@ -54,6 +55,10 @@ import java.util.regex.Pattern; public class MobileSignalController extends SignalController< MobileSignalController.MobileState, MobileSignalController.MobileIconGroup> { + + // The message to display Nr5G icon gracfully by CarrierConfig timeout + private static final int MSG_DISPLAY_GRACE = 1; + private final TelephonyManager mPhone; private final SubscriptionDefaults mDefaults; private final String mNetworkNameDefault; @@ -76,8 +81,11 @@ public class MobileSignalController extends SignalController< private SignalStrength mSignalStrength; private MobileIconGroup mDefaultIcons; private Config mConfig; + private final Handler mDisplayGraceHandler; @VisibleForTesting boolean mInflateSignalStrengths = false; + @VisibleForTesting + boolean mIsShowingIconGracefully = false; // Some specific carriers have 5GE network which is special LTE CA network. private static final int NETWORK_TYPE_LTE_CA_5GE = TelephonyManager.MAX_NETWORK_TYPE + 1; @@ -116,6 +124,16 @@ public class MobileSignalController extends SignalController< updateTelephony(); } }; + + mDisplayGraceHandler = new Handler(receiverLooper) { + @Override + public void handleMessage(Message msg) { + if (msg.what == MSG_DISPLAY_GRACE) { + mIsShowingIconGracefully = false; + updateTelephony(); + } + } + }; } public void setConfiguration(Config config) { @@ -479,6 +497,10 @@ public class MobileSignalController extends SignalController< // When the device is camped on a 5G Non-Standalone network, the data network type is still // LTE. In this case, we first check which 5G icon should be shown. MobileIconGroup nr5GIconGroup = getNr5GIconGroup(); + if (mConfig.nrIconDisplayGracePeriodMs > 0) { + nr5GIconGroup = adjustNr5GIconGroupByDisplayGraceTime(nr5GIconGroup); + } + if (nr5GIconGroup != null) { mCurrentState.iconGroup = nr5GIconGroup; } else if (mNetworkToIconLookup.indexOfKey(mDataNetType) >= 0) { @@ -537,8 +559,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)) { @@ -549,6 +577,46 @@ public class MobileSignalController extends SignalController< return null; } + /** + * The function to adjust MobileIconGroup depend on CarrierConfig's time + * nextIconGroup == null imply next state could be 2G/3G/4G/4G+ + * nextIconGroup != null imply next state will be 5G/5G+ + * Flag : mIsShowingIconGracefully + * --------------------------------------------------------------------------------- + * | Last state | Current state | Flag | Action | + * --------------------------------------------------------------------------------- + * | 5G/5G+ | 2G/3G/4G/4G+ | true | return previous IconGroup | + * | 5G/5G+ | 5G/5G+ | true | Bypass | + * | 2G/3G/4G/4G+ | 5G/5G+ | true | Bypass | + * | 2G/3G/4G/4G+ | 2G/3G/4G/4G+ | true | Bypass | + * | SS.connected | SS.disconnect | T|F | Reset timer | + * |NETWORK_TYPE_LTE|!NETWORK_TYPE_LTE| T|F | Reset timer | + * | 5G/5G+ | 2G/3G/4G/4G+ | false| Bypass | + * | 5G/5G+ | 5G/5G+ | false| Bypass | + * | 2G/3G/4G/4G+ | 5G/5G+ | false| SendMessageDelay(time), flag->true | + * | 2G/3G/4G/4G+ | 2G/3G/4G/4G+ | false| Bypass | + * --------------------------------------------------------------------------------- + */ + private MobileIconGroup adjustNr5GIconGroupByDisplayGraceTime( + MobileIconGroup candidateIconGroup) { + if (mIsShowingIconGracefully && candidateIconGroup == null) { + candidateIconGroup = (MobileIconGroup) mCurrentState.iconGroup; + } else if (!mIsShowingIconGracefully && candidateIconGroup != null + && mLastState.iconGroup != candidateIconGroup) { + mDisplayGraceHandler.sendMessageDelayed( + mDisplayGraceHandler.obtainMessage(MSG_DISPLAY_GRACE), + mConfig.nrIconDisplayGracePeriodMs); + mIsShowingIconGracefully = true; + } else if (!mCurrentState.connected || mDataState == TelephonyManager.DATA_DISCONNECTED + || candidateIconGroup == null) { + mDisplayGraceHandler.removeMessages(MSG_DISPLAY_GRACE); + mIsShowingIconGracefully = false; + candidateIconGroup = null; + } + + return candidateIconGroup; + } + private boolean isDataDisabled() { return !mPhone.isDataCapable(); } @@ -559,6 +627,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(); } @@ -572,6 +642,7 @@ public class MobileSignalController extends SignalController< pw.println(" mDataNetType=" + mDataNetType + ","); pw.println(" mInflateSignalStrengths=" + mInflateSignalStrengths + ","); pw.println(" isDataDisabled=" + isDataDisabled() + ","); + pw.println(" mIsShowingIconGracefully=" + mIsShowingIconGracefully + ","); } class MobilePhoneStateListener extends PhoneStateListener { 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..bb3742198117 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java @@ -51,6 +51,7 @@ import android.telephony.SubscriptionManager; import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener; import android.telephony.TelephonyManager; import android.text.TextUtils; +import android.text.format.DateUtils; import android.util.Log; import android.util.MathUtils; import android.util.SparseArray; @@ -829,6 +830,13 @@ public class NetworkControllerImpl extends BroadcastReceiver pw.print(" mEmergencySource="); pw.println(emergencyToString(mEmergencySource)); + pw.println(" - config ------"); + pw.print(" patternOfCarrierSpecificDataIcon="); + pw.println(mConfig.patternOfCarrierSpecificDataIcon); + pw.print(" nr5GIconMap="); + pw.println(mConfig.nr5GIconMap.toString()); + pw.print(" nrIconDisplayGracePeriodMs="); + pw.println(mConfig.nrIconDisplayGracePeriodMs); for (int i = 0; i < mMobileSignalControllers.size(); i++) { MobileSignalController mobileSignalController = mMobileSignalControllers.valueAt(i); mobileSignalController.dump(pw); @@ -992,6 +1000,8 @@ public class NetworkControllerImpl extends BroadcastReceiver datatype.equals("3g") ? TelephonyIcons.THREE_G : datatype.equals("4g") ? TelephonyIcons.FOUR_G : datatype.equals("4g+") ? TelephonyIcons.FOUR_G_PLUS : + datatype.equals("5g") ? TelephonyIcons.NR_5G : + datatype.equals("5g+") ? TelephonyIcons.NR_5G_PLUS : datatype.equals("e") ? TelephonyIcons.E : datatype.equals("g") ? TelephonyIcons.G : datatype.equals("h") ? TelephonyIcons.H : @@ -1108,8 +1118,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<>(); @@ -1122,6 +1133,7 @@ public class NetworkControllerImpl extends BroadcastReceiver boolean inflateSignalStrengths = false; boolean alwaysShowDataRatIcon = false; public String patternOfCarrierSpecificDataIcon = ""; + public long nrIconDisplayGracePeriodMs; /** * Mapping from NR 5G status string to an integer. The NR 5G status string should match @@ -1129,10 +1141,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); } @@ -1173,6 +1186,9 @@ public class NetworkControllerImpl extends BroadcastReceiver add5GIconMapping(pair, config); } } + setDisplayGraceTime( + b.getInt(CarrierConfigManager.KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT), + config); } return config; @@ -1206,5 +1222,18 @@ public class NetworkControllerImpl extends BroadcastReceiver TelephonyIcons.ICON_NAME_TO_ICON.get(value)); } } + + /** + * Set display gracefully period time(MS) depend on carrierConfig KEY + * KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT, and this function will convert to ms. + * {@link CarrierConfigManager}. + * + * @param time showing 5G icon gracefully in the period of the time(SECOND) + * @param config container that used to store the parsed configs. + */ + @VisibleForTesting + static void setDisplayGraceTime(int time, Config config) { + config.nrIconDisplayGracePeriodMs = time * DateUtils.SECOND_IN_MILLIS; + } } } 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/src/com/android/systemui/usb/StorageNotification.java b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java index de86f3d8cfb4..ff5bd03740bd 100644 --- a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java +++ b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java @@ -628,6 +628,14 @@ public class StorageNotification extends SystemUI { final int requestKey = vol.getId().hashCode(); return PendingIntent.getActivityAsUser(mContext, requestKey, intent, PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT); + } else if (isAutomotive()) { + intent.setClassName("com.android.car.settings", + "com.android.car.settings.storage.StorageUnmountReceiver"); + intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.getId()); + + final int requestKey = vol.getId().hashCode(); + return PendingIntent.getBroadcastAsUser(mContext, requestKey, intent, + PendingIntent.FLAG_CANCEL_CURRENT, UserHandle.CURRENT); } else { intent.setClassName("com.android.settings", "com.android.settings.deviceinfo.StorageUnmountReceiver"); @@ -749,6 +757,11 @@ public class StorageNotification extends SystemUI { PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT); } + private boolean isAutomotive() { + PackageManager packageManager = mContext.getPackageManager(); + return packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE); + } + private boolean isTv() { PackageManager packageManager = mContext.getPackageManager(); return packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK); diff --git a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java index ede30046d6c3..e44e58a84dc8 100644 --- a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java +++ b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java @@ -26,12 +26,13 @@ import android.view.View; import com.android.keyguard.KeyguardClockSwitch; import com.android.keyguard.KeyguardMessageArea; import com.android.keyguard.KeyguardSliceView; -import com.android.systemui.SystemUIFactory; +import com.android.systemui.SystemUIRootComponent; import com.android.systemui.qs.QSCarrierGroup; import com.android.systemui.qs.QSFooterImpl; import com.android.systemui.qs.QSPanel; import com.android.systemui.qs.QuickQSPanel; import com.android.systemui.qs.QuickStatusBarHeader; +import com.android.systemui.qs.customize.QSCustomizer; import com.android.systemui.statusbar.NotificationShelf; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; import com.android.systemui.statusbar.phone.LockIcon; @@ -62,7 +63,7 @@ public class InjectionInflationController { private final LayoutInflater.Factory2 mFactory = new InjectionFactory(); @Inject - public InjectionInflationController(SystemUIFactory.SystemUIRootComponent rootComponent) { + public InjectionInflationController(SystemUIRootComponent rootComponent) { mViewCreator = rootComponent.createViewCreator(); initInjectionMap(); } @@ -172,6 +173,11 @@ public class InjectionInflationController { * Creates the QuickQSPanel. */ QuickQSPanel createQuickQSPanel(); + + /** + * Creates the QSCustomizer. + */ + QSCustomizer createQSCustomizer(); } /** 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/ForegroundServiceNotificationListenerTest.java b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceNotificationListenerTest.java new file mode 100644 index 000000000000..72a457e9bbbe --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceNotificationListenerTest.java @@ -0,0 +1,86 @@ +/* + * 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.ForegroundServiceNotificationListener.ForegroundServiceLifetimeExtender.MIN_FGS_TIME_MS; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import android.app.Notification; +import android.service.notification.StatusBarNotification; + +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import com.android.systemui.statusbar.notification.collection.NotificationEntry; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class ForegroundServiceNotificationListenerTest extends SysuiTestCase { + private ForegroundServiceNotificationListener.ForegroundServiceLifetimeExtender mExtender = + new ForegroundServiceNotificationListener.ForegroundServiceLifetimeExtender(); + private StatusBarNotification mSbn; + private NotificationEntry mEntry; + private Notification mNotif; + + @Before + public void setup() { + mNotif = new Notification.Builder(mContext, "") + .setSmallIcon(R.drawable.ic_person) + .setContentTitle("Title") + .setContentText("Text") + .build(); + + mSbn = mock(StatusBarNotification.class); + when(mSbn.getNotification()).thenReturn(mNotif); + + mEntry = new NotificationEntry(mSbn); + } + + /** + * ForegroundServiceLifetimeExtenderTest + */ + @Test + public void testShouldExtendLifetime_should_foreground() { + // Extend the lifetime of a FGS notification iff it has not been visible + // for the minimum time + mNotif.flags |= Notification.FLAG_FOREGROUND_SERVICE; + when(mSbn.getPostTime()).thenReturn(System.currentTimeMillis()); + assertTrue(mExtender.shouldExtendLifetime(mEntry)); + } + + @Test + public void testShouldExtendLifetime_shouldNot_foreground() { + mNotif.flags |= Notification.FLAG_FOREGROUND_SERVICE; + when(mSbn.getPostTime()).thenReturn(System.currentTimeMillis() - MIN_FGS_TIME_MS - 1); + assertFalse(mExtender.shouldExtendLifetime(mEntry)); + } + + @Test + public void testShouldExtendLifetime_shouldNot_notForeground() { + mNotif.flags = 0; + when(mSbn.getPostTime()).thenReturn(System.currentTimeMillis() - MIN_FGS_TIME_MS - 1); + assertFalse(mExtender.shouldExtendLifetime(mEntry)); + } +} 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/doze/DozeConfigurationUtil.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java index 2ed0970ce44b..0c124fff53a3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java @@ -37,7 +37,6 @@ public class DozeConfigurationUtil { when(params.getPulseOnSigMotion()).thenReturn(false); when(params.getPickupVibrationThreshold()).thenReturn(0); when(params.getProxCheckBeforePulse()).thenReturn(true); - when(params.getPickupPerformsProxCheck()).thenReturn(true); when(params.getPolicy()).thenReturn(mock(AlwaysOnDisplayPolicy.class)); when(params.doubleTapReportsTouchCoordinates()).thenReturn(false); when(params.getDisplayNeedsBlanking()).thenReturn(false); diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java index 6dfb19ea075a..1e18e51bc079 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java @@ -45,11 +45,14 @@ import android.testing.UiThreadTest; import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; +import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.util.wakelock.WakeLockFake; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; @SmallTest @RunWith(AndroidTestingRunner.class) @@ -58,6 +61,8 @@ public class DozeMachineTest extends SysuiTestCase { DozeMachine mMachine; + @Mock + private WakefulnessLifecycle mWakefulnessLifecycle; private DozeServiceFake mServiceFake; private WakeLockFake mWakeLockFake; private AmbientDisplayConfiguration mConfigMock; @@ -65,12 +70,13 @@ public class DozeMachineTest extends SysuiTestCase { @Before public void setUp() { + MockitoAnnotations.initMocks(this); mServiceFake = new DozeServiceFake(); mWakeLockFake = new WakeLockFake(); mConfigMock = mock(AmbientDisplayConfiguration.class); mPartMock = mock(DozeMachine.Part.class); - mMachine = new DozeMachine(mServiceFake, mConfigMock, mWakeLockFake); + mMachine = new DozeMachine(mServiceFake, mConfigMock, mWakeLockFake, mWakefulnessLifecycle); mMachine.setParts(new DozeMachine.Part[]{mPartMock}); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java index 7df45a3d8949..cd6d1e069566 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java @@ -19,7 +19,6 @@ package com.android.systemui.doze; import static com.android.systemui.plugins.SensorManagerPlugin.Sensor.TYPE_WAKE_LOCK_SCREEN; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyFloat; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; @@ -79,8 +78,6 @@ public class DozeSensorsTest extends SysuiTestCase { private AlwaysOnDisplayPolicy mAlwaysOnDisplayPolicy; @Mock private TriggerSensor mTriggerSensor; - @Mock - private TriggerSensor mProxGatedTriggerSensor; private SensorManagerPlugin.SensorEventListener mWakeLockScreenListener; private TestableLooper mTestableLooper; private DozeSensors mDozeSensors; @@ -88,7 +85,6 @@ public class DozeSensorsTest extends SysuiTestCase { @Before public void setUp() { MockitoAnnotations.initMocks(this); - when(mProxGatedTriggerSensor.performsProxCheck()).thenReturn(true); mTestableLooper = TestableLooper.get(this); when(mAmbientDisplayConfiguration.getWakeLockScreenDebounce()).thenReturn(5000L); when(mAmbientDisplayConfiguration.alwaysOnEnabled(anyInt())).thenReturn(true); @@ -106,14 +102,14 @@ public class DozeSensorsTest extends SysuiTestCase { mWakeLockScreenListener.onSensorChanged(mock(SensorManagerPlugin.SensorEvent.class)); mTestableLooper.processAllMessages(); verify(mCallback).onSensorPulse(eq(DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN), - anyBoolean(), anyFloat(), anyFloat(), eq(null)); + anyFloat(), anyFloat(), eq(null)); mDozeSensors.requestTemporaryDisable(); reset(mCallback); mWakeLockScreenListener.onSensorChanged(mock(SensorManagerPlugin.SensorEvent.class)); mTestableLooper.processAllMessages(); verify(mCallback, never()).onSensorPulse(eq(DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN), - anyBoolean(), anyFloat(), anyFloat(), eq(null)); + anyFloat(), anyFloat(), eq(null)); } @Test @@ -132,20 +128,17 @@ public class DozeSensorsTest extends SysuiTestCase { } @Test - public void testSetPaused_onlyPausesNonGatedSensors() { + public void testSetPaused_doesntPause_sensors() { mDozeSensors.setListening(true); verify(mTriggerSensor).setListening(eq(true)); - verify(mProxGatedTriggerSensor).setListening(eq(true)); - clearInvocations(mTriggerSensor, mProxGatedTriggerSensor); + clearInvocations(mTriggerSensor); mDozeSensors.setPaused(true); - verify(mTriggerSensor).setListening(eq(false)); - verify(mProxGatedTriggerSensor).setListening(eq(true)); - - clearInvocations(mTriggerSensor, mProxGatedTriggerSensor); - mDozeSensors.setPaused(false); verify(mTriggerSensor).setListening(eq(true)); - verify(mProxGatedTriggerSensor).setListening(eq(true)); + + clearInvocations(mTriggerSensor); + mDozeSensors.setListening(false); + verify(mTriggerSensor).setListening(eq(false)); } private class TestableDozeSensors extends DozeSensors { @@ -161,7 +154,7 @@ public class DozeSensorsTest extends SysuiTestCase { mWakeLockScreenListener = (PluginSensor) sensor; } } - mSensors = new TriggerSensor[] {mTriggerSensor, mProxGatedTriggerSensor}; + mSensors = new TriggerSensor[] {mTriggerSensor}; } } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java index d4642238d8fd..e190f9923da8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java @@ -20,7 +20,6 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.clearInvocations; -import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; @@ -134,28 +133,4 @@ public class DozeTriggersTest extends SysuiTestCase { mTriggers.transitionTo(DozeMachine.State.DOZE, DozeMachine.State.FINISH); verify(mDockManagerFake).removeListener(any()); } - - @Test - public void testOnSensor_whenUndockedWithNearAndDoubleTapScreen_shouldNotWakeUp() { - mSensors.getMockProximitySensor().sendProximityResult(false /* far */); - - mTriggers.onSensor(DozeLog.REASON_SENSOR_DOUBLE_TAP, - false /* sensorPerformedProxCheck */, 50 /* screenX */, 50 /* screenY */, - null /* rawValues */); - verify(mMachine, never()).wakeUp(); - } - - @Test - public void testOnSensor_whenDockedWithNearAndDoubleTapScreen_shouldWakeUp() { - doReturn(true).when(mDockManagerFake).isDocked(); - doReturn(true).when(mParameters).getDisplayNeedsBlanking(); - mSensors.getMockProximitySensor().sendProximityResult(false /* far */); - - mTriggers.onSensor(DozeLog.REASON_SENSOR_DOUBLE_TAP, - false /* sensorPerformedProxCheck */, 50 /* screenX */, 50 /* screenY */, - null /* rawValues */); - - verify(mHost).setAodDimmingScrim(eq(1f)); - verify(mMachine).wakeUp(); - } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UserDetailViewAdapterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UserDetailViewAdapterTest.kt new file mode 100644 index 000000000000..b51e716591fe --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UserDetailViewAdapterTest.kt @@ -0,0 +1,128 @@ +/* + * 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.qs.tiles + +import android.content.Context +import android.content.pm.UserInfo +import android.graphics.Bitmap +import android.testing.AndroidTestingRunner +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.statusbar.policy.UserSwitcherController +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.ArgumentMatchers.any +import org.mockito.ArgumentMatchers.anyBoolean +import org.mockito.ArgumentMatchers.anyInt +import org.mockito.Mock +import org.mockito.Mockito.`when` +import org.mockito.Mockito.verify +import org.mockito.MockitoAnnotations + +@RunWith(AndroidTestingRunner::class) +@SmallTest +class UserDetailViewAdapterTest : SysuiTestCase() { + + @Mock private lateinit var mUserSwitcherController: UserSwitcherController + @Mock private lateinit var mParent: ViewGroup + @Mock private lateinit var mUserDetailItemView: UserDetailItemView + @Mock private lateinit var mOtherView: View + @Mock private lateinit var mInflatedUserDetailItemView: UserDetailItemView + @Mock private lateinit var mUserInfo: UserInfo + @Mock private lateinit var mPicture: Bitmap + @Mock private lateinit var mLayoutInflater: LayoutInflater + private lateinit var adapter: UserDetailView.Adapter + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + + mContext.addMockSystemService(Context.LAYOUT_INFLATER_SERVICE, mLayoutInflater) + `when`(mLayoutInflater.inflate(anyInt(), any(ViewGroup::class.java), anyBoolean())) + .thenReturn(mInflatedUserDetailItemView) + adapter = UserDetailView.Adapter(mContext, mUserSwitcherController) + } + + private fun clickableTest( + current: Boolean, + guest: Boolean, + convertView: View, + shouldBeClickable: Boolean + ) { + val user = createUserRecord(current, guest) + val v = adapter.createUserDetailItemView(convertView, mParent, user) + if (shouldBeClickable) { + verify(v).setOnClickListener(adapter) + } else { + verify(v).setOnClickListener(null) + } + } + + @Test + fun testGuestIsClickable_differentViews_notCurrent() { + clickableTest(false, true, mOtherView, true) + } + + @Test + fun testGuestIsClickable_differentViews_Current() { + clickableTest(true, true, mOtherView, true) + } + + @Test + fun testGuestIsClickable_sameView_notCurrent() { + clickableTest(false, true, mUserDetailItemView, true) + } + + @Test + fun testGuestIsClickable_sameView_Current() { + clickableTest(true, true, mUserDetailItemView, true) + } + + @Test + fun testNotGuestCurrentUserIsNotClickable_otherView() { + clickableTest(true, false, mOtherView, false) + } + + @Test + fun testNotGuestCurrentUserIsNotClickable_sameView() { + clickableTest(true, false, mUserDetailItemView, false) + } + + @Test + fun testNotGuestNotCurrentUserIsClickable_otherView() { + clickableTest(false, false, mOtherView, true) + } + + @Test + fun testNotGuestNotCurrentUserIsClickable_sameView() { + clickableTest(false, false, mUserDetailItemView, true) + } + + private fun createUserRecord(current: Boolean, guest: Boolean) = + UserSwitcherController.UserRecord( + mUserInfo, + mPicture, + guest, + current, + false /* isAddUser */, + false /* isRestricted */, + true /* isSwitchToEnabled */) +}
\ No newline at end of file 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/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java index c851c915d655..31054260eb15 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java @@ -53,6 +53,7 @@ import com.android.systemui.ExpandHelper; import com.android.systemui.InitController; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; +import com.android.systemui.classifier.FalsingManagerFake; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.EmptyShadeView; @@ -80,7 +81,6 @@ import com.android.systemui.statusbar.phone.StatusBarTest.TestableNotificationEn import com.android.systemui.statusbar.policy.ConfigurationController; import org.junit.After; -import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -165,7 +165,8 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { mock(ActivityStarterDelegate.class), mock(SysuiStatusBarStateController.class), mHeadsUpManager, - mKeyguardBypassController); + mKeyguardBypassController, + new FalsingManagerFake()); mStackScroller = spy(mStackScrollerInternal); mStackScroller.setShelf(notificationShelf); mStackScroller.setStatusBar(mBar); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java index b24c3ddc1199..06a2eecd208c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java @@ -40,6 +40,7 @@ import androidx.test.filters.SmallTest; import com.android.systemui.SwipeHelper; import com.android.systemui.SysuiTestCase; +import com.android.systemui.classifier.FalsingManagerFake; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; @@ -76,7 +77,8 @@ public class NotificationSwipeHelperTest extends SysuiTestCase { public void setUp() throws Exception { mCallback = mock(NotificationSwipeHelper.NotificationCallback.class); mListener = mock(NotificationMenuRowPlugin.OnMenuEventListener.class); - mSwipeHelper = spy(new NotificationSwipeHelper(SwipeHelper.X, mCallback, mContext, mListener)); + mSwipeHelper = spy(new NotificationSwipeHelper( + SwipeHelper.X, mCallback, mContext, mListener, new FalsingManagerFake())); mView = mock(View.class); mEvent = mock(MotionEvent.class); mMenuRow = mock(NotificationMenuRowPlugin.class); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java index d14b460d8c63..0334d49ce9df 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java @@ -21,21 +21,26 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.StatusBarManager; +import android.hardware.biometrics.BiometricSourceType; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.view.MotionEvent; +import android.view.View; import android.view.ViewGroup; import androidx.test.filters.SmallTest; import com.android.keyguard.KeyguardStatusView; +import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.SystemUIFactory; import com.android.systemui.SysuiTestCase; +import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.KeyguardAffordanceView; import com.android.systemui.statusbar.NotificationLockscreenUserManager; @@ -49,7 +54,6 @@ import com.android.systemui.statusbar.notification.stack.NotificationRoundnessMa import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.ZenModeController; -import com.android.systemui.tuner.TunerService; import com.android.systemui.util.InjectionInflationController; import org.junit.Before; @@ -98,6 +102,12 @@ public class NotificationPanelViewTest extends SysuiTestCase { private PanelBar mPanelBar; @Mock private KeyguardAffordanceHelper mAffordanceHelper; + @Mock + private KeyguardUpdateMonitor mUpdateMonitor; + @Mock + private FalsingManager mFalsingManager; + @Mock + private KeyguardBypassController mKeyguardBypassController; private NotificationPanelView mNotificationPanelView; @Before @@ -112,18 +122,16 @@ public class NotificationPanelViewTest extends SysuiTestCase { mDependency.injectMockDependency(NotificationLockscreenUserManager.class); mDependency.injectMockDependency(ConfigurationController.class); mDependency.injectMockDependency(ZenModeController.class); - KeyguardBypassController bypassController = new KeyguardBypassController(mContext, - mock(TunerService.class), mStatusBarStateController, - mock(NotificationLockscreenUserManager.class)); NotificationWakeUpCoordinator coordinator = new NotificationWakeUpCoordinator(mContext, mock(HeadsUpManagerPhone.class), new StatusBarStateControllerImpl(), - bypassController); + mKeyguardBypassController); PulseExpansionHandler expansionHandler = new PulseExpansionHandler(mContext, coordinator, - bypassController, mHeadsUpManager, mock(NotificationRoundnessManager.class)); + mKeyguardBypassController, mHeadsUpManager, + mock(NotificationRoundnessManager.class)); mNotificationPanelView = new TestableNotificationPanelView(coordinator, expansionHandler, - bypassController); + mKeyguardBypassController); mNotificationPanelView.setHeadsUpManager(mHeadsUpManager); mNotificationPanelView.setBar(mPanelBar); @@ -183,6 +191,20 @@ public class NotificationPanelViewTest extends SysuiTestCase { assertThat(mNotificationPanelView.isTrackingBlocked()).isFalse(); } + @Test + public void testKeyguardStatusBarVisibility_hiddenForBypass() { + when(mUpdateMonitor.shouldListenForFace()).thenReturn(true); + mNotificationPanelView.mKeyguardUpdateCallback.onBiometricRunningStateChanged(true, + BiometricSourceType.FACE); + verify(mKeyguardStatusBar, never()).setVisibility(View.VISIBLE); + + when(mKeyguardBypassController.getBypassEnabled()).thenReturn(true); + mNotificationPanelView.mKeyguardUpdateCallback.onFinishedGoingToSleep(0); + mNotificationPanelView.mKeyguardUpdateCallback.onBiometricRunningStateChanged(true, + BiometricSourceType.FACE); + verify(mKeyguardStatusBar, never()).setVisibility(View.VISIBLE); + } + private class TestableNotificationPanelView extends NotificationPanelView { TestableNotificationPanelView(NotificationWakeUpCoordinator coordinator, PulseExpansionHandler expansionHandler, @@ -191,7 +213,8 @@ public class NotificationPanelViewTest extends SysuiTestCase { new InjectionInflationController( SystemUIFactory.getInstance().getRootComponent()), coordinator, expansionHandler, mock(DynamicPrivacyController.class), - bypassController); + bypassController, + mFalsingManager); mNotificationStackScroller = mNotificationStackScrollLayout; mKeyguardStatusView = NotificationPanelViewTest.this.mKeyguardStatusView; mKeyguardStatusBar = NotificationPanelViewTest.this.mKeyguardStatusBar; @@ -199,6 +222,7 @@ public class NotificationPanelViewTest extends SysuiTestCase { mBigClockContainer = NotificationPanelViewTest.this.mBigClockContainer; mQsFrame = NotificationPanelViewTest.this.mQsFrame; mAffordanceHelper = NotificationPanelViewTest.this.mAffordanceHelper; + mUpdateMonitor = NotificationPanelViewTest.this.mUpdateMonitor; initDependencies(NotificationPanelViewTest.this.mStatusBar, NotificationPanelViewTest.this.mGroupManager, NotificationPanelViewTest.this.mNotificationShelf, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java index da2e8dc90854..63f653b0b303 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java @@ -39,8 +39,10 @@ import androidx.test.filters.SmallTest; import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.ViewMediatorCallback; import com.android.systemui.SysuiTestCase; +import com.android.systemui.classifier.FalsingManagerFake; import com.android.systemui.keyguard.DismissCallbackRegistry; import com.android.systemui.plugins.ActivityStarter.OnDismissAction; +import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.SysuiStatusBarStateController; @@ -93,7 +95,8 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase { mViewMediatorCallback, mLockPatternUtils); mStatusBarKeyguardViewManager.registerStatusBar(mStatusBar, mContainer, mNotificationPanelView, mBiometrucUnlockController, mDismissCallbackRegistry, - mLockIconContainer, mNotificationContainer, mBypassController); + mLockIconContainer, mNotificationContainer, mBypassController, + new FalsingManagerFake()); mStatusBarKeyguardViewManager.show(null); } @@ -232,11 +235,11 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase { BiometricUnlockController fingerprintUnlockController, DismissCallbackRegistry dismissCallbackRegistry, ViewGroup lockIconContainer, View notificationContainer, - KeyguardBypassController bypassController) { + KeyguardBypassController bypassController, FalsingManager falsingManager) { super.registerStatusBar(statusBar, container, notificationPanelView, fingerprintUnlockController, dismissCallbackRegistry, lockIconContainer, - notificationContainer, bypassController); + notificationContainer, bypassController, falsingManager); mBouncer = StatusBarKeyguardViewManagerTest.this.mBouncer; } } -}
\ No newline at end of file +} 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..c03f07e59129 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 @@ -30,6 +30,7 @@ import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import android.app.Instrumentation; import android.content.Intent; import android.net.ConnectivityManager; import android.net.Network; @@ -48,6 +49,8 @@ import android.testing.TestableLooper; import android.testing.TestableResources; import android.util.Log; +import androidx.test.InstrumentationRegistry; + import com.android.internal.telephony.cdma.EriInfo; import com.android.settingslib.graph.SignalDrawable; import com.android.settingslib.net.DataUsageController; @@ -95,6 +98,7 @@ public class NetworkControllerBaseTest extends SysuiTestCase { protected SubscriptionDefaults mMockSubDefaults; protected DeviceProvisionedController mMockProvisionController; protected DeviceProvisionedListener mUserCallback; + protected Instrumentation mInstrumentation; protected int mSubId; @@ -116,6 +120,7 @@ public class NetworkControllerBaseTest extends SysuiTestCase { @Before public void setUp() throws Exception { + mInstrumentation = InstrumentationRegistry.getInstrumentation(); Settings.Global.putInt(mContext.getContentResolver(), Global.AIRPLANE_MODE_ON, 0); TestableResources res = mContext.getOrCreateTestableResources(); res.addOverride(R.string.cell_data_off_content_description, NO_DATA_STRING); @@ -228,6 +233,28 @@ 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 setupDefaultNr5GIconDisplayGracePeriodTime_enableThirtySeconds() { + final int enableDisplayGraceTimeSec = 30; + NetworkControllerImpl.Config.setDisplayGraceTime(enableDisplayGraceTimeSec, mConfig); + } + + public void setupDefaultNr5GIconDisplayGracePeriodTime_disabled() { + final int disableDisplayGraceTimeSec = 0; + NetworkControllerImpl.Config.setDisplayGraceTime(disableDisplayGraceTimeSec, 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..3ddfbdac6db8 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 @@ -1,5 +1,7 @@ package com.android.systemui.statusbar.policy; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.anyInt; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; @@ -175,6 +177,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(); @@ -216,6 +247,186 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest { } @Test + public void testNr5GIcon_displayGracePeriodTime_enabled() { + setupDefaultNr5GIconConfiguration(); + setupDefaultNr5GIconDisplayGracePeriodTime_enableThirtySeconds(); + setupDefaultSignal(); + mNetworkController.handleConfigurationChanged(); + mPhoneStateListener.onServiceStateChanged(mServiceState); + + ServiceState ss = Mockito.mock(ServiceState.class); + // While nrIconDisplayGracePeriodMs > 0 & is Nr5G, mIsShowingIconGracefully should be true + doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(ss).getNrState(); + doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(ss).getNrFrequencyRange(); + mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED, + TelephonyManager.NETWORK_TYPE_LTE); + mPhoneStateListener.onServiceStateChanged(ss); + + assertTrue(mConfig.nrIconDisplayGracePeriodMs > 0); + assertTrue(mMobileSignalController.mIsShowingIconGracefully); + } + + @Test + public void testNr5GIcon_displayGracePeriodTime_disabled() { + setupDefaultNr5GIconConfiguration(); + setupDefaultNr5GIconDisplayGracePeriodTime_disabled(); + setupDefaultSignal(); + + assertTrue(mConfig.nrIconDisplayGracePeriodMs == 0); + + // While nrIconDisplayGracePeriodMs <= 0, mIsShowingIconGracefully should be false + doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState(); + doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(mServiceState).getNrFrequencyRange(); + mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED, + TelephonyManager.NETWORK_TYPE_LTE); + + assertFalse(mMobileSignalController.mIsShowingIconGracefully); + } + + @Test + public void testNr5GIcon_enableDisplayGracePeriodTime_showIconGracefully() { + setupDefaultNr5GIconConfiguration(); + setupDefaultNr5GIconDisplayGracePeriodTime_enableThirtySeconds(); + setupDefaultSignal(); + mNetworkController.handleConfigurationChanged(); + mPhoneStateListener.onServiceStateChanged(mServiceState); + + ServiceState ss = Mockito.mock(ServiceState.class); + doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(ss).getNrState(); + doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(ss).getNrFrequencyRange(); + mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED, + TelephonyManager.NETWORK_TYPE_LTE); + mPhoneStateListener.onServiceStateChanged(ss); + + verifyDataIndicators(TelephonyIcons.ICON_5G); + + // Enabled timer Nr5G switch to None Nr5G, showing 5G icon gracefully + ServiceState ssLte = Mockito.mock(ServiceState.class); + doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(ssLte).getNrState(); + doReturn(ServiceState.FREQUENCY_RANGE_UNKNOWN).when(ssLte).getNrFrequencyRange(); + mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED, + TelephonyManager.NETWORK_TYPE_LTE); + mPhoneStateListener.onServiceStateChanged(ssLte); + + verifyDataIndicators(TelephonyIcons.ICON_5G); + } + + @Test + public void testNr5GIcon_disableDisplayGracePeriodTime_showLatestIconImmediately() { + setupDefaultNr5GIconConfiguration(); + setupDefaultNr5GIconDisplayGracePeriodTime_disabled(); + setupDefaultSignal(); + mNetworkController.handleConfigurationChanged(); + + doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState(); + doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(mServiceState).getNrFrequencyRange(); + mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED, + TelephonyManager.NETWORK_TYPE_LTE); + + verifyDataIndicators(TelephonyIcons.ICON_5G); + + doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(mServiceState).getNrState(); + doReturn(ServiceState.FREQUENCY_RANGE_UNKNOWN).when(mServiceState).getNrFrequencyRange(); + mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED, + TelephonyManager.NETWORK_TYPE_LTE); + + verifyDataIndicators(TelephonyIcons.ICON_LTE); + } + + @Test + public void testNr5GIcon_resetDisplayGracePeriodTime_whenDataDisconnected() { + setupDefaultNr5GIconConfiguration(); + setupDefaultNr5GIconDisplayGracePeriodTime_enableThirtySeconds(); + setupDefaultSignal(); + mNetworkController.handleConfigurationChanged(); + doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState(); + doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(mServiceState).getNrFrequencyRange(); + mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED, + TelephonyManager.NETWORK_TYPE_LTE); + + verifyDataIndicators(TelephonyIcons.ICON_5G); + + // Disabled timer, when out of service, reset timer to display latest state + updateDataConnectionState(TelephonyManager.DATA_CONNECTED, + TelephonyManager.NETWORK_TYPE_LTE); + doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(mServiceState).getNrState(); + doReturn(ServiceState.FREQUENCY_RANGE_UNKNOWN).when(mServiceState).getNrFrequencyRange(); + mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_DISCONNECTED, + TelephonyManager.NETWORK_TYPE_UMTS); + + verifyDataIndicators(0); + } + + @Test + public void testNr5GIcon_enableDisplayGracePeriodTime_show5G_switching_5GPlus() { + setupDefaultNr5GIconConfiguration(); + setupDefaultNr5GIconDisplayGracePeriodTime_enableThirtySeconds(); + setupDefaultSignal(); + mNetworkController.handleConfigurationChanged(); + mPhoneStateListener.onServiceStateChanged(mServiceState); + + ServiceState ss5G = Mockito.mock(ServiceState.class); + doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(ss5G).getNrState(); + doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(ss5G).getNrFrequencyRange(); + mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED, + TelephonyManager.NETWORK_TYPE_LTE); + mPhoneStateListener.onServiceStateChanged(ss5G); + + verifyDataIndicators(TelephonyIcons.ICON_5G); + + // When timeout enabled, 5G/5G+ switching should be updated immediately + ServiceState ss5GPlus = Mockito.mock(ServiceState.class); + doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(ss5GPlus).getNrState(); + doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(ss5GPlus).getNrFrequencyRange(); + mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED, + TelephonyManager.NETWORK_TYPE_LTE); + mPhoneStateListener.onServiceStateChanged(ss5GPlus); + + verifyDataIndicators(TelephonyIcons.ICON_5G_PLUS); + } + + @Test + public void testNr5GIcon_carrierDisabledDisplayGracePeriodTime_shouldUpdateIconImmediately() { + setupDefaultNr5GIconConfiguration(); + setupDefaultNr5GIconDisplayGracePeriodTime_enableThirtySeconds(); + setupDefaultSignal(); + mNetworkController.handleConfigurationChanged(); + mPhoneStateListener.onServiceStateChanged(mServiceState); + + ServiceState ss5G = Mockito.mock(ServiceState.class); + doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(ss5G).getNrState(); + doReturn(ServiceState.FREQUENCY_RANGE_HIGH).when(ss5G).getNrFrequencyRange(); + mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED, + TelephonyManager.NETWORK_TYPE_LTE); + mPhoneStateListener.onServiceStateChanged(ss5G); + + verifyDataIndicators(TelephonyIcons.ICON_5G); + + // State from NR_5G to NONE NR_5G with timeout, should show previous 5G icon + ServiceState ssLte = Mockito.mock(ServiceState.class); + doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(ssLte).getNrState(); + doReturn(ServiceState.FREQUENCY_RANGE_UNKNOWN).when(ssLte).getNrFrequencyRange(); + mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED, + TelephonyManager.NETWORK_TYPE_LTE); + mPhoneStateListener.onServiceStateChanged(ssLte); + + verifyDataIndicators(TelephonyIcons.ICON_5G); + + // Update nrIconDisplayGracePeriodMs to 0 + setupDefaultNr5GIconDisplayGracePeriodTime_disabled(); + mNetworkController.handleConfigurationChanged(); + + // State from NR_5G to NONE NR_STATE_RESTRICTED, showing corresponding icon + doReturn(NetworkRegistrationInfo.NR_STATE_RESTRICTED).when(mServiceState).getNrState(); + doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType(); + mPhoneStateListener.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED, + TelephonyManager.NETWORK_TYPE_LTE); + + assertTrue(mConfig.nrIconDisplayGracePeriodMs == 0); + verifyDataIndicators(TelephonyIcons.ICON_LTE); + } + + @Test public void testDataDisabledIcon_UserNotSetup() { setupNetworkController(); when(mMockTm.isDataCapable()).thenReturn(false); 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/packages/SystemUI/tools/lint/baseline.xml b/packages/SystemUI/tools/lint/baseline.xml index 8c43222894ec..096a63901b9d 100644 --- a/packages/SystemUI/tools/lint/baseline.xml +++ b/packages/SystemUI/tools/lint/baseline.xml @@ -2685,39 +2685,6 @@ <issue id="UnusedResources" - message="The resource `R.dimen.volume_dialog_base_margin` appears to be unused" - errorLine1=" <dimen name="volume_dialog_base_margin">8dp</dimen>" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="res/values/dimens.xml" - line="308" - column="12"/> - </issue> - - <issue - id="UnusedResources" - message="The resource `R.dimen.volume_dialog_row_height` appears to be unused" - errorLine1=" <dimen name="volume_dialog_row_height">252dp</dimen>" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="res/values/dimens.xml" - line="314" - column="12"/> - </issue> - - <issue - id="UnusedResources" - message="The resource `R.dimen.volume_dialog_settings_icon_size` appears to be unused" - errorLine1=" <dimen name="volume_dialog_settings_icon_size">16dp</dimen>" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="res/values/dimens.xml" - line="328" - column="12"/> - </issue> - - <issue - id="UnusedResources" message="The resource `R.dimen.carrier_label_height` appears to be unused" errorLine1=" <dimen name="carrier_label_height">24dp</dimen>" errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~"> diff --git a/services/accessibility/java/com/android/server/accessibility/GlobalActionPerformer.java b/services/accessibility/java/com/android/server/accessibility/GlobalActionPerformer.java index 672518cc17ed..b9b2654b93cc 100644 --- a/services/accessibility/java/com/android/server/accessibility/GlobalActionPerformer.java +++ b/services/accessibility/java/com/android/server/accessibility/GlobalActionPerformer.java @@ -24,10 +24,7 @@ import android.os.Binder; import android.os.Handler; import android.os.Looper; import android.os.PowerManager; -import android.os.RemoteException; -import android.os.ServiceManager; import android.os.SystemClock; -import android.view.IWindowManager; import android.view.InputDevice; import android.view.KeyCharacterMap; import android.view.KeyEvent; @@ -191,7 +188,7 @@ public class GlobalActionPerformer { ScreenshotHelper screenshotHelper = (mScreenshotHelperSupplier != null) ? mScreenshotHelperSupplier.get() : new ScreenshotHelper(mContext); screenshotHelper.takeScreenshot(android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN, - true, true, new Handler(Looper.getMainLooper())); + true, true, new Handler(Looper.getMainLooper()), null); return true; } } diff --git a/services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java b/services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java index d7e68f896c6c..5844f9873001 100644 --- a/services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java +++ b/services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java @@ -23,6 +23,7 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.UserIdInt; import android.app.prediction.AppPredictionContext; import android.app.prediction.AppPredictionSessionId; import android.app.prediction.AppTargetEvent; @@ -61,7 +62,8 @@ public class AppPredictionManagerService extends public AppPredictionManagerService(Context context) { super(context, new FrameworkResourcesServiceNameResolver(context, - com.android.internal.R.string.config_defaultAppPredictionService), null); + com.android.internal.R.string.config_defaultAppPredictionService), null, + PACKAGE_UPDATE_POLICY_NO_REFRESH | PACKAGE_RESTART_POLICY_NO_REFRESH); mActivityTaskManagerInternal = LocalServices.getService(ActivityTaskManagerInternal.class); } @@ -80,6 +82,22 @@ public class AppPredictionManagerService extends getContext().enforceCallingPermission(MANAGE_APP_PREDICTIONS, TAG); } + @Override // from AbstractMasterSystemService + protected void onServicePackageUpdatedLocked(@UserIdInt int userId) { + final AppPredictionPerUserService service = peekServiceForUserLocked(userId); + if (service != null) { + service.onPackageUpdatedLocked(); + } + } + + @Override // from AbstractMasterSystemService + protected void onServicePackageRestartedLocked(@UserIdInt int userId) { + final AppPredictionPerUserService service = peekServiceForUserLocked(userId); + if (service != null) { + service.onPackageRestartedLocked(); + } + } + @Override protected int getMaximumTemporaryServiceDurationMs() { return MAX_TEMP_SERVICE_DURATION_MS; diff --git a/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java b/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java index 03c4542a50d4..4f49fb7578a1 100644 --- a/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java +++ b/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java @@ -251,6 +251,40 @@ public class AppPredictionPerUserService extends // Do nothing, eventually the system will bind to the remote service again... } + void onPackageUpdatedLocked() { + if (isDebug()) { + Slog.v(TAG, "onPackageUpdatedLocked()"); + } + destroyAndRebindRemoteService(); + } + + void onPackageRestartedLocked() { + if (isDebug()) { + Slog.v(TAG, "onPackageRestartedLocked()"); + } + destroyAndRebindRemoteService(); + } + + private void destroyAndRebindRemoteService() { + if (mRemoteService == null) { + return; + } + + if (isDebug()) { + Slog.d(TAG, "Destroying the old remote service."); + } + mRemoteService.destroy(); + mRemoteService = null; + + mRemoteService = getRemoteServiceLocked(); + if (mRemoteService != null) { + if (isDebug()) { + Slog.d(TAG, "Rebinding to the new remote service."); + } + mRemoteService.reconnect(); + } + } + /** * Called after the remote service connected, it's used to restore state from a 'zombie' * service (i.e., after it died). diff --git a/services/appprediction/java/com/android/server/appprediction/RemoteAppPredictionService.java b/services/appprediction/java/com/android/server/appprediction/RemoteAppPredictionService.java index c82e7a012fff..04e0e7f7102f 100644 --- a/services/appprediction/java/com/android/server/appprediction/RemoteAppPredictionService.java +++ b/services/appprediction/java/com/android/server/appprediction/RemoteAppPredictionService.java @@ -135,6 +135,13 @@ public class RemoteAppPredictionService extends } /** + * Schedules a request to bind to the remote service. + */ + public void reconnect() { + super.scheduleBind(); + } + + /** * Failure callback */ public interface RemoteAppPredictionServiceCallbacks 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/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags index 4d39f9ab8d78..bec08f45188f 100644 --- a/services/core/java/com/android/server/EventLogTags.logtags +++ b/services/core/java/com/android/server/EventLogTags.logtags @@ -39,6 +39,12 @@ option java_package com.android.server 27391 user_activity_timeout_override (override|2|3) 27392 battery_saver_setting (threshold|1) + +# --------------------------- +# ThermalManagerService.java +# --------------------------- +2737 thermal_changed (name|3),(type|1|5),(temperature|5),(sensor_status|1|5),(previous_system_status|1|5) + # # Leave IDs through 2740 for more power logs (2730 used by battery_discharge above) # 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/accounts/AccountManagerServiceShellCommand.java b/services/core/java/com/android/server/accounts/AccountManagerServiceShellCommand.java index 9e5f7229d382..9bf0bd357f37 100644 --- a/services/core/java/com/android/server/accounts/AccountManagerServiceShellCommand.java +++ b/services/core/java/com/android/server/accounts/AccountManagerServiceShellCommand.java @@ -17,6 +17,7 @@ package com.android.server.accounts; import android.annotation.NonNull; +import android.app.ActivityManager; import android.os.ShellCommand; import android.os.UserHandle; @@ -83,7 +84,7 @@ final class AccountManagerServiceShellCommand extends ShellCommand { return null; } } - return UserHandle.USER_SYSTEM; + return ActivityManager.getCurrentUser(); } @Override @@ -92,9 +93,11 @@ final class AccountManagerServiceShellCommand extends ShellCommand { pw.println("Account manager service commands:"); pw.println(" help"); pw.println(" Print this help text."); - pw.println(" set-bind-instant-service-allowed [--user <USER_ID>] true|false "); + pw.println(" set-bind-instant-service-allowed " + + "[--user <USER_ID> (current user if not specified)] true|false "); pw.println(" Set whether binding to services provided by instant apps is allowed."); - pw.println(" get-bind-instant-service-allowed [--user <USER_ID>]"); + pw.println(" get-bind-instant-service-allowed " + + "[--user <USER_ID> (current user if not specified)]"); pw.println(" Get whether binding to services provided by instant apps is allowed."); } } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 60bc9aef644a..c410b8bd41c8 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -9023,7 +9023,16 @@ public class ActivityManagerService extends IActivityManager.Stub Integer.toString(currentUserId), currentUserId); mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, Integer.toString(currentUserId), currentUserId); - mSystemServiceManager.startUser(currentUserId); + + // On Automotive, at this point the system user has already been started and unlocked, + // and some of the tasks we do here have already been done. So skip those in that case. + // TODO(b/132262830): this workdound shouldn't be necessary once we move the + // headless-user start logic to UserManager-land + final boolean bootingSystemUser = currentUserId == UserHandle.USER_SYSTEM; + + if (bootingSystemUser) { + mSystemServiceManager.startUser(currentUserId); + } synchronized (this) { // Only start up encryption-aware persistent apps; once user is @@ -9047,43 +9056,53 @@ public class ActivityManagerService extends IActivityManager.Stub throw e.rethrowAsRuntimeException(); } } - mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady"); + + if (bootingSystemUser) { + mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady"); + } mAtmInternal.showSystemReadyErrorDialogsIfNeeded(); - final int callingUid = Binder.getCallingUid(); - final int callingPid = Binder.getCallingPid(); - long ident = Binder.clearCallingIdentity(); - try { - Intent intent = new Intent(Intent.ACTION_USER_STARTED); - intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY - | Intent.FLAG_RECEIVER_FOREGROUND); - intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId); - broadcastIntentLocked(null, null, intent, - null, null, 0, null, null, null, OP_NONE, - null, false, false, MY_PID, SYSTEM_UID, callingUid, callingPid, - currentUserId); - intent = new Intent(Intent.ACTION_USER_STARTING); - intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); - intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId); - broadcastIntentLocked(null, null, intent, - null, new IIntentReceiver.Stub() { - @Override - public void performReceive(Intent intent, int resultCode, String data, - Bundle extras, boolean ordered, boolean sticky, int sendingUser) - throws RemoteException { - } - }, 0, null, null, - new String[] {INTERACT_ACROSS_USERS}, OP_NONE, - null, true, false, MY_PID, SYSTEM_UID, callingUid, callingPid, - UserHandle.USER_ALL); - } catch (Throwable t) { - Slog.wtf(TAG, "Failed sending first user broadcasts", t); - } finally { - Binder.restoreCallingIdentity(ident); + if (bootingSystemUser) { + final int callingUid = Binder.getCallingUid(); + final int callingPid = Binder.getCallingPid(); + long ident = Binder.clearCallingIdentity(); + try { + Intent intent = new Intent(Intent.ACTION_USER_STARTED); + intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY + | Intent.FLAG_RECEIVER_FOREGROUND); + intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId); + broadcastIntentLocked(null, null, intent, + null, null, 0, null, null, null, OP_NONE, + null, false, false, MY_PID, SYSTEM_UID, callingUid, callingPid, + currentUserId); + intent = new Intent(Intent.ACTION_USER_STARTING); + intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); + intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId); + broadcastIntentLocked(null, null, intent, + null, new IIntentReceiver.Stub() { + @Override + public void performReceive(Intent intent, int resultCode, String data, + Bundle extras, boolean ordered, boolean sticky, int sendingUser) + throws RemoteException { + } + }, 0, null, null, + new String[] {INTERACT_ACROSS_USERS}, OP_NONE, + null, true, false, MY_PID, SYSTEM_UID, callingUid, callingPid, + UserHandle.USER_ALL); + } catch (Throwable t) { + Slog.wtf(TAG, "Failed sending first user broadcasts", t); + } finally { + Binder.restoreCallingIdentity(ident); + } + } else { + Slog.i(TAG, "Not sending multi-user broadcasts for non-system user " + + currentUserId); } mAtmInternal.resumeTopActivities(false /* scheduleIdle */); - mUserController.sendUserSwitchBroadcasts(-1, currentUserId); + if (bootingSystemUser) { + mUserController.sendUserSwitchBroadcasts(-1, currentUserId); + } BinderInternal.nSetBinderProxyCountWatermarks(BINDER_PROXY_HIGH_WATERMARK, BINDER_PROXY_LOW_WATERMARK); diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index c2f452932775..a47ea4f95b3e 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -722,10 +722,10 @@ public final class BatteryStatsService extends IBatteryStats.Stub } } - public void notePhoneDataConnectionState(int dataType, boolean hasData) { + public void notePhoneDataConnectionState(int dataType, boolean hasData, int serviceType) { enforceCallingPermission(); synchronized (mStats) { - mStats.notePhoneDataConnectionStateLocked(dataType, hasData); + mStats.notePhoneDataConnectionStateLocked(dataType, hasData, serviceType); } } @@ -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/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index b399971d1ad5..838e7d3c0208 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -2094,10 +2094,10 @@ public final class ProcessList { } } } - if (lrui <= mLruProcessActivityStart) { + if (lrui < mLruProcessActivityStart) { mLruProcessActivityStart--; } - if (lrui <= mLruProcessServiceStart) { + if (lrui < mLruProcessServiceStart) { mLruProcessServiceStart--; } mLruProcesses.remove(lrui); @@ -2629,7 +2629,7 @@ public final class ProcessList { if (!moved) { // Goes to the end of the group. mLruProcesses.remove(i); - mLruProcesses.add(endIndex - 1, subProc); + mLruProcesses.add(endIndex, subProc); if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving " + subProc + " from position " + i + " to end of group @ " @@ -2874,15 +2874,6 @@ public final class ProcessList { pos--; } mLruProcesses.add(pos, app); - if (pos == mLruProcessActivityStart) { - mLruProcessActivityStart++; - } - if (pos == mLruProcessServiceStart) { - // Unless {@code #hasService} is implemented, currently the starting position - // for activity and service are the same, so the incoming position may equal to - // the starting position of service. - mLruProcessServiceStart++; - } // If this process is part of a group, need to pull up any other processes // in that group to be with it. int endIndex = pos - 1; diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index 7569363a7134..b44904135736 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -2979,17 +2979,40 @@ public class AppOpsService extends IAppOpsService.Stub { out.startTag(null, "app-ops"); out.attribute(null, "v", String.valueOf(CURRENT_VERSION)); - final int uidStateCount = mUidStates.size(); - for (int i = 0; i < uidStateCount; i++) { - UidState uidState = mUidStates.valueAt(i); - if (uidState.opModes != null && uidState.opModes.size() > 0) { + SparseArray<SparseIntArray> uidStatesClone; + synchronized (this) { + uidStatesClone = new SparseArray<>(mUidStates.size()); + + final int uidStateCount = mUidStates.size(); + for (int uidStateNum = 0; uidStateNum < uidStateCount; uidStateNum++) { + UidState uidState = mUidStates.valueAt(uidStateNum); + int uid = mUidStates.keyAt(uidStateNum); + + SparseIntArray opModes = uidState.opModes; + if (opModes != null && opModes.size() > 0) { + uidStatesClone.put(uid, new SparseIntArray(opModes.size())); + + final int opCount = opModes.size(); + for (int opCountNum = 0; opCountNum < opCount; opCountNum++) { + uidStatesClone.get(uid).put( + opModes.keyAt(opCountNum), + opModes.valueAt(opCountNum)); + } + } + } + } + + final int uidStateCount = uidStatesClone.size(); + for (int uidStateNum = 0; uidStateNum < uidStateCount; uidStateNum++) { + SparseIntArray opModes = uidStatesClone.valueAt(uidStateNum); + if (opModes != null && opModes.size() > 0) { out.startTag(null, "uid"); - out.attribute(null, "n", Integer.toString(uidState.uid)); - SparseIntArray uidOpModes = uidState.opModes; - final int opCount = uidOpModes.size(); - for (int j = 0; j < opCount; j++) { - final int op = uidOpModes.keyAt(j); - final int mode = uidOpModes.valueAt(j); + out.attribute(null, "n", + Integer.toString(uidStatesClone.keyAt(uidStateNum))); + final int opCount = opModes.size(); + for (int opCountNum = 0; opCountNum < opCount; opCountNum++) { + final int op = opModes.keyAt(opCountNum); + final int mode = opModes.valueAt(opCountNum); out.startTag(null, "op"); out.attribute(null, "n", Integer.toString(op)); out.attribute(null, "m", Integer.toString(mode)); 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/connectivity/DataConnectionStats.java b/services/core/java/com/android/server/connectivity/DataConnectionStats.java index 227ab2341012..4990ea136246 100644 --- a/services/core/java/com/android/server/connectivity/DataConnectionStats.java +++ b/services/core/java/com/android/server/connectivity/DataConnectionStats.java @@ -91,7 +91,8 @@ public class DataConnectionStats extends BroadcastReceiver { if (DEBUG) Log.d(TAG, String.format("Noting data connection for network type %s: %svisible", networkType, visible ? "" : "not ")); try { - mBatteryStats.notePhoneDataConnectionState(networkType, visible); + mBatteryStats.notePhoneDataConnectionState(networkType, visible, + mServiceState.getState()); } catch (RemoteException e) { Log.w(TAG, "Error noting data connection state", e); } diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java index 500a24282191..1fc0db3ff7cb 100644 --- a/services/core/java/com/android/server/display/DisplayModeDirector.java +++ b/services/core/java/com/android/server/display/DisplayModeDirector.java @@ -766,6 +766,7 @@ public class DisplayModeDirector { @Override public void onDisplayChanged(int displayId) { updateDisplayModes(displayId); + mBrightnessObserver.onDisplayChanged(displayId); } private void updateDisplayModes(int displayId) { @@ -820,7 +821,6 @@ public class DisplayModeDirector { private AmbientFilter mAmbientFilter; private final Context mContext; - private final ScreenStateReceiver mScreenStateReceiver; // Enable light sensor only when mShouldObserveAmbientChange is true, screen is on, peak // refresh rate changeable and low power mode off. After initialization, these states will @@ -834,7 +834,6 @@ public class DisplayModeDirector { BrightnessObserver(Context context, Handler handler) { super(handler); mContext = context; - mScreenStateReceiver = new ScreenStateReceiver(mContext); mDisplayBrightnessThresholds = context.getResources().getIntArray( R.array.config_brightnessThresholdsOfPeakRefreshRate); mAmbientBrightnessThresholds = context.getResources().getIntArray( @@ -919,12 +918,16 @@ public class DisplayModeDirector { } } + public void onDisplayChanged(int displayId) { + if (displayId == Display.DEFAULT_DISPLAY) { + onScreenOn(isDefaultDisplayOn()); + } + } + @Override public void onChange(boolean selfChange, Uri uri, int userId) { synchronized (mLock) { - if (mRefreshRateChangeable) { - onBrightnessChangedLocked(); - } + onBrightnessChangedLocked(); } } @@ -970,16 +973,11 @@ public class DisplayModeDirector { mAmbientFilter = DisplayWhiteBalanceFactory.createBrightnessFilter(res); mLightSensor = lightSensor; - // Intent.ACTION_SCREEN_ON is not sticky. Check current screen status. - if (mContext.getSystemService(PowerManager.class).isInteractive()) { - onScreenOn(true); - } - mScreenStateReceiver.register(); + onScreenOn(isDefaultDisplayOn()); } } else { mAmbientFilter = null; mLightSensor = null; - mScreenStateReceiver.unregister(); } if (mRefreshRateChangeable) { @@ -1049,8 +1047,6 @@ public class DisplayModeDirector { } private void onScreenOn(boolean on) { - // Not check mShouldObserveAmbientChange because Screen status receiver is registered - // only when it is true. if (mScreenOn != on) { mScreenOn = on; updateSensorStatus(); @@ -1072,6 +1068,13 @@ public class DisplayModeDirector { } } + private boolean isDefaultDisplayOn() { + final Display display = mContext.getSystemService(DisplayManager.class) + .getDisplay(Display.DEFAULT_DISPLAY); + return display.getState() != Display.STATE_OFF + && mContext.getSystemService(PowerManager.class).isInteractive(); + } + private final class LightSensorEventListener implements SensorEventListener { final private static int INJECT_EVENTS_INTERVAL_MS = LIGHT_SENSOR_RATE_MS; private float mLastSensorData; @@ -1149,38 +1152,6 @@ public class DisplayModeDirector { } } }; - }; - - private final class ScreenStateReceiver extends BroadcastReceiver { - final Context mContext; - boolean mRegistered; - - public ScreenStateReceiver(Context context) { - mContext = context; - } - - @Override - public void onReceive(Context context, Intent intent) { - onScreenOn(Intent.ACTION_SCREEN_ON.equals(intent.getAction())); - } - - public void register() { - if (!mRegistered) { - IntentFilter filter = new IntentFilter(); - filter.addAction(Intent.ACTION_SCREEN_OFF); - filter.addAction(Intent.ACTION_SCREEN_ON); - filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); - mContext.registerReceiver(this, filter, null, mHandler); - mRegistered = true; - } - } - - public void unregister() { - if (mRegistered) { - mContext.unregisterReceiver(this); - mRegistered = false; - } - } } } diff --git a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java index 9782f30d3074..259527a5f217 100644 --- a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java +++ b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java @@ -79,7 +79,7 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem S extends AbstractPerUserSystemService<S, M>> extends SystemService { /** On a package update, does not refresh the per-user service in the cache. */ - public static final int PACKAGE_UPDATE_POLICY_NO_REFRESH = 0; + public static final int PACKAGE_UPDATE_POLICY_NO_REFRESH = 0x00000001; /** * On a package update, removes any existing per-user services in the cache. @@ -87,20 +87,40 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem * <p>This does not immediately recreate these services. It is assumed they will be recreated * for the next user request. */ - public static final int PACKAGE_UPDATE_POLICY_REFRESH_LAZY = 1; + public static final int PACKAGE_UPDATE_POLICY_REFRESH_LAZY = 0x00000002; /** * On a package update, removes and recreates any existing per-user services in the cache. */ - public static final int PACKAGE_UPDATE_POLICY_REFRESH_EAGER = 2; + public static final int PACKAGE_UPDATE_POLICY_REFRESH_EAGER = 0x00000004; - @IntDef(flag = true, prefix = { "PACKAGE_UPDATE_POLICY_" }, value = { + /** On a package restart, does not refresh the per-user service in the cache. */ + public static final int PACKAGE_RESTART_POLICY_NO_REFRESH = 0x00000010; + + /** + * On a package restart, removes any existing per-user services in the cache. + * + * <p>This does not immediately recreate these services. It is assumed they will be recreated + * for the next user request. + */ + public static final int PACKAGE_RESTART_POLICY_REFRESH_LAZY = 0x00000020; + + /** + * On a package restart, removes and recreates any existing per-user services in the cache. + */ + public static final int PACKAGE_RESTART_POLICY_REFRESH_EAGER = 0x00000040; + + @IntDef(flag = true, prefix = { "PACKAGE_" }, value = { PACKAGE_UPDATE_POLICY_NO_REFRESH, PACKAGE_UPDATE_POLICY_REFRESH_LAZY, - PACKAGE_UPDATE_POLICY_REFRESH_EAGER + PACKAGE_UPDATE_POLICY_REFRESH_EAGER, + PACKAGE_RESTART_POLICY_NO_REFRESH, + PACKAGE_RESTART_POLICY_REFRESH_LAZY, + PACKAGE_RESTART_POLICY_REFRESH_EAGER }) + @Retention(RetentionPolicy.SOURCE) - public @interface PackageUpdatePolicy {} + public @interface ServicePackagePolicyFlags {} /** * Log tag @@ -153,12 +173,10 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem private final SparseArray<S> mServicesCache = new SparseArray<>(); /** - * Whether the per-user service should be removed from the cache when its apk is updated. - * - * <p>One of {@link #PACKAGE_UPDATE_POLICY_NO_REFRESH}, - * {@link #PACKAGE_UPDATE_POLICY_REFRESH_LAZY} or {@link #PACKAGE_UPDATE_POLICY_REFRESH_EAGER}. + * Value that determines whether the per-user service should be removed from the cache when its + * apk is updated or restarted. */ - private final @PackageUpdatePolicy int mPackageUpdatePolicy; + private final @ServicePackagePolicyFlags int mServicePackagePolicyFlags; /** * Name of the service packages whose APK are being updated, keyed by user id. @@ -184,11 +202,11 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem @Nullable ServiceNameResolver serviceNameResolver, @Nullable String disallowProperty) { this(context, serviceNameResolver, disallowProperty, - /*packageUpdatePolicy=*/ PACKAGE_UPDATE_POLICY_REFRESH_LAZY); + PACKAGE_UPDATE_POLICY_REFRESH_LAZY | PACKAGE_RESTART_POLICY_REFRESH_LAZY); } /** - * Full constructor. + * Full Constructor. * * @param context system context. * @param serviceNameResolver resolver for @@ -197,19 +215,32 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem * @param disallowProperty when not {@code null}, defines a {@link UserManager} restriction that * disables the service. <b>NOTE: </b> you'll also need to add it to * {@code UserRestrictionsUtils.USER_RESTRICTIONS}. - * @param packageUpdatePolicy when {@link #PACKAGE_UPDATE_POLICY_REFRESH_LAZY}, the - * {@link AbstractPerUserSystemService} is removed from the cache when the service - * package is updated; when {@link #PACKAGE_UPDATE_POLICY_REFRESH_EAGER}, the - * {@link AbstractPerUserSystemService} is removed from the cache and immediately - * re-added when the service package is updated; when - * {@link #PACKAGE_UPDATE_POLICY_NO_REFRESH}, the service is untouched during the update. + * @param servicePackagePolicyFlags a combination of + * {@link #PACKAGE_UPDATE_POLICY_NO_REFRESH}, + * {@link #PACKAGE_UPDATE_POLICY_REFRESH_LAZY}, + * {@link #PACKAGE_UPDATE_POLICY_REFRESH_EAGER}, + * {@link #PACKAGE_RESTART_POLICY_NO_REFRESH}, + * {@link #PACKAGE_RESTART_POLICY_REFRESH_LAZY} or + * {@link #PACKAGE_RESTART_POLICY_REFRESH_EAGER} */ protected AbstractMasterSystemService(@NonNull Context context, - @Nullable ServiceNameResolver serviceNameResolver, - @Nullable String disallowProperty, @PackageUpdatePolicy int packageUpdatePolicy) { + @Nullable ServiceNameResolver serviceNameResolver, @Nullable String disallowProperty, + @ServicePackagePolicyFlags int servicePackagePolicyFlags) { super(context); - mPackageUpdatePolicy = packageUpdatePolicy; + final int updatePolicyMask = PACKAGE_UPDATE_POLICY_NO_REFRESH + | PACKAGE_UPDATE_POLICY_REFRESH_LAZY | PACKAGE_UPDATE_POLICY_REFRESH_EAGER; + if ((servicePackagePolicyFlags & updatePolicyMask) == 0) { + // If the package update policy is not set, add the default flag + servicePackagePolicyFlags |= PACKAGE_UPDATE_POLICY_REFRESH_LAZY; + } + final int restartPolicyMask = PACKAGE_RESTART_POLICY_NO_REFRESH + | PACKAGE_RESTART_POLICY_REFRESH_LAZY | PACKAGE_RESTART_POLICY_REFRESH_EAGER; + if ((servicePackagePolicyFlags & restartPolicyMask) == 0) { + // If the package restart policy is not set, add the default flag + servicePackagePolicyFlags |= PACKAGE_RESTART_POLICY_REFRESH_LAZY; + } + mServicePackagePolicyFlags = servicePackagePolicyFlags; mServiceNameResolver = serviceNameResolver; if (mServiceNameResolver != null) { @@ -606,6 +637,20 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem } /** + * Called after the package data that provides the service for the given user is cleared. + */ + protected void onServicePackageDataClearedLocked(@UserIdInt int userId) { + if (verbose) Slog.v(mTag, "onServicePackageDataCleared(" + userId + ")"); + } + + /** + * Called after the package that provides the service for the given user is restarted. + */ + protected void onServicePackageRestartedLocked(@UserIdInt int userId) { + if (verbose) Slog.v(mTag, "onServicePackageRestarted(" + userId + ")"); + } + + /** * Called after the service is removed from the cache. */ @SuppressWarnings("unused") @@ -677,7 +722,7 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem final int size = mServicesCache.size(); pw.print(prefix); pw.print("Debug: "); pw.print(realDebug); pw.print(" Verbose: "); pw.println(realVerbose); - pw.print("Refresh on package update: "); pw.println(mPackageUpdatePolicy); + pw.print("Package policy flags: "); pw.println(mServicePackagePolicyFlags); if (mUpdatingPackageNames != null) { pw.print("Packages being updated: "); pw.println(mUpdatingPackageNames); } @@ -733,7 +778,12 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem } mUpdatingPackageNames.put(userId, packageName); onServicePackageUpdatingLocked(userId); - if (mPackageUpdatePolicy != PACKAGE_UPDATE_POLICY_NO_REFRESH) { + if ((mServicePackagePolicyFlags & PACKAGE_UPDATE_POLICY_NO_REFRESH) != 0) { + if (debug) { + Slog.d(mTag, "Holding service for user " + userId + " while package " + + activePackageName + " is being updated"); + } + } else { if (debug) { Slog.d(mTag, "Removing service for user " + userId + " because package " + activePackageName @@ -741,18 +791,14 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem } removeCachedServiceLocked(userId); - if (mPackageUpdatePolicy == PACKAGE_UPDATE_POLICY_REFRESH_EAGER) { + if ((mServicePackagePolicyFlags & PACKAGE_UPDATE_POLICY_REFRESH_EAGER) + != 0) { if (debug) { Slog.d(mTag, "Eagerly recreating service for user " + userId); } getServiceForUserLocked(userId); } - } else { - if (debug) { - Slog.d(mTag, "Holding service for user " + userId + " while package " - + activePackageName + " is being updated"); - } } } } @@ -804,7 +850,13 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem if (!doit) { return true; } - removeCachedServiceLocked(getChangingUserId()); + final String action = intent.getAction(); + final int userId = getChangingUserId(); + if (Intent.ACTION_PACKAGE_RESTARTED.equals(action)) { + handleActiveServiceRestartedLocked(activePackageName, userId); + } else { + removeCachedServiceLocked(userId); + } } else { handlePackageUpdateLocked(pkg); } @@ -813,6 +865,23 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem return false; } + @Override + public void onPackageDataCleared(String packageName, int uid) { + if (verbose) Slog.v(mTag, "onPackageDataCleared(): " + packageName); + final int userId = getChangingUserId(); + synchronized (mLock) { + final S service = peekServiceForUserLocked(userId); + if (service != null) { + final ComponentName componentName = service.getServiceComponentName(); + if (componentName != null) { + if (packageName.equals(componentName.getPackageName())) { + onServicePackageDataClearedLocked(userId); + } + } + } + } + } + private void handleActiveServiceRemoved(@UserIdInt int userId) { synchronized (mLock) { removeCachedServiceLocked(userId); @@ -824,6 +893,31 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem } } + private void handleActiveServiceRestartedLocked(String activePackageName, + @UserIdInt int userId) { + if ((mServicePackagePolicyFlags & PACKAGE_RESTART_POLICY_NO_REFRESH) != 0) { + if (debug) { + Slog.d(mTag, "Holding service for user " + userId + " while package " + + activePackageName + " is being restarted"); + } + } else { + if (debug) { + Slog.d(mTag, "Removing service for user " + userId + + " because package " + activePackageName + + " is being restarted"); + } + removeCachedServiceLocked(userId); + + if ((mServicePackagePolicyFlags & PACKAGE_RESTART_POLICY_REFRESH_EAGER) != 0) { + if (debug) { + Slog.d(mTag, "Eagerly recreating service for user " + userId); + } + getServiceForUserLocked(userId); + } + } + onServicePackageRestartedLocked(userId); + } + private String getActiveServicePackageNameLocked() { final int userId = getChangingUserId(); final S service = peekServiceForUserLocked(userId); diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java index 4a6eb276bd02..4828bbfff676 100644 --- a/services/core/java/com/android/server/notification/ManagedServices.java +++ b/services/core/java/com/android/server/notification/ManagedServices.java @@ -196,18 +196,20 @@ abstract public class ManagedServices { public void dump(PrintWriter pw, DumpFilter filter) { pw.println(" Allowed " + getCaption() + "s:"); - final int N = mApproved.size(); - for (int i = 0 ; i < N; i++) { - final int userId = mApproved.keyAt(i); - final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.valueAt(i); - if (approvedByType != null) { - final int M = approvedByType.size(); - for (int j = 0; j < M; j++) { - final boolean isPrimary = approvedByType.keyAt(j); - final ArraySet<String> approved = approvedByType.valueAt(j); - if (approvedByType != null && approvedByType.size() > 0) { - pw.println(" " + String.join(ENABLED_SERVICES_SEPARATOR, approved) - + " (user: " + userId + " isPrimary: " + isPrimary + ")"); + synchronized (mApproved) { + final int N = mApproved.size(); + for (int i = 0; i < N; i++) { + final int userId = mApproved.keyAt(i); + final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.valueAt(i); + if (approvedByType != null) { + final int M = approvedByType.size(); + for (int j = 0; j < M; j++) { + final boolean isPrimary = approvedByType.keyAt(j); + final ArraySet<String> approved = approvedByType.valueAt(j); + if (approvedByType != null && approvedByType.size() > 0) { + pw.println(" " + String.join(ENABLED_SERVICES_SEPARATOR, approved) + + " (user: " + userId + " isPrimary: " + isPrimary + ")"); + } } } } @@ -240,23 +242,25 @@ abstract public class ManagedServices { public void dump(ProtoOutputStream proto, DumpFilter filter) { proto.write(ManagedServicesProto.CAPTION, getCaption()); - final int N = mApproved.size(); - for (int i = 0 ; i < N; i++) { - final int userId = mApproved.keyAt(i); - final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.valueAt(i); - if (approvedByType != null) { - final int M = approvedByType.size(); - for (int j = 0; j < M; j++) { - final boolean isPrimary = approvedByType.keyAt(j); - final ArraySet<String> approved = approvedByType.valueAt(j); - if (approvedByType != null && approvedByType.size() > 0) { - final long sToken = proto.start(ManagedServicesProto.APPROVED); - for (String s : approved) { - proto.write(ServiceProto.NAME, s); + synchronized (mApproved) { + final int N = mApproved.size(); + for (int i = 0; i < N; i++) { + final int userId = mApproved.keyAt(i); + final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.valueAt(i); + if (approvedByType != null) { + final int M = approvedByType.size(); + for (int j = 0; j < M; j++) { + final boolean isPrimary = approvedByType.keyAt(j); + final ArraySet<String> approved = approvedByType.valueAt(j); + if (approvedByType != null && approvedByType.size() > 0) { + final long sToken = proto.start(ManagedServicesProto.APPROVED); + for (String s : approved) { + proto.write(ServiceProto.NAME, s); + } + proto.write(ServiceProto.USER_ID, userId); + proto.write(ServiceProto.IS_PRIMARY, isPrimary); + proto.end(sToken); } - proto.write(ServiceProto.USER_ID, userId); - proto.write(ServiceProto.IS_PRIMARY, isPrimary); - proto.end(sToken); } } } @@ -315,33 +319,36 @@ abstract public class ManagedServices { trimApprovedListsAccordingToInstalledServices(userId); } - final int N = mApproved.size(); - for (int i = 0 ; i < N; i++) { - final int approvedUserId = mApproved.keyAt(i); - if (forBackup && approvedUserId != userId) { - continue; - } - final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.valueAt(i); - if (approvedByType != null) { - final int M = approvedByType.size(); - for (int j = 0; j < M; j++) { - final boolean isPrimary = approvedByType.keyAt(j); - final Set<String> approved = approvedByType.valueAt(j); - if (approved != null) { - String allowedItems = String.join(ENABLED_SERVICES_SEPARATOR, approved); - out.startTag(null, TAG_MANAGED_SERVICES); - out.attribute(null, ATT_APPROVED_LIST, allowedItems); - out.attribute(null, ATT_USER_ID, Integer.toString(approvedUserId)); - out.attribute(null, ATT_IS_PRIMARY, Boolean.toString(isPrimary)); - writeExtraAttributes(out, approvedUserId); - out.endTag(null, TAG_MANAGED_SERVICES); - - if (!forBackup && isPrimary) { - // Also write values to settings, for observers who haven't migrated yet - Settings.Secure.putStringForUser(mContext.getContentResolver(), - getConfig().secureSettingName, allowedItems, approvedUserId); - } + synchronized (mApproved) { + final int N = mApproved.size(); + for (int i = 0; i < N; i++) { + final int approvedUserId = mApproved.keyAt(i); + if (forBackup && approvedUserId != userId) { + continue; + } + final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.valueAt(i); + if (approvedByType != null) { + final int M = approvedByType.size(); + for (int j = 0; j < M; j++) { + final boolean isPrimary = approvedByType.keyAt(j); + final Set<String> approved = approvedByType.valueAt(j); + if (approved != null) { + String allowedItems = String.join(ENABLED_SERVICES_SEPARATOR, approved); + out.startTag(null, TAG_MANAGED_SERVICES); + out.attribute(null, ATT_APPROVED_LIST, allowedItems); + out.attribute(null, ATT_USER_ID, Integer.toString(approvedUserId)); + out.attribute(null, ATT_IS_PRIMARY, Boolean.toString(isPrimary)); + writeExtraAttributes(out, approvedUserId); + out.endTag(null, TAG_MANAGED_SERVICES); + + if (!forBackup && isPrimary) { + // Also write values to settings, for observers who haven't migrated yet + Settings.Secure.putStringForUser(mContext.getContentResolver(), + getConfig().secureSettingName, allowedItems, + approvedUserId); + } + } } } } @@ -440,23 +447,25 @@ abstract public class ManagedServices { if (TextUtils.isEmpty(approved)) { approved = ""; } - ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.get(userId); - if (approvedByType == null) { - approvedByType = new ArrayMap<>(); - mApproved.put(userId, approvedByType); - } + synchronized (mApproved) { + ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.get(userId); + if (approvedByType == null) { + approvedByType = new ArrayMap<>(); + mApproved.put(userId, approvedByType); + } - ArraySet<String> approvedList = approvedByType.get(isPrimary); - if (approvedList == null) { - approvedList = new ArraySet<>(); - approvedByType.put(isPrimary, approvedList); - } + ArraySet<String> approvedList = approvedByType.get(isPrimary); + if (approvedList == null) { + approvedList = new ArraySet<>(); + approvedByType.put(isPrimary, approvedList); + } - String[] approvedArray = approved.split(ENABLED_SERVICES_SEPARATOR); - for (String pkgOrComponent : approvedArray) { - String approvedItem = getApprovedValue(pkgOrComponent); - if (approvedItem != null) { - approvedList.add(approvedItem); + String[] approvedArray = approved.split(ENABLED_SERVICES_SEPARATOR); + for (String pkgOrComponent : approvedArray) { + String approvedItem = getApprovedValue(pkgOrComponent); + if (approvedItem != null) { + approvedList.add(approvedItem); + } } } } @@ -469,23 +478,25 @@ abstract public class ManagedServices { boolean isPrimary, boolean enabled) { Slog.i(TAG, (enabled ? " Allowing " : "Disallowing ") + mConfig.caption + " " + pkgOrComponent); - ArrayMap<Boolean, ArraySet<String>> allowedByType = mApproved.get(userId); - if (allowedByType == null) { - allowedByType = new ArrayMap<>(); - mApproved.put(userId, allowedByType); - } - ArraySet<String> approved = allowedByType.get(isPrimary); - if (approved == null) { - approved = new ArraySet<>(); - allowedByType.put(isPrimary, approved); - } - String approvedItem = getApprovedValue(pkgOrComponent); - - if (approvedItem != null) { - if (enabled) { - approved.add(approvedItem); - } else { - approved.remove(approvedItem); + synchronized (mApproved) { + ArrayMap<Boolean, ArraySet<String>> allowedByType = mApproved.get(userId); + if (allowedByType == null) { + allowedByType = new ArrayMap<>(); + mApproved.put(userId, allowedByType); + } + ArraySet<String> approved = allowedByType.get(isPrimary); + if (approved == null) { + approved = new ArraySet<>(); + allowedByType.put(isPrimary, approved); + } + String approvedItem = getApprovedValue(pkgOrComponent); + + if (approvedItem != null) { + if (enabled) { + approved.add(approvedItem); + } else { + approved.remove(approvedItem); + } } } @@ -504,22 +515,26 @@ abstract public class ManagedServices { } protected String getApproved(int userId, boolean primary) { - final ArrayMap<Boolean, ArraySet<String>> allowedByType = - mApproved.getOrDefault(userId, new ArrayMap<>()); - ArraySet<String> approved = allowedByType.getOrDefault(primary, new ArraySet<>()); - return String.join(ENABLED_SERVICES_SEPARATOR, approved); + synchronized (mApproved) { + final ArrayMap<Boolean, ArraySet<String>> allowedByType = + mApproved.getOrDefault(userId, new ArrayMap<>()); + ArraySet<String> approved = allowedByType.getOrDefault(primary, new ArraySet<>()); + return String.join(ENABLED_SERVICES_SEPARATOR, approved); + } } protected List<ComponentName> getAllowedComponents(int userId) { final List<ComponentName> allowedComponents = new ArrayList<>(); - final ArrayMap<Boolean, ArraySet<String>> allowedByType = - mApproved.getOrDefault(userId, new ArrayMap<>()); - for (int i = 0; i < allowedByType.size(); i++) { - final ArraySet<String> allowed = allowedByType.valueAt(i); - for (int j = 0; j < allowed.size(); j++) { - ComponentName cn = ComponentName.unflattenFromString(allowed.valueAt(j)); - if (cn != null) { - allowedComponents.add(cn); + synchronized (mApproved) { + final ArrayMap<Boolean, ArraySet<String>> allowedByType = + mApproved.getOrDefault(userId, new ArrayMap<>()); + for (int i = 0; i < allowedByType.size(); i++) { + final ArraySet<String> allowed = allowedByType.valueAt(i); + for (int j = 0; j < allowed.size(); j++) { + ComponentName cn = ComponentName.unflattenFromString(allowed.valueAt(j)); + if (cn != null) { + allowedComponents.add(cn); + } } } } @@ -528,14 +543,16 @@ abstract public class ManagedServices { protected List<String> getAllowedPackages(int userId) { final List<String> allowedPackages = new ArrayList<>(); - final ArrayMap<Boolean, ArraySet<String>> allowedByType = - mApproved.getOrDefault(userId, new ArrayMap<>()); - for (int i = 0; i < allowedByType.size(); i++) { - final ArraySet<String> allowed = allowedByType.valueAt(i); - for (int j = 0; j < allowed.size(); j++) { - String pkgName = getPackageName(allowed.valueAt(j)); - if (!TextUtils.isEmpty(pkgName)) { - allowedPackages.add(pkgName); + synchronized (mApproved) { + final ArrayMap<Boolean, ArraySet<String>> allowedByType = + mApproved.getOrDefault(userId, new ArrayMap<>()); + for (int i = 0; i < allowedByType.size(); i++) { + final ArraySet<String> allowed = allowedByType.valueAt(i); + for (int j = 0; j < allowed.size(); j++) { + String pkgName = getPackageName(allowed.valueAt(j)); + if (!TextUtils.isEmpty(pkgName)) { + allowedPackages.add(pkgName); + } } } } @@ -543,12 +560,14 @@ abstract public class ManagedServices { } protected boolean isPackageOrComponentAllowed(String pkgOrComponent, int userId) { - ArrayMap<Boolean, ArraySet<String>> allowedByType = - mApproved.getOrDefault(userId, new ArrayMap<>()); - for (int i = 0; i < allowedByType.size(); i++) { - ArraySet<String> allowed = allowedByType.valueAt(i); - if (allowed.contains(pkgOrComponent)) { - return true; + synchronized (mApproved) { + ArrayMap<Boolean, ArraySet<String>> allowedByType = + mApproved.getOrDefault(userId, new ArrayMap<>()); + for (int i = 0; i < allowedByType.size(); i++) { + ArraySet<String> allowed = allowedByType.valueAt(i); + if (allowed.contains(pkgOrComponent)) { + return true; + } } } return false; @@ -558,19 +577,21 @@ abstract public class ManagedServices { if (pkg == null) { return false; } - ArrayMap<Boolean, ArraySet<String>> allowedByType = - mApproved.getOrDefault(userId, new ArrayMap<>()); - for (int i = 0; i < allowedByType.size(); i++) { - ArraySet<String> allowed = allowedByType.valueAt(i); - for (String allowedEntry : allowed) { - ComponentName component = ComponentName.unflattenFromString(allowedEntry); - if (component != null) { - if (pkg.equals(component.getPackageName())) { - return true; - } - } else { - if (pkg.equals(allowedEntry)) { - return true; + synchronized (mApproved) { + ArrayMap<Boolean, ArraySet<String>> allowedByType = + mApproved.getOrDefault(userId, new ArrayMap<>()); + for (int i = 0; i < allowedByType.size(); i++) { + ArraySet<String> allowed = allowedByType.valueAt(i); + for (String allowedEntry : allowed) { + ComponentName component = ComponentName.unflattenFromString(allowedEntry); + if (component != null) { + if (pkg.equals(component.getPackageName())) { + return true; + } + } else { + if (pkg.equals(allowedEntry)) { + return true; + } } } } @@ -616,7 +637,9 @@ abstract public class ManagedServices { public void onUserRemoved(int user) { Slog.i(TAG, "Removing approved services for removed user " + user); - mApproved.remove(user); + synchronized (mApproved) { + mApproved.remove(user); + } rebindServices(true, user); } @@ -797,14 +820,16 @@ abstract public class ManagedServices { protected Set<String> getAllowedPackages() { final Set<String> allowedPackages = new ArraySet<>(); - for (int k = 0; k < mApproved.size(); k++) { - ArrayMap<Boolean, ArraySet<String>> allowedByType = mApproved.valueAt(k); - for (int i = 0; i < allowedByType.size(); i++) { - final ArraySet<String> allowed = allowedByType.valueAt(i); - for (int j = 0; j < allowed.size(); j++) { - String pkgName = getPackageName(allowed.valueAt(j)); - if (!TextUtils.isEmpty(pkgName)) { - allowedPackages.add(pkgName); + synchronized (mApproved) { + for (int k = 0; k < mApproved.size(); k++) { + ArrayMap<Boolean, ArraySet<String>> allowedByType = mApproved.valueAt(k); + for (int i = 0; i < allowedByType.size(); i++) { + final ArraySet<String> allowed = allowedByType.valueAt(i); + for (int j = 0; j < allowed.size(); j++) { + String pkgName = getPackageName(allowed.valueAt(j)); + if (!TextUtils.isEmpty(pkgName)) { + allowedPackages.add(pkgName); + } } } } @@ -813,22 +838,24 @@ abstract public class ManagedServices { } private void trimApprovedListsAccordingToInstalledServices(int userId) { - final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.get(userId); - if (approvedByType == null) { - return; - } - for (int i = 0; i < approvedByType.size(); i++) { - final ArraySet<String> approved = approvedByType.valueAt(i); - for (int j = approved.size() - 1; j >= 0; j--) { - final String approvedPackageOrComponent = approved.valueAt(j); - if (!isValidEntry(approvedPackageOrComponent, userId)){ - approved.removeAt(j); - Slog.v(TAG, "Removing " + approvedPackageOrComponent - + " from approved list; no matching services found"); - } else { - if (DEBUG) { - Slog.v(TAG, "Keeping " + approvedPackageOrComponent - + " on approved list; matching services found"); + synchronized (mApproved) { + final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.get(userId); + if (approvedByType == null) { + return; + } + for (int i = 0; i < approvedByType.size(); i++) { + final ArraySet<String> approved = approvedByType.valueAt(i); + for (int j = approved.size() - 1; j >= 0; j--) { + final String approvedPackageOrComponent = approved.valueAt(j); + if (!isValidEntry(approvedPackageOrComponent, userId)) { + approved.removeAt(j); + Slog.v(TAG, "Removing " + approvedPackageOrComponent + + " from approved list; no matching services found"); + } else { + if (DEBUG) { + Slog.v(TAG, "Keeping " + approvedPackageOrComponent + + " on approved list; matching services found"); + } } } } @@ -837,20 +864,23 @@ abstract public class ManagedServices { private boolean removeUninstalledItemsFromApprovedLists(int uninstalledUserId, String pkg) { boolean removed = false; - final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.get(uninstalledUserId); - if (approvedByType != null) { - int M = approvedByType.size(); - for (int j = 0; j < M; j++) { - final ArraySet<String> approved = approvedByType.valueAt(j); - int O = approved.size(); - for (int k = O - 1; k >= 0; k--) { - final String packageOrComponent = approved.valueAt(k); - final String packageName = getPackageName(packageOrComponent); - if (TextUtils.equals(pkg, packageName)) { - approved.removeAt(k); - if (DEBUG) { - Slog.v(TAG, "Removing " + packageOrComponent - + " from approved list; uninstalled"); + synchronized (mApproved) { + final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.get( + uninstalledUserId); + if (approvedByType != null) { + int M = approvedByType.size(); + for (int j = 0; j < M; j++) { + final ArraySet<String> approved = approvedByType.valueAt(j); + int O = approved.size(); + for (int k = O - 1; k >= 0; k--) { + final String packageOrComponent = approved.valueAt(k); + final String packageName = getPackageName(packageOrComponent); + if (TextUtils.equals(pkg, packageName)) { + approved.removeAt(k); + if (DEBUG) { + Slog.v(TAG, "Removing " + packageOrComponent + + " from approved list; uninstalled"); + } } } } @@ -887,17 +917,19 @@ abstract public class ManagedServices { for (int i = 0; i < nUserIds; ++i) { final int userId = userIds.get(i); - final ArrayMap<Boolean, ArraySet<String>> approvedLists = mApproved.get(userId); - if (approvedLists != null) { - final int N = approvedLists.size(); - for (int j = 0; j < N; j++) { - ArraySet<ComponentName> approvedByUser = componentsByUser.get(userId); - if (approvedByUser == null) { - approvedByUser = new ArraySet<>(); - componentsByUser.put(userId, approvedByUser); + synchronized (mApproved) { + final ArrayMap<Boolean, ArraySet<String>> approvedLists = mApproved.get(userId); + if (approvedLists != null) { + final int N = approvedLists.size(); + for (int j = 0; j < N; j++) { + ArraySet<ComponentName> approvedByUser = componentsByUser.get(userId); + if (approvedByUser == null) { + approvedByUser = new ArraySet<>(); + componentsByUser.put(userId, approvedByUser); + } + approvedByUser.addAll( + loadComponentNamesFromValues(approvedLists.valueAt(j), userId)); } - approvedByUser.addAll( - loadComponentNamesFromValues(approvedLists.valueAt(j), userId)); } } } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index d358f9a1a553..c0b26467da08 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -466,6 +466,8 @@ public class NotificationManagerService extends SystemService { private MetricsLogger mMetricsLogger; private TriPredicate<String, Integer, String> mAllowedManagedServicePackages; + private final SavePolicyFileRunnable mSavePolicyFile = new SavePolicyFileRunnable(); + private static class Archive { final int mBufferSize; final ArrayDeque<StatusBarNotification> mBuffer; @@ -659,7 +661,14 @@ public class NotificationManagerService extends SystemService { @VisibleForTesting protected void handleSavePolicyFile() { - IoThread.getHandler().post(() -> { + if (!IoThread.getHandler().hasCallbacks(mSavePolicyFile)) { + IoThread.getHandler().post(mSavePolicyFile); + } + } + + private final class SavePolicyFileRunnable implements Runnable { + @Override + public void run() { if (DBG) Slog.d(TAG, "handleSavePolicyFile"); synchronized (mPolicyFile) { final FileOutputStream stream; @@ -679,7 +688,7 @@ public class NotificationManagerService extends SystemService { } } BackupManager.dataChanged(getContext().getPackageName()); - }); + } } private void writePolicyXml(OutputStream stream, boolean forBackup, int userId) @@ -1824,6 +1833,7 @@ public class NotificationManagerService extends SystemService { } if (properties.getKeyset() .contains(SystemUiDeviceConfigFlags.NAS_DEFAULT_SERVICE)) { + mAssistants.allowAdjustmentType(Adjustment.KEY_IMPORTANCE); mAssistants.resetDefaultAssistantsIfNecessary(); } }); @@ -2256,7 +2266,7 @@ public class NotificationManagerService extends SystemService { final int callingUid = Binder.getCallingUid(); final boolean isSystemToast = isCallerSystemOrPhone() || PackageManagerService.PLATFORM_PACKAGE_NAME.equals(pkg); - final boolean isPackageSuspended = isPackageSuspendedForUser(pkg, callingUid); + final boolean isPackageSuspended = isPackagePaused(pkg); final boolean notificationsDisabledForPackage = !areNotificationsEnabledForPackage(pkg, callingUid); @@ -2405,9 +2415,25 @@ public class NotificationManagerService extends SystemService { } @Override + public void silenceNotificationSound() { + checkCallerIsSystem(); + + mNotificationDelegate.clearEffects(); + } + + @Override public void setNotificationsEnabledForPackage(String pkg, int uid, boolean enabled) { enforceSystemOrSystemUI("setNotificationsEnabledForPackage"); + synchronized (mNotificationLock) { + boolean wasEnabled = mPreferencesHelper.getImportance(pkg, uid) + != NotificationManager.IMPORTANCE_NONE; + + if (wasEnabled == enabled) { + return; + } + } + mPreferencesHelper.setEnabled(pkg, uid, enabled); mMetricsLogger.write(new LogMaker(MetricsEvent.ACTION_BAN_APP_NOTES) .setType(MetricsEvent.TYPE_ACTION) @@ -4094,17 +4120,7 @@ public class NotificationManagerService extends SystemService { Preconditions.checkNotNull(pkg); checkCallerIsSameApp(pkg); - boolean isPaused; - - final PackageManagerInternal pmi = LocalServices.getService( - PackageManagerInternal.class); - int flags = pmi.getDistractingPackageRestrictions( - pkg, Binder.getCallingUserHandle().getIdentifier()); - isPaused = ((flags & PackageManager.RESTRICTION_HIDE_NOTIFICATIONS) != 0); - - isPaused |= isPackageSuspendedForUser(pkg, Binder.getCallingUid()); - - return isPaused; + return isPackagePausedOrSuspended(pkg, Binder.getCallingUid()); } private void verifyPrivilegedListener(INotificationListener token, UserHandle user, @@ -5220,8 +5236,16 @@ public class NotificationManagerService extends SystemService { } synchronized (mNotificationLock) { - // Look for the notification, searching both the posted and enqueued lists. - NotificationRecord r = findNotificationLocked(mPkg, mTag, mId, mUserId); + // If the notification is currently enqueued, repost this runnable so it has a + // chance to notify listeners + if ((findNotificationByListLocked(mEnqueuedNotifications, mPkg, mTag, mId, mUserId)) + != null) { + mHandler.post(this); + return; + } + // Look for the notification in the posted list, since we already checked enqueued. + NotificationRecord r = + findNotificationByListLocked(mNotificationList, mPkg, mTag, mId, mUserId); if (r != null) { // The notification was found, check if it should be removed. @@ -5326,11 +5350,18 @@ public class NotificationManagerService extends SystemService { } @GuardedBy("mNotificationLock") - private boolean isPackageSuspendedLocked(NotificationRecord r) { - final String pkg = r.sbn.getPackageName(); - final int callingUid = r.sbn.getUid(); + boolean isPackagePausedOrSuspended(String pkg, int uid) { + boolean isPaused; + + final PackageManagerInternal pmi = LocalServices.getService( + PackageManagerInternal.class); + int flags = pmi.getDistractingPackageRestrictions( + pkg, Binder.getCallingUserHandle().getIdentifier()); + isPaused = ((flags & PackageManager.RESTRICTION_HIDE_NOTIFICATIONS) != 0); + + isPaused |= isPackageSuspendedForUser(pkg, uid); - return isPackageSuspendedForUser(pkg, callingUid); + return isPaused; } protected class PostNotificationRunnable implements Runnable { @@ -5363,7 +5394,8 @@ public class NotificationManagerService extends SystemService { return; } - final boolean isPackageSuspended = isPackageSuspendedLocked(r); + final boolean isPackageSuspended = + isPackagePausedOrSuspended(r.sbn.getPackageName(), r.getUid()); r.setHidden(isPackageSuspended); if (isPackageSuspended) { mUsageStats.registerSuspendedByAdmin(r); diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java index 7b45a1b1997c..e4c5f3dcc713 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 = 50000; + + @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/notification/ZenLog.java b/services/core/java/com/android/server/notification/ZenLog.java index c6af7566a8bd..8f05636eed9c 100644 --- a/services/core/java/com/android/server/notification/ZenLog.java +++ b/services/core/java/com/android/server/notification/ZenLog.java @@ -179,6 +179,7 @@ public class ZenLog { case TYPE_SUPPRESSOR_CHANGED: return "suppressor_changed"; case TYPE_LISTENER_HINTS_CHANGED: return "listener_hints_changed"; case TYPE_SET_NOTIFICATION_POLICY: return "set_notification_policy"; + case TYPE_SET_CONSOLIDATED_ZEN_POLICY: return "set_consolidated_policy"; default: return "unknown"; } } diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index f81015dae468..ebc41916d034 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -942,12 +942,11 @@ public class ZenModeHelper { } private void applyCustomPolicy(ZenPolicy policy, ZenRule rule) { - if (rule.zenMode == NotificationManager.INTERRUPTION_FILTER_NONE) { + if (rule.zenMode == Global.ZEN_MODE_NO_INTERRUPTIONS) { policy.apply(new ZenPolicy.Builder() .disallowAllSounds() .build()); - } else if (rule.zenMode - == NotificationManager.INTERRUPTION_FILTER_ALARMS) { + } else if (rule.zenMode == Global.ZEN_MODE_ALARMS) { policy.apply(new ZenPolicy.Builder() .disallowAllSounds() .allowAlarms(true) diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java index da69986cd59f..965ddc9f2782 100644 --- a/services/core/java/com/android/server/om/OverlayManagerService.java +++ b/services/core/java/com/android/server/om/OverlayManagerService.java @@ -751,7 +751,7 @@ public final class OverlayManagerService extends SystemService { @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { final DumpState dumpState = new DumpState(); - dumpState.setUserId(UserHandle.getUserId(Binder.getCallingUid())); + dumpState.setUserId(UserHandle.USER_ALL); int opti = 0; while (opti < args.length) { @@ -771,13 +771,13 @@ public final class OverlayManagerService extends SystemService { pw.println(" so the following are equivalent: mState, mstate, State, state."); return; } else if ("--user".equals(opt)) { - opti++; if (opti >= args.length) { pw.println("Error: user missing argument"); return; } try { dumpState.setUserId(Integer.parseInt(args[opti])); + opti++; } catch (NumberFormatException e) { pw.println("Error: user argument is not a number: " + args[opti]); return; diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index a7d436ab87b4..aa4a87e9801b 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -198,6 +198,7 @@ import android.content.pm.VersionedPackage; import android.content.pm.dex.ArtManager; import android.content.pm.dex.DexMetadataHelper; import android.content.pm.dex.IArtManager; +import android.content.pm.permission.SplitPermissionInfoParcelable; import android.content.res.Resources; import android.content.rollback.IRollbackManager; import android.database.ContentObserver; @@ -238,6 +239,7 @@ import android.os.storage.StorageManager; import android.os.storage.StorageManagerInternal; import android.os.storage.VolumeInfo; import android.os.storage.VolumeRecord; +import android.permission.PermissionManager; import android.provider.DeviceConfig; import android.provider.MediaStore; import android.provider.Settings.Global; @@ -2023,6 +2025,14 @@ public class PackageManagerService extends IPackageManager.Stub pkgList.add(packageName); sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null); } + } else if (!ArrayUtils.isEmpty(res.libraryConsumers)) { // if static shared lib + for (int i = 0; i < res.libraryConsumers.size(); i++) { + PackageParser.Package pkg = res.libraryConsumers.get(i); + // send broadcast that all consumers of the static shared library have changed + sendPackageChangedBroadcast(pkg.packageName, false /*killFlag*/, + new ArrayList<>(Collections.singletonList(pkg.packageName)), + pkg.applicationInfo.uid); + } } // Work that needs to happen on first install within each user @@ -2121,6 +2131,12 @@ public class PackageManagerService extends IPackageManager.Stub } } + @Override + public List<SplitPermissionInfoParcelable> getSplitPermissions() { + return PermissionManager.splitPermissionInfoListToParcelableList( + SystemConfig.getInstance().getSplitPermissions()); + } + private void notifyInstallObserver(String packageName) { Pair<PackageInstalledInfo, IPackageInstallObserver2> pair = mNoKillInstallObservers.remove(packageName); @@ -12193,6 +12209,9 @@ public class PackageManagerService extends IPackageManager.Stub } } } + if (reconciledPkg.installResult != null) { + reconciledPkg.installResult.libraryConsumers = clientLibPkgs; + } if ((scanFlags & SCAN_BOOTING) != 0) { // No apps can run during boot scan, so they don't need to be frozen @@ -16046,6 +16065,8 @@ public class PackageManagerService extends IPackageManager.Stub String installerPackageName; PackageRemovedInfo removedInfo; ArrayMap<String, PackageInstalledInfo> addedChildPackages; + // The set of packages consuming this shared library or null if no consumers exist. + ArrayList<PackageParser.Package> libraryConsumers; public void setError(int code, String msg) { setReturnCode(code); @@ -18890,19 +18911,20 @@ public class PackageManagerService extends IPackageManager.Stub // or packages running under the shared user of the removed // package if revoking the permissions requested only by the removed // package is successful and this causes a change in gids. + boolean shouldKill = false; for (int userId : UserManagerService.getInstance().getUserIds()) { final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs, userId); - if (userIdToKill == UserHandle.USER_ALL - || userIdToKill >= UserHandle.USER_SYSTEM) { - // If gids changed for this user, kill all affected packages. - mHandler.post(() -> { - // This has to happen with no lock held. - killApplication(deletedPs.name, deletedPs.appId, - KILL_APP_REASON_GIDS_CHANGED); - }); - break; - } + shouldKill |= userIdToKill == UserHandle.USER_ALL + || userIdToKill >= UserHandle.USER_SYSTEM; + } + // If gids changed, kill all affected packages. + if (shouldKill) { + mHandler.post(() -> { + // This has to happen with no lock held. + killApplication(deletedPs.name, deletedPs.appId, + KILL_APP_REASON_GIDS_CHANGED); + }); } } clearPackagePreferredActivitiesLPw( diff --git a/services/core/java/com/android/server/pm/ProtectedPackages.java b/services/core/java/com/android/server/pm/ProtectedPackages.java index a374e1484b28..231168e9c660 100644 --- a/services/core/java/com/android/server/pm/ProtectedPackages.java +++ b/services/core/java/com/android/server/pm/ProtectedPackages.java @@ -92,6 +92,9 @@ public class ProtectedPackages { if (mDeviceOwnerUserId == userId) { return mDeviceOwnerPackage; } + if (mProfileOwnerPackages == null) { + return null; + } return mProfileOwnerPackages.get(userId); } diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index 899f8022dc8d..4c33bec71a14 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -967,10 +967,12 @@ public class PermissionManagerService { // or has updated its target SDK and AR is no longer implicit to it. // This is a compatibility workaround for apps when AR permission was // split in Q. - int numSplitPerms = PermissionManager.SPLIT_PERMISSIONS.size(); + final List<PermissionManager.SplitPermissionInfo> permissionList = + getSplitPermissions(); + int numSplitPerms = permissionList.size(); for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) { PermissionManager.SplitPermissionInfo sp = - PermissionManager.SPLIT_PERMISSIONS.get(splitPermNum); + permissionList.get(splitPermNum); String splitPermName = sp.getSplitPermission(); if (sp.getNewPermissions().contains(permName) && origPermissions.hasInstallPermission(splitPermName)) { @@ -1537,10 +1539,10 @@ public class PermissionManagerService { String pkgName = pkg.packageName; ArrayMap<String, ArraySet<String>> newToSplitPerms = new ArrayMap<>(); - int numSplitPerms = PermissionManager.SPLIT_PERMISSIONS.size(); + final List<PermissionManager.SplitPermissionInfo> permissionList = getSplitPermissions(); + int numSplitPerms = permissionList.size(); for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) { - PermissionManager.SplitPermissionInfo spi = - PermissionManager.SPLIT_PERMISSIONS.get(splitPermNum); + PermissionManager.SplitPermissionInfo spi = permissionList.get(splitPermNum); List<String> newPerms = spi.getNewPermissions(); int numNewPerms = newPerms.size(); @@ -1595,8 +1597,6 @@ public class PermissionManagerService { Slog.i(TAG, newPerm + " does not inherit from " + sourcePerms + " for " + pkgName + " as split permission is also new"); } - - break; } else { // Inherit from new install or existing runtime permissions inheritPermissionStateToNewImplicitPermissionLocked(sourcePerms, @@ -1610,6 +1610,10 @@ public class PermissionManagerService { return updatedUserIds; } + private List<PermissionManager.SplitPermissionInfo> getSplitPermissions() { + return SystemConfig.getInstance().getSplitPermissions(); + } + private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) { boolean allowed = false; final int NP = PackageParser.NEW_PERMISSIONS.length; @@ -2022,16 +2026,6 @@ public class PermissionManagerService { return whitelistedPermissions; } - private void setWhitelistedRestrictedPermissions(@NonNull PackageParser.Package pkg, - @NonNull int[] userIds, @Nullable List<String> permissions, int callingUid, - @PackageManager.PermissionWhitelistFlags int whitelistFlags, - @NonNull PermissionCallback callback) { - for (int userId : userIds) { - setWhitelistedRestrictedPermissionsForUser(pkg, userId, permissions, - callingUid, whitelistFlags, callback); - } - } - private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId, String[] grantedPermissions, int callingUid, PermissionCallback callback) { PackageSetting ps = (PackageSetting) pkg.mExtras; @@ -2312,109 +2306,122 @@ public class PermissionManagerService { } } - private void setWhitelistedRestrictedPermissionsForUser(@NonNull PackageParser.Package pkg, - @UserIdInt int userId, @Nullable List<String> permissions, int callingUid, - @PermissionWhitelistFlags int whitelistFlags, PermissionCallback callback) { + private void setWhitelistedRestrictedPermissions(@NonNull PackageParser.Package pkg, + @NonNull int[] userIds, @Nullable List<String> permissions, int callingUid, + @PackageManager.PermissionWhitelistFlags int whitelistFlags, + @NonNull PermissionCallback callback) { + final PackageSetting ps = (PackageSetting) pkg.mExtras; if (ps == null) { return; } final PermissionsState permissionsState = ps.getPermissionsState(); - - ArraySet<String> oldGrantedRestrictedPermissions = null; + SparseArray<ArraySet<String>> oldGrantedRestrictedPermissionsByUser = new SparseArray<>(); boolean updatePermissions = false; final int permissionCount = pkg.requestedPermissions.size(); - for (int i = 0; i < permissionCount; i++) { - final String permissionName = pkg.requestedPermissions.get(i); - - final BasePermission bp = mSettings.getPermissionLocked(permissionName); - if (bp == null) { - Slog.w(TAG, "Cannot whitelist unknown permission: " + permissionName); - continue; - } + for (int userId : userIds) { + for (int i = 0; i < permissionCount; i++) { + final String permissionName = pkg.requestedPermissions.get(i); - if (!bp.isHardOrSoftRestricted()) { - continue; - } + final BasePermission bp = mSettings.getPermissionLocked(permissionName); + if (bp == null) { + Slog.w(TAG, "Cannot whitelist unknown permission: " + permissionName); + continue; + } - if (permissionsState.hasPermission(permissionName, userId)) { - if (oldGrantedRestrictedPermissions == null) { - oldGrantedRestrictedPermissions = new ArraySet<>(); + if (!bp.isHardOrSoftRestricted()) { + continue; } - oldGrantedRestrictedPermissions.add(permissionName); - } - final int oldFlags = permissionsState.getPermissionFlags(permissionName, userId); + if (permissionsState.hasPermission(permissionName, userId)) { + if (oldGrantedRestrictedPermissionsByUser.get(userId) == null) { + oldGrantedRestrictedPermissionsByUser.put(userId, new ArraySet<>()); + } + oldGrantedRestrictedPermissionsByUser.get(userId).add(permissionName); + } - int newFlags = oldFlags; - int mask = 0; - int whitelistFlagsCopy = whitelistFlags; - while (whitelistFlagsCopy != 0) { - final int flag = 1 << Integer.numberOfTrailingZeros(whitelistFlagsCopy); - whitelistFlagsCopy &= ~flag; - switch (flag) { - case FLAG_PERMISSION_WHITELIST_SYSTEM: { - mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT; - if (permissions != null && permissions.contains(permissionName)) { - newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT; - } else { - newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT; + final int oldFlags = permissionsState.getPermissionFlags(permissionName, userId); + + int newFlags = oldFlags; + int mask = 0; + int whitelistFlagsCopy = whitelistFlags; + while (whitelistFlagsCopy != 0) { + final int flag = 1 << Integer.numberOfTrailingZeros(whitelistFlagsCopy); + whitelistFlagsCopy &= ~flag; + switch (flag) { + case FLAG_PERMISSION_WHITELIST_SYSTEM: { + mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT; + if (permissions != null && permissions.contains(permissionName)) { + newFlags |= + PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT; + } else { + newFlags &= + ~PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT; + } } - } break; - case FLAG_PERMISSION_WHITELIST_UPGRADE: { - mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT; - if (permissions != null && permissions.contains(permissionName)) { - newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT; - } else { - newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT; + break; + case FLAG_PERMISSION_WHITELIST_UPGRADE: { + mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT; + if (permissions != null && permissions.contains(permissionName)) { + newFlags |= + PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT; + } else { + newFlags &= + ~PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT; + } } - } break; - case FLAG_PERMISSION_WHITELIST_INSTALLER: { - mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT; - if (permissions != null && permissions.contains(permissionName)) { - newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT; - } else { - newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT; + break; + case FLAG_PERMISSION_WHITELIST_INSTALLER: { + mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT; + if (permissions != null && permissions.contains(permissionName)) { + newFlags |= + PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT; + } else { + newFlags &= ~PackageManager + .FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT; + } } - } break; + break; + } } - } - - if (oldFlags == newFlags) { - continue; - } - updatePermissions = true; + if (oldFlags == newFlags) { + continue; + } - final boolean wasWhitelisted = (oldFlags - & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0; - final boolean isWhitelisted = (newFlags - & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0; + updatePermissions = true; + + final boolean wasWhitelisted = (oldFlags + & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0; + final boolean isWhitelisted = (newFlags + & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0; + + // If the permission is policy fixed as granted but it is no longer + // on any of the whitelists we need to clear the policy fixed flag + // as whitelisting trumps policy i.e. policy cannot grant a non + // grantable permission. + if ((oldFlags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) { + final boolean isGranted = permissionsState.hasPermission(permissionName, + userId); + if (!isWhitelisted && isGranted) { + mask |= PackageManager.FLAG_PERMISSION_POLICY_FIXED; + newFlags &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED; + } + } - // If the permission is policy fixed as granted but it is no longer - // on any of the whitelists we need to clear the policy fixed flag - // as whitelisting trumps policy i.e. policy cannot grant a non - // grantable permission. - if ((oldFlags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) { - final boolean isGranted = permissionsState.hasPermission(permissionName, userId); - if (!isWhitelisted && isGranted) { - mask |= PackageManager.FLAG_PERMISSION_POLICY_FIXED; - newFlags &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED; + // If we are whitelisting an app that does not support runtime permissions + // we need to make sure it goes through the permission review UI at launch. + if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M + && !wasWhitelisted && isWhitelisted) { + mask |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; + newFlags |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; } - } - // If we are whitelisting an app that does not support runtime permissions - // we need to make sure it goes through the permission review UI at launch. - if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M - && !wasWhitelisted && isWhitelisted) { - mask |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; - newFlags |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; + updatePermissionFlags(permissionName, pkg.packageName, mask, newFlags, + callingUid, userId, false, null /*callback*/); } - - updatePermissionFlags(permissionName, pkg.packageName, mask, newFlags, - callingUid, userId, false, null /*callback*/); } if (updatePermissions) { @@ -2422,7 +2429,12 @@ public class PermissionManagerService { restorePermissionState(pkg, false, pkg.packageName, callback); // If this resulted in losing a permission we need to kill the app. - if (oldGrantedRestrictedPermissions != null) { + int oldGrantedRestrictedPermissionsByUserCount = + oldGrantedRestrictedPermissionsByUser.size(); + for (int j = 0; j < oldGrantedRestrictedPermissionsByUserCount; j++) { + final int userId = oldGrantedRestrictedPermissionsByUser.keyAt(j); + final ArraySet<String> oldGrantedRestrictedPermissions = + oldGrantedRestrictedPermissionsByUser.valueAt(j); final int oldGrantedCount = oldGrantedRestrictedPermissions.size(); for (int i = 0; i < oldGrantedCount; i++) { final String permission = oldGrantedRestrictedPermissions.valueAt(i); diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index eba4fb63bfc6..eacf1cc8f9fe 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -107,6 +107,7 @@ import android.app.ActivityManagerInternal; import android.app.ActivityTaskManager; import android.app.AppOpsManager; import android.app.IUiModeManager; +import android.app.NotificationManager; import android.app.ProgressDialog; import android.app.SearchManager; import android.app.UiModeManager; @@ -2572,6 +2573,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { return (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); } + NotificationManager getNotificationService() { + return mContext.getSystemService(NotificationManager.class); + } + static IAudioService getAudioService() { IAudioService audioService = IAudioService.Stub.asInterface( ServiceManager.checkService(Context.AUDIO_SERVICE)); @@ -3806,6 +3811,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (down) { sendSystemKeyToStatusBarAsync(event.getKeyCode()); + NotificationManager nm = getNotificationService(); + if (nm != null && !mHandleVolumeKeysInWM) { + nm.silenceNotificationSound(); + } + TelecomManager telecomManager = getTelecommService(); if (telecomManager != null && !mHandleVolumeKeysInWM) { // When {@link #mHandleVolumeKeysInWM} is set, volume key events 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/core/java/com/android/server/power/ThermalManagerService.java b/services/core/java/com/android/server/power/ThermalManagerService.java index 1552fd517d30..491c5ab2ac03 100644 --- a/services/core/java/com/android/server/power/ThermalManagerService.java +++ b/services/core/java/com/android/server/power/ThermalManagerService.java @@ -38,11 +38,13 @@ import android.os.ShellCallback; import android.os.ShellCommand; import android.os.Temperature; import android.util.ArrayMap; +import android.util.EventLog; import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.DumpUtils; +import com.android.server.EventLogTags; import com.android.server.FgThread; import com.android.server.SystemService; @@ -250,6 +252,8 @@ public class ThermalManagerService extends SystemService { } finally { mThermalEventListeners.finishBroadcast(); } + EventLog.writeEvent(EventLogTags.THERMAL_CHANGED, temperature.getName(), + temperature.getType(), temperature.getValue(), temperature.getStatus(), mStatus); } private void shutdownIfNeeded(Temperature temperature) { @@ -860,10 +864,10 @@ public class ThermalManagerService extends SystemService { mThermalHal11.linkToDeath(new DeathRecipient(), THERMAL_HAL_DEATH_COOKIE); mThermalHal11.registerThermalCallback(mThermalCallback11); + Slog.i(TAG, "Thermal HAL 1.1 service connected, limited thermal functions " + + "due to legacy API."); } catch (NoSuchElementException | RemoteException e) { - Slog.e(TAG, - "Thermal HAL 1.1 service not connected, no thermal call back will be " - + "called."); + Slog.e(TAG, "Thermal HAL 1.1 service not connected."); mThermalHal11 = null; } return (mThermalHal11 != null); @@ -978,8 +982,9 @@ public class ThermalManagerService extends SystemService { mThermalHal20.linkToDeath(new DeathRecipient(), THERMAL_HAL_DEATH_COOKIE); mThermalHal20.registerThermalChangedCallback(mThermalCallback20, false, 0 /* not used */); + Slog.i(TAG, "Thermal HAL 2.0 service connected."); } catch (NoSuchElementException | RemoteException e) { - Slog.e(TAG, "Thermal HAL 2.0 service not connected, trying 1.1."); + Slog.e(TAG, "Thermal HAL 2.0 service not connected."); mThermalHal20 = null; } return (mThermalHal20 != null); diff --git a/services/core/java/com/android/server/webkit/WebViewUpdater.java b/services/core/java/com/android/server/webkit/WebViewUpdater.java index a460040d0a60..3b58af2a200f 100644 --- a/services/core/java/com/android/server/webkit/WebViewUpdater.java +++ b/services/core/java/com/android/server/webkit/WebViewUpdater.java @@ -87,19 +87,6 @@ class WebViewUpdater { newPackage = findPreferredWebViewPackage(); if (mCurrentWebViewPackage != null) { oldProviderName = mCurrentWebViewPackage.packageName; - if (changedState == WebViewUpdateService.PACKAGE_CHANGED - && newPackage.packageName.equals(oldProviderName)) { - // If we don't change package name we should only rerun the - // preparation phase if the current package has been replaced - // (not if it has been enabled/disabled). - return; - } - if (newPackage.packageName.equals(oldProviderName) - && (newPackage.lastUpdateTime - == mCurrentWebViewPackage.lastUpdateTime)) { - // If the chosen package hasn't been updated, then early-out - return; - } } // Only trigger update actions if the updated package is the one // that will be used, or the one that was in use before the diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java index c5c53d8ba4ca..97682b7e6d57 100644 --- a/services/core/java/com/android/server/wm/ActivityStack.java +++ b/services/core/java/com/android/server/wm/ActivityStack.java @@ -5227,18 +5227,27 @@ class ActivityStack extends ConfigurationContainer { * then skip running tasks that match those types. */ void getRunningTasks(List<TaskRecord> tasksOut, @ActivityType int ignoreActivityType, - @WindowingMode int ignoreWindowingMode, int callingUid, boolean allowed) { + @WindowingMode int ignoreWindowingMode, int callingUid, boolean allowed, + boolean crossUser) { boolean focusedStack = mRootActivityContainer.getTopDisplayFocusedStack() == this; boolean topTask = true; + int userId = UserHandle.getUserId(callingUid); for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { final TaskRecord task = mTaskHistory.get(taskNdx); if (task.getTopActivity() == null) { // Skip if there are no activities in the task continue; } - if (!allowed && !task.isActivityTypeHome() && task.effectiveUid != callingUid) { - // Skip if the caller can't fetch this task - continue; + if (task.effectiveUid != callingUid) { + if (task.userId != userId && !crossUser) { + // Skip if the caller does not have cross user permission + continue; + } + if (!allowed && !task.isActivityTypeHome()) { + // Skip if the caller isn't allowed to fetch this task, except for the home + // task which we always return. + continue; + } } if (ignoreActivityType != ACTIVITY_TYPE_UNDEFINED && task.getActivityType() == ignoreActivityType) { diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 747837bc933f..59ae9ac96355 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -19,6 +19,8 @@ package com.android.server.wm; import static android.Manifest.permission.BIND_VOICE_INTERACTION; import static android.Manifest.permission.CHANGE_CONFIGURATION; import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS; +import static android.Manifest.permission.INTERACT_ACROSS_USERS; +import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW; import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS; import static android.Manifest.permission.READ_FRAME_BUFFER; @@ -2522,15 +2524,16 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @WindowConfiguration.ActivityType int ignoreActivityType, @WindowConfiguration.WindowingMode int ignoreWindowingMode) { final int callingUid = Binder.getCallingUid(); + final int callingPid = Binder.getCallingPid(); + final boolean crossUser = isCrossUserAllowed(callingPid, callingUid); ArrayList<ActivityManager.RunningTaskInfo> list = new ArrayList<>(); synchronized (mGlobalLock) { if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum); - final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), - callingUid); + final boolean allowed = isGetTasksAllowed("getTasks", callingPid, callingUid); mRootActivityContainer.getRunningTasks(maxNum, list, ignoreActivityType, - ignoreWindowingMode, callingUid, allowed); + ignoreWindowingMode, callingUid, allowed, crossUser); } return list; @@ -3587,6 +3590,11 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { return allowed; } + boolean isCrossUserAllowed(int pid, int uid) { + return checkPermission(INTERACT_ACROSS_USERS, pid, uid) == PERMISSION_GRANTED + || checkPermission(INTERACT_ACROSS_USERS_FULL, pid, uid) == PERMISSION_GRANTED; + } + private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout, diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index e099a4f0c91c..bafb0d1e26a4 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -1072,9 +1072,10 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo // removing from parent. token.getParent().removeChild(token); } - if (prevDc.mLastFocus == mCurrentFocus) { - // The window has become the focus of this display, so it should not be notified - // that it lost focus from the previous display. + if (token.hasChild(prevDc.mLastFocus)) { + // If the reparent window token contains previous display's last focus window, means + // it will end up to gain window focus on the target display, so it should not be + // notified that it lost focus from the previous display. prevDc.mLastFocus = null; } } diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index ed7dbd05853a..99a9db316c63 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -3622,7 +3622,8 @@ public class DisplayPolicy { if (mScreenshotHelper != null) { mScreenshotHelper.takeScreenshot(screenshotType, mStatusBar != null && mStatusBar.isVisibleLw(), - mNavigationBar != null && mNavigationBar.isVisibleLw(), mHandler); + mNavigationBar != null && mNavigationBar.isVisibleLw(), + mHandler, null /* completionConsumer */); } } diff --git a/services/core/java/com/android/server/wm/DisplayWindowSettings.java b/services/core/java/com/android/server/wm/DisplayWindowSettings.java index a46fa13adf4e..207e8ef728eb 100644 --- a/services/core/java/com/android/server/wm/DisplayWindowSettings.java +++ b/services/core/java/com/android/server/wm/DisplayWindowSettings.java @@ -30,6 +30,7 @@ import android.annotation.IntDef; import android.annotation.Nullable; import android.app.WindowConfiguration; import android.os.Environment; +import android.os.FileUtils; import android.provider.Settings; import android.util.AtomicFile; import android.util.Slog; @@ -64,6 +65,11 @@ import java.util.HashMap; class DisplayWindowSettings { private static final String TAG = TAG_WITH_CLASS_NAME ? "DisplayWindowSettings" : TAG_WM; + private static final String SYSTEM_DIRECTORY = "system"; + private static final String DISPLAY_SETTINGS_FILE_NAME = "display_settings.xml"; + private static final String VENDOR_DISPLAY_SETTINGS_PATH = "etc/" + DISPLAY_SETTINGS_FILE_NAME; + private static final String WM_DISPLAY_COMMIT_TAG = "wm-displays"; + private static final int IDENTIFIER_UNIQUE_ID = 0; private static final int IDENTIFIER_PORT = 1; @IntDef(prefix = { "IDENTIFIER_" }, value = { @@ -688,8 +694,26 @@ class DisplayWindowSettings { private final AtomicFile mAtomicFile; AtomicFileStorage() { - final File folder = new File(Environment.getDataDirectory(), "system"); - mAtomicFile = new AtomicFile(new File(folder, "display_settings.xml"), "wm-displays"); + final File folder = new File(Environment.getDataDirectory(), SYSTEM_DIRECTORY); + final File settingsFile = new File(folder, DISPLAY_SETTINGS_FILE_NAME); + // If display_settings.xml doesn't exist, try to copy the vendor's one instead + // in order to provide the vendor specific initialization. + if (!settingsFile.exists()) { + copyVendorSettings(settingsFile); + } + mAtomicFile = new AtomicFile(settingsFile, WM_DISPLAY_COMMIT_TAG); + } + + private static void copyVendorSettings(File target) { + final File vendorFile = new File(Environment.getVendorDirectory(), + VENDOR_DISPLAY_SETTINGS_PATH); + if (vendorFile.canRead()) { + try { + FileUtils.copy(vendorFile, target); + } catch (IOException e) { + Slog.e(TAG, "Failed to copy vendor display_settings.xml"); + } + } } @Override diff --git a/services/core/java/com/android/server/wm/RootActivityContainer.java b/services/core/java/com/android/server/wm/RootActivityContainer.java index d58c61368f9a..2e3094a6b554 100644 --- a/services/core/java/com/android/server/wm/RootActivityContainer.java +++ b/services/core/java/com/android/server/wm/RootActivityContainer.java @@ -2266,9 +2266,9 @@ class RootActivityContainer extends ConfigurationContainer void getRunningTasks(int maxNum, List<ActivityManager.RunningTaskInfo> list, @WindowConfiguration.ActivityType int ignoreActivityType, @WindowConfiguration.WindowingMode int ignoreWindowingMode, int callingUid, - boolean allowed) { + boolean allowed, boolean crossUser) { mStackSupervisor.mRunningTasks.getTasks(maxNum, list, ignoreActivityType, - ignoreWindowingMode, mActivityDisplays, callingUid, allowed); + ignoreWindowingMode, mActivityDisplays, callingUid, allowed, crossUser); } void sendPowerHintForLaunchStartIfNeeded(boolean forceSend, ActivityRecord targetActivity) { diff --git a/services/core/java/com/android/server/wm/RunningTasks.java b/services/core/java/com/android/server/wm/RunningTasks.java index 3bf437d38bcc..22a9c32a830f 100644 --- a/services/core/java/com/android/server/wm/RunningTasks.java +++ b/services/core/java/com/android/server/wm/RunningTasks.java @@ -40,7 +40,7 @@ class RunningTasks { void getTasks(int maxNum, List<RunningTaskInfo> list, @ActivityType int ignoreActivityType, @WindowingMode int ignoreWindowingMode, ArrayList<ActivityDisplay> activityDisplays, - int callingUid, boolean allowed) { + int callingUid, boolean allowed, boolean crossUser) { // Return early if there are no tasks to fetch if (maxNum <= 0) { return; @@ -55,7 +55,7 @@ class RunningTasks { final ActivityStack stack = display.getChildAt(stackNdx); mTmpStackTasks.clear(); stack.getRunningTasks(mTmpStackTasks, ignoreActivityType, ignoreWindowingMode, - callingUid, allowed); + callingUid, allowed, crossUser); mTmpSortedSet.addAll(mTmpStackTasks); } } diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 133b82f72746..97e003c78cd9 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -23,6 +23,7 @@ import static android.os.IServiceManager.DUMP_FLAG_PROTO; import static android.view.Display.DEFAULT_DISPLAY; import android.annotation.NonNull; +import android.annotation.StringRes; import android.app.ActivityThread; import android.app.INotificationManager; import android.app.usage.UsageStatsManagerInternal; @@ -1251,14 +1252,22 @@ public final class SystemServer { startSystemCaptionsManagerService(context); // App prediction manager service - traceBeginAndSlog("StartAppPredictionService"); - mSystemServiceManager.startService(APP_PREDICTION_MANAGER_SERVICE_CLASS); - traceEnd(); + if (deviceHasConfigString(context, R.string.config_defaultAppPredictionService)) { + traceBeginAndSlog("StartAppPredictionService"); + mSystemServiceManager.startService(APP_PREDICTION_MANAGER_SERVICE_CLASS); + traceEnd(); + } else { + Slog.d(TAG, "AppPredictionService not defined by OEM"); + } // Content suggestions manager service - traceBeginAndSlog("StartContentSuggestionsService"); - mSystemServiceManager.startService(CONTENT_SUGGESTIONS_SERVICE_CLASS); - traceEnd(); + if (deviceHasConfigString(context, R.string.config_defaultContentSuggestionsService)) { + traceBeginAndSlog("StartContentSuggestionsService"); + mSystemServiceManager.startService(CONTENT_SUGGESTIONS_SERVICE_CLASS); + traceEnd(); + } else { + Slog.d(TAG, "ContentSuggestionsService not defined by OEM"); + } traceBeginAndSlog("InitNetworkStackClient"); try { @@ -2249,10 +2258,13 @@ public final class SystemServer { }, BOOT_TIMINGS_TRACE_LOG); } + private boolean deviceHasConfigString(@NonNull Context context, @StringRes int resId) { + String serviceName = context.getString(resId); + return !TextUtils.isEmpty(serviceName); + } + private void startSystemCaptionsManagerService(@NonNull Context context) { - String serviceName = context.getString( - com.android.internal.R.string.config_defaultSystemCaptionsManagerService); - if (TextUtils.isEmpty(serviceName)) { + if (!deviceHasConfigString(context, R.string.config_defaultSystemCaptionsManagerService)) { Slog.d(TAG, "SystemCaptionsManagerService disabled because resource is not overlaid"); return; } @@ -2279,9 +2291,7 @@ public final class SystemServer { // Then check if OEM overlaid the resource that defines the service. if (!explicitlyEnabled) { - final String serviceName = context - .getString(com.android.internal.R.string.config_defaultContentCaptureService); - if (TextUtils.isEmpty(serviceName)) { + if (!deviceHasConfigString(context, R.string.config_defaultContentCaptureService)) { Slog.d(TAG, "ContentCaptureService disabled because resource is not overlaid"); return; } diff --git a/services/tests/servicestests/src/com/android/server/accessibility/GlobalActionPerformerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/GlobalActionPerformerTest.java index e72e4601bbe8..c73be6f100cd 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/GlobalActionPerformerTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/GlobalActionPerformerTest.java @@ -35,6 +35,8 @@ import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import java.util.function.Consumer; + /** * Tests for GlobalActionPerformer */ @@ -84,6 +86,6 @@ public class GlobalActionPerformerTest { AccessibilityService.GLOBAL_ACTION_TAKE_SCREENSHOT); verify(mMockScreenshotHelper).takeScreenshot( eq(android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN), anyBoolean(), - anyBoolean(), any(Handler.class)); + anyBoolean(), any(Handler.class), any()); } } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index 5ba1eb29f6b4..5d9e0e21601b 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -962,6 +962,20 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test + public void testCancelImmediatelyAfterEnqueueNotifiesListeners_ForegroundServiceFlag() + throws Exception { + final StatusBarNotification sbn = generateNotificationRecord(null).sbn; + sbn.getNotification().flags = + Notification.FLAG_ONGOING_EVENT | FLAG_FOREGROUND_SERVICE; + mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", + sbn.getId(), sbn.getNotification(), sbn.getUserId()); + mBinderService.cancelNotificationWithTag(PKG, "tag", sbn.getId(), sbn.getUserId()); + waitForIdle(); + verify(mListeners, times(1)).notifyPostedLocked(any(), any()); + verify(mListeners, times(1)).notifyRemovedLocked(any(), anyInt(), any()); + } + + @Test public void testUserInitiatedClearAll_noLeak() throws Exception { final NotificationRecord n = generateNotificationRecord( mTestNotificationChannel, 1, "group", true); @@ -1508,14 +1522,22 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { public void testUpdateAppNotifyCreatorBlock() throws Exception { mService.setPreferencesHelper(mPreferencesHelper); - mBinderService.setNotificationsEnabledForPackage(PKG, 0, false); + mBinderService.setNotificationsEnabledForPackage(PKG, 0, true); ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class); verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null)); assertEquals(NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED, captor.getValue().getAction()); assertEquals(PKG, captor.getValue().getPackage()); - assertTrue(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, false)); + assertFalse(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, true)); + } + + @Test + public void testUpdateAppNotifyCreatorBlock_notIfMatchesExistingSetting() throws Exception { + mService.setPreferencesHelper(mPreferencesHelper); + + mBinderService.setNotificationsEnabledForPackage(PKG, 0, false); + verify(mContext, never()).sendBroadcastAsUser(any(), any(), eq(null)); } @Test 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/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java index a1999c901702..bad6c7cc3eec 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java @@ -1301,10 +1301,10 @@ public class RecentTasksTest extends ActivityTestsBase { @Override void getTasks(int maxNum, List<RunningTaskInfo> list, int ignoreActivityType, int ignoreWindowingMode, ArrayList<ActivityDisplay> activityDisplays, - int callingUid, boolean allowed) { + int callingUid, boolean allowed, boolean crossUser) { mLastAllowed = allowed; super.getTasks(maxNum, list, ignoreActivityType, ignoreWindowingMode, activityDisplays, - callingUid, allowed); + callingUid, allowed, crossUser); } } } diff --git a/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java index dc964806b7a9..cdd4c2424421 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java @@ -77,7 +77,7 @@ public class RunningTasksTest extends ActivityTestsBase { final int numFetchTasks = 5; ArrayList<RunningTaskInfo> tasks = new ArrayList<>(); mRunningTasks.getTasks(5, tasks, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED, - displays, -1 /* callingUid */, true /* allowed */); + displays, -1 /* callingUid */, true /* allowed */, true /*crossUser */); assertThat(tasks).hasSize(numFetchTasks); for (int i = 0; i < numFetchTasks; i++) { assertEquals(numTasks - i - 1, tasks.get(i).id); @@ -87,7 +87,7 @@ public class RunningTasksTest extends ActivityTestsBase { // and does not crash tasks.clear(); mRunningTasks.getTasks(100, tasks, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED, - displays, -1 /* callingUid */, true /* allowed */); + displays, -1 /* callingUid */, true /* allowed */, true /* crossUser */); assertThat(tasks).hasSize(numTasks); for (int i = 0; i < numTasks; i++) { assertEquals(numTasks - i - 1, tasks.get(i).id); 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/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java index f16dec6fb670..0ff92739f8b6 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java @@ -194,7 +194,7 @@ final class VoiceInteractionSessionConnection implements ServiceConnection, if (!mFullyBound) { mFullyBound = mContext.bindServiceAsUser(mBindIntent, mFullConnection, Context.BIND_AUTO_CREATE | Context.BIND_TREAT_LIKE_ACTIVITY - | Context.BIND_FOREGROUND_SERVICE + | Context.BIND_SCHEDULE_LIKE_TOP_APP | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS, new UserHandle(mUser)); } diff --git a/telecomm/java/android/telecom/Logging/Session.java b/telecomm/java/android/telecom/Logging/Session.java index 50c3cd97d77a..95a47e131272 100644 --- a/telecomm/java/android/telecom/Logging/Session.java +++ b/telecomm/java/android/telecom/Logging/Session.java @@ -33,6 +33,8 @@ import java.util.ArrayList; */ public class Session { + public static final String LOG_TAG = "Session"; + public static final String START_SESSION = "START_SESSION"; public static final String START_EXTERNAL_SESSION = "START_EXTERNAL_SESSION"; public static final String CREATE_SUBSESSION = "CREATE_SUBSESSION"; @@ -45,6 +47,9 @@ public class Session { public static final String EXTERNAL_INDICATOR = "E-"; public static final String TRUNCATE_STRING = "..."; + // Prevent infinite recursion by setting a reasonable limit. + private static final int SESSION_RECURSION_LIMIT = 25; + /** * Initial value of mExecutionEndTimeMs and the final value of {@link #getLocalExecutionTime()} * if the Session is canceled. @@ -226,6 +231,15 @@ public class Session { // Builds full session id recursively private String getFullSessionId() { + return getFullSessionId(0); + } + + // keep track of calls and bail if we hit the recursion limit + private String getFullSessionId(int parentCount) { + if (parentCount >= SESSION_RECURSION_LIMIT) { + Log.w(LOG_TAG, "getFullSessionId: Hit recursion limit!"); + return TRUNCATE_STRING + mSessionId; + } // Cache mParentSession locally to prevent a concurrency problem where // Log.endParentSessions() is called while a logging statement is running (Log.i, for // example) and setting mParentSession to null in a different thread after the null check @@ -235,42 +249,57 @@ public class Session { return mSessionId; } else { if (Log.VERBOSE) { - return parentSession.getFullSessionId() + + return parentSession.getFullSessionId(parentCount + 1) // Append "_X" to subsession to show subsession designation. - SESSION_SEPARATION_CHAR_CHILD + mSessionId; + + SESSION_SEPARATION_CHAR_CHILD + mSessionId; } else { // Only worry about the base ID at the top of the tree. - return parentSession.getFullSessionId(); + return parentSession.getFullSessionId(parentCount + 1); } } } - // Print out the full Session tree from any subsession node - public String printFullSessionTree() { - // Get to the top of the tree + private Session getRootSession(String callingMethod) { + int currParentCount = 0; Session topNode = this; while (topNode.getParentSession() != null) { + if (currParentCount >= SESSION_RECURSION_LIMIT) { + Log.w(LOG_TAG, "getRootSession: Hit recursion limit from " + callingMethod); + break; + } topNode = topNode.getParentSession(); + currParentCount++; } - return topNode.printSessionTree(); + return topNode; + } + + // Print out the full Session tree from any subsession node + public String printFullSessionTree() { + return getRootSession("printFullSessionTree").printSessionTree(); } // Recursively move down session tree using DFS, but print out each node when it is reached. - public String printSessionTree() { + private String printSessionTree() { StringBuilder sb = new StringBuilder(); - printSessionTree(0, sb); + printSessionTree(0, sb, 0); return sb.toString(); } - private void printSessionTree(int tabI, StringBuilder sb) { + private void printSessionTree(int tabI, StringBuilder sb, int currChildCount) { + // Prevent infinite recursion. + if (currChildCount >= SESSION_RECURSION_LIMIT) { + Log.w(LOG_TAG, "printSessionTree: Hit recursion limit!"); + sb.append(TRUNCATE_STRING); + return; + } sb.append(toString()); for (Session child : mChildSessions) { sb.append("\n"); for (int i = 0; i <= tabI; i++) { sb.append("\t"); } - child.printSessionTree(tabI + 1, sb); + child.printSessionTree(tabI + 1, sb, currChildCount + 1); } } @@ -279,11 +308,17 @@ public class Session { // recent) will be truncated to "..." public String getFullMethodPath(boolean truncatePath) { StringBuilder sb = new StringBuilder(); - getFullMethodPath(sb, truncatePath); + getFullMethodPath(sb, truncatePath, 0); return sb.toString(); } - private synchronized void getFullMethodPath(StringBuilder sb, boolean truncatePath) { + private synchronized void getFullMethodPath(StringBuilder sb, boolean truncatePath, + int parentCount) { + if (parentCount >= SESSION_RECURSION_LIMIT) { + Log.w(LOG_TAG, "getFullMethodPath: Hit recursion limit!"); + sb.append(TRUNCATE_STRING); + return; + } // Return cached value for method path. When returning the truncated path, recalculate the // full path without using the cached value. if (!TextUtils.isEmpty(mFullMethodPathCache) && !truncatePath) { @@ -296,7 +331,7 @@ public class Session { // Check to see if the session has been renamed yet. If it has not, then the session // has not been continued. isSessionStarted = !mShortMethodName.equals(parentSession.mShortMethodName); - parentSession.getFullMethodPath(sb, truncatePath); + parentSession.getFullMethodPath(sb, truncatePath, parentCount + 1); sb.append(SUBSESSION_SEPARATION_CHAR); } // Encapsulate the external session's method name so it is obvious what part of the session @@ -319,13 +354,10 @@ public class Session { mFullMethodPathCache = sb.toString(); } } + // Recursively move to the top of the tree to see if the parent session is external. private boolean isSessionExternal() { - if (getParentSession() == null) { - return isExternal(); - } else { - return getParentSession().isSessionExternal(); - } + return getRootSession("isSessionExternal").isExternal(); } @Override diff --git a/telephony/java/android/provider/Telephony.java b/telephony/java/android/provider/Telephony.java index 8e56fe72e152..3d28cf630a66 100644 --- a/telephony/java/android/provider/Telephony.java +++ b/telephony/java/android/provider/Telephony.java @@ -3917,6 +3917,12 @@ public final class Telephony { public static final Uri CONTENT_URI = Uri.parse("content://cellbroadcasts"); /** + * The id of the subscription which received this cell broadcast message. + * <P>Type: INTEGER</P> + */ + public static final String SUB_ID = "sub_id"; + + /** * Message geographical scope. * <P>Type: INTEGER</P> */ @@ -4049,6 +4055,64 @@ public final class Telephony { public static final String DEFAULT_SORT_ORDER = DELIVERY_TIME + " DESC"; /** + * The timestamp in millisecond of when the device received the message. + * <P>Type: BIGINT</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"; + + /** + * Geo-Fencing Maximum Wait Time in second. The range of the time is [0, 255]. A device + * shall allow to determine its position meeting operator policy. If the device is unable to + * determine its position meeting operator policy within the GeoFencing Maximum Wait Time, + * it shall present the alert to the user and discontinue further positioning determination + * for the alert. + * + * <P>Type: INTEGER</P> + */ + public static final String MAXIMUM_WAIT_TIME = "maximum_wait_time"; + + /** * Query columns for instantiating {@link android.telephony.CellBroadcastMessage} objects. */ public static final String[] QUERY_COLUMNS = { @@ -4073,6 +4137,34 @@ public final class Telephony { CMAS_URGENCY, CMAS_CERTAINTY }; + + /** + * Query columns for instantiating {@link android.telephony.SmsCbMessage} objects. + */ + public static final String[] QUERY_COLUMNS_FWK = { + _ID, + GEOGRAPHICAL_SCOPE, + PLMN, + LAC, + CID, + SERIAL_NUMBER, + SERVICE_CATEGORY, + LANGUAGE_CODE, + MESSAGE_BODY, + MESSAGE_FORMAT, + MESSAGE_PRIORITY, + ETWS_WARNING_TYPE, + CMAS_MESSAGE_CLASS, + CMAS_CATEGORY, + CMAS_RESPONSE_TYPE, + CMAS_SEVERITY, + CMAS_URGENCY, + CMAS_CERTAINTY, + RECEIVED_TIME, + MESSAGE_BROADCASTED, + GEOMETRIES, + MAXIMUM_WAIT_TIME + }; } /** diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index de8347316f8f..67f346ff5597 100755 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -1387,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 */ @@ -2628,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. + * + * Icon name options: "5G_Plus", "5G". * - * Here is an example of the configuration: - * "connected_mmwave:5GPlus,connected:5G,not_restricted:None,restricted:None" + * 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 */ @@ -2654,6 +2670,22 @@ public class CarrierConfigManager { "5g_icon_configuration_string"; /** + * Timeout in second for displaying 5G icon, default value is 0 which means the timer is + * disabled. + * + * System UI will show the 5G icon and start a timer with the timeout from this config when the + * device connects to a 5G cell. System UI stops displaying 5G icon when both the device + * disconnects from 5G cell and the timer is expired. + * + * If 5G is reacquired during this timer, the timer is canceled and restarted when 5G is next + * lost. Allows us to momentarily lose 5G without blinking the icon. + * + * @hide + */ + public static final String KEY_5G_ICON_DISPLAY_GRACE_PERIOD_SEC_INT = + "5g_icon_display_grace_period_sec_int"; + + /** * Support ASCII 7-BIT encoding for long SMS. This carrier config is used to enable * this feature. * @hide @@ -2705,12 +2737,20 @@ public class CarrierConfigManager { /** * Controls hysteresis time in milli seconds for which OpportunisticNetworkService - * will wait before switching data to a network. + * will wait before switching data to an opportunistic network. */ public static final String KEY_OPPORTUNISTIC_NETWORK_DATA_SWITCH_HYSTERESIS_TIME_LONG = "opportunistic_network_data_switch_hysteresis_time_long"; /** + * Controls hysteresis time in milli seconds for which OpportunisticNetworkService + * will wait before switching data from opportunistic network to primary network. + * @hide + */ + public static final String KEY_OPPORTUNISTIC_NETWORK_DATA_SWITCH_EXIT_HYSTERESIS_TIME_LONG = + "opportunistic_network_data_switch_exit_hysteresis_time_long"; + + /** * Indicates zero or more emergency number prefix(es), because some carrier requires * if users dial an emergency number address with a specific prefix, the combination of the * prefix and the address is also a valid emergency number to dial. For example, an emergency @@ -3063,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; @@ -3179,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); @@ -3442,7 +3490,8 @@ 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 */ sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_RSRP_INT, -108); @@ -3458,6 +3507,8 @@ public class CarrierConfigManager { sDefaults.putLong(KEY_OPPORTUNISTIC_NETWORK_ENTRY_OR_EXIT_HYSTERESIS_TIME_LONG, 10000); /* Default value is 10 seconds. */ sDefaults.putLong(KEY_OPPORTUNISTIC_NETWORK_DATA_SWITCH_HYSTERESIS_TIME_LONG, 10000); + /* Default value is 3 seconds. */ + sDefaults.putLong(KEY_OPPORTUNISTIC_NETWORK_DATA_SWITCH_EXIT_HYSTERESIS_TIME_LONG, 3000); sDefaults.putAll(Gps.getDefaults()); sDefaults.putAll(Wifi.getDefaults()); sDefaults.putIntArray(KEY_CDMA_ENHANCED_ROAMING_INDICATOR_FOR_HOME_NETWORK_INT_ARRAY, @@ -3467,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); @@ -3481,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/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java index 1e6cd474d13b..c6c198668d95 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(); @@ -574,9 +580,10 @@ public class SubscriptionInfo implements Parcelable { try { packageInfo = packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES); } catch (PackageManager.NameNotFoundException e) { - throw new IllegalArgumentException("Unknown package: " + packageName, e); + Log.d("SubscriptionInfo", "canManageSubscription: Unknown package: " + packageName, e); + return false; } - for (UiccAccessRule rule : mAccessRules) { + for (UiccAccessRule rule : allAccessRules) { if (rule.getCarrierPrivilegeStatus(packageInfo) == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { return true; @@ -586,17 +593,33 @@ 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 +674,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 +686,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 +720,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 +732,7 @@ public class SubscriptionInfo implements Parcelable { dest.writeStringArray(mEhplmns); dest.writeStringArray(mHplmns); dest.writeString(mGroupOwner); + dest.writeTypedArray(mCarrierConfigAccessRules, flags); } @Override @@ -738,7 +765,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 +773,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 +817,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..776b168e6766 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 == null || info.getAllAccessRules() == null) { return false; } PackageManager packageManager = mContext.getPackageManager(); @@ -2609,9 +2614,10 @@ public class SubscriptionManager { try { packageInfo = packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES); } catch (PackageManager.NameNotFoundException e) { - throw new IllegalArgumentException("Unknown package: " + packageName, e); + logd("Unknown package: " + packageName); + return false; } - for (UiccAccessRule rule : info.getAccessRules()) { + for (UiccAccessRule rule : info.getAllAccessRules()) { if (rule.getCarrierPrivilegeStatus(packageInfo) == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { return true; @@ -3002,7 +3008,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/com/android/internal/telephony/CbGeoUtils.java b/telephony/java/com/android/internal/telephony/CbGeoUtils.java new file mode 100644 index 000000000000..0b73252a1e1b --- /dev/null +++ b/telephony/java/com/android/internal/telephony/CbGeoUtils.java @@ -0,0 +1,370 @@ +/* + * 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 TLV tags of WAC, defined in ATIS-0700041 5.2.3 WAC tag coding. */ + public static final int GEO_FENCING_MAXIMUM_WAIT_TIME = 0x01; + public static final int GEOMETRY_TYPE_POLYGON = 0x02; + public static final int GEOMETRY_TYPE_CIRCLE = 0x03; + + /** 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; + } + + @Override + public String toString() { + return "(" + lat + "," + lng + ")"; + } + } + + /** + * 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(List<Geometry> geometries) { + if (geometries == null || geometries.isEmpty()) return ""; + 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/telephony/java/com/android/internal/telephony/SmsCbMessage.java b/telephony/java/com/android/internal/telephony/SmsCbMessage.java index 046bf8c700eb..21576668db72 100644 --- a/telephony/java/com/android/internal/telephony/SmsCbMessage.java +++ b/telephony/java/com/android/internal/telephony/SmsCbMessage.java @@ -16,8 +16,17 @@ package android.telephony; +import android.annotation.Nullable; +import android.content.ContentValues; +import android.database.Cursor; import android.os.Parcel; import android.os.Parcelable; +import android.provider.Telephony.CellBroadcasts; + +import com.android.internal.telephony.CbGeoUtils; +import com.android.internal.telephony.CbGeoUtils.Geometry; + +import java.util.List; /** * Parcelable object containing a received cell broadcast message. There are four different types @@ -95,6 +104,9 @@ public class SmsCbMessage implements Parcelable { /** Emergency message priority. */ public static final int MESSAGE_PRIORITY_EMERGENCY = 3; + /** ATIS-0700041 Section 5.2.8 WAC Geo-Fencing Maximum Wait Time Table 12. */ + public static final int MAXIMUM_WAIT_TIME_NOT_SET = 255; + /** Format of this message (for interpretation of service category values). */ private final int mMessageFormat; @@ -139,11 +151,38 @@ public class SmsCbMessage implements Parcelable { private final SmsCbCmasInfo mCmasWarningInfo; /** + * Geo-Fencing Maximum Wait Time in second, a device shall allow to determine its position + * meeting operator policy. If the device is unable to determine its position meeting operator + * policy within the GeoFencing Maximum Wait Time, it shall present the alert to the user and + * discontinue further positioning determination for the alert. + */ + private final int mMaximumWaitTimeSec; + + /** UNIX timestamp of when the message was received. */ + private final long mReceivedTimeMillis; + + /** CMAS warning area coordinates. */ + private final List<Geometry> mGeometries; + + /** * Create a new SmsCbMessage with the specified data. */ public SmsCbMessage(int messageFormat, int geographicalScope, int serialNumber, SmsCbLocation location, int serviceCategory, String language, String body, int priority, SmsCbEtwsInfo etwsWarningInfo, SmsCbCmasInfo cmasWarningInfo) { + + this(messageFormat, geographicalScope, serialNumber, location, serviceCategory, language, + body, priority, etwsWarningInfo, cmasWarningInfo, 0 /* maximumWaitingTime */, + null /* geometries */, System.currentTimeMillis()); + } + + /** + * Create a new {@link SmsCbMessage} with the warning area coordinates information. + */ + public SmsCbMessage(int messageFormat, int geographicalScope, int serialNumber, + SmsCbLocation location, int serviceCategory, String language, String body, + int priority, SmsCbEtwsInfo etwsWarningInfo, SmsCbCmasInfo cmasWarningInfo, + int maximumWaitTimeSec, List<Geometry> geometries, long receivedTimeMillis) { mMessageFormat = messageFormat; mGeographicalScope = geographicalScope; mSerialNumber = serialNumber; @@ -154,6 +193,9 @@ public class SmsCbMessage implements Parcelable { mPriority = priority; mEtwsWarningInfo = etwsWarningInfo; mCmasWarningInfo = cmasWarningInfo; + mReceivedTimeMillis = receivedTimeMillis; + mGeometries = geometries; + mMaximumWaitTimeSec = maximumWaitTimeSec; } /** Create a new SmsCbMessage object from a Parcel. */ @@ -184,6 +226,10 @@ public class SmsCbMessage implements Parcelable { mEtwsWarningInfo = null; mCmasWarningInfo = null; } + mReceivedTimeMillis = in.readLong(); + String geoStr = in.readString(); + mGeometries = geoStr != null ? CbGeoUtils.parseGeometriesFromString(geoStr) : null; + mMaximumWaitTimeSec = in.readInt(); } /** @@ -214,6 +260,10 @@ public class SmsCbMessage implements Parcelable { // no ETWS or CMAS warning information dest.writeInt('0'); } + dest.writeLong(mReceivedTimeMillis); + dest.writeString( + mGeometries != null ? CbGeoUtils.encodeGeometriesToString(mGeometries) : null); + dest.writeInt(mMaximumWaitTimeSec); } public static final Parcelable.Creator<SmsCbMessage> CREATOR @@ -293,6 +343,32 @@ public class SmsCbMessage implements Parcelable { } /** + * Get the warning area coordinates information represent by polygons and circles. + * @return a list of geometries, {@link Nullable} means there is no coordinate information + * associated to this message. + */ + @Nullable + public List<Geometry> getGeometries() { + return mGeometries; + } + + /** + * Get the Geo-Fencing Maximum Wait Time. + * @return the time in second. + */ + public int getMaximumWaitingTime() { + return mMaximumWaitTimeSec; + } + + /** + * Get the time when this message was received. + * @return the time in millisecond + */ + public long getReceivedTime() { + return mReceivedTimeMillis; + } + + /** * Get the message format ({@link #MESSAGE_FORMAT_3GPP} or {@link #MESSAGE_FORMAT_3GPP2}). * @return an integer representing 3GPP or 3GPP2 message format */ @@ -368,7 +444,11 @@ public class SmsCbMessage implements Parcelable { + mServiceCategory + ", language=" + mLanguage + ", body=" + mBody + ", priority=" + mPriority + (mEtwsWarningInfo != null ? (", " + mEtwsWarningInfo.toString()) : "") - + (mCmasWarningInfo != null ? (", " + mCmasWarningInfo.toString()) : "") + '}'; + + (mCmasWarningInfo != null ? (", " + mCmasWarningInfo.toString()) : "") + + ", maximumWaitingTime = " + mMaximumWaitTimeSec + + ", geo=" + (mGeometries != null + ? CbGeoUtils.encodeGeometriesToString(mGeometries) : "null") + + '}'; } /** @@ -379,4 +459,177 @@ public class SmsCbMessage implements Parcelable { public int describeContents() { return 0; } + + /** + * @return the {@link ContentValues} instance that includes the cell broadcast data. + */ + public ContentValues getContentValues() { + ContentValues cv = new ContentValues(16); + cv.put(CellBroadcasts.GEOGRAPHICAL_SCOPE, mGeographicalScope); + if (mLocation.getPlmn() != null) { + cv.put(CellBroadcasts.PLMN, mLocation.getPlmn()); + } + if (mLocation.getLac() != -1) { + cv.put(CellBroadcasts.LAC, mLocation.getLac()); + } + if (mLocation.getCid() != -1) { + cv.put(CellBroadcasts.CID, mLocation.getCid()); + } + cv.put(CellBroadcasts.SERIAL_NUMBER, getSerialNumber()); + cv.put(CellBroadcasts.SERVICE_CATEGORY, getServiceCategory()); + cv.put(CellBroadcasts.LANGUAGE_CODE, getLanguageCode()); + cv.put(CellBroadcasts.MESSAGE_BODY, getMessageBody()); + cv.put(CellBroadcasts.MESSAGE_FORMAT, getMessageFormat()); + cv.put(CellBroadcasts.MESSAGE_PRIORITY, getMessagePriority()); + + SmsCbEtwsInfo etwsInfo = getEtwsWarningInfo(); + if (etwsInfo != null) { + cv.put(CellBroadcasts.ETWS_WARNING_TYPE, etwsInfo.getWarningType()); + } + + SmsCbCmasInfo cmasInfo = getCmasWarningInfo(); + if (cmasInfo != null) { + cv.put(CellBroadcasts.CMAS_MESSAGE_CLASS, cmasInfo.getMessageClass()); + cv.put(CellBroadcasts.CMAS_CATEGORY, cmasInfo.getCategory()); + cv.put(CellBroadcasts.CMAS_RESPONSE_TYPE, cmasInfo.getResponseType()); + cv.put(CellBroadcasts.CMAS_SEVERITY, cmasInfo.getSeverity()); + cv.put(CellBroadcasts.CMAS_URGENCY, cmasInfo.getUrgency()); + cv.put(CellBroadcasts.CMAS_CERTAINTY, cmasInfo.getCertainty()); + } + + cv.put(CellBroadcasts.RECEIVED_TIME, mReceivedTimeMillis); + + if (mGeometries != null) { + cv.put(CellBroadcasts.GEOMETRIES, CbGeoUtils.encodeGeometriesToString(mGeometries)); + } else { + cv.put(CellBroadcasts.GEOMETRIES, (String) null); + } + + cv.put(CellBroadcasts.MAXIMUM_WAIT_TIME, mMaximumWaitTimeSec); + + return cv; + } + + /** + * Create a {@link SmsCbMessage} instance from a row in the cell broadcast database. + * @param cursor an open SQLite cursor pointing to the row to read + * @return a {@link SmsCbMessage} instance. + * @throws IllegalArgumentException if one of the required columns is missing + */ + public static SmsCbMessage createFromCursor(Cursor cursor) { + int geoScope = cursor.getInt( + cursor.getColumnIndexOrThrow(CellBroadcasts.GEOGRAPHICAL_SCOPE)); + int serialNum = cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.SERIAL_NUMBER)); + int category = cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.SERVICE_CATEGORY)); + String language = cursor.getString( + cursor.getColumnIndexOrThrow(CellBroadcasts.LANGUAGE_CODE)); + String body = cursor.getString(cursor.getColumnIndexOrThrow(CellBroadcasts.MESSAGE_BODY)); + int format = cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.MESSAGE_FORMAT)); + int priority = cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.MESSAGE_PRIORITY)); + + String plmn; + int plmnColumn = cursor.getColumnIndex(CellBroadcasts.PLMN); + if (plmnColumn != -1 && !cursor.isNull(plmnColumn)) { + plmn = cursor.getString(plmnColumn); + } else { + plmn = null; + } + + int lac; + int lacColumn = cursor.getColumnIndex(CellBroadcasts.LAC); + if (lacColumn != -1 && !cursor.isNull(lacColumn)) { + lac = cursor.getInt(lacColumn); + } else { + lac = -1; + } + + int cid; + int cidColumn = cursor.getColumnIndex(CellBroadcasts.CID); + if (cidColumn != -1 && !cursor.isNull(cidColumn)) { + cid = cursor.getInt(cidColumn); + } else { + cid = -1; + } + + SmsCbLocation location = new SmsCbLocation(plmn, lac, cid); + + SmsCbEtwsInfo etwsInfo; + int etwsWarningTypeColumn = cursor.getColumnIndex(CellBroadcasts.ETWS_WARNING_TYPE); + if (etwsWarningTypeColumn != -1 && !cursor.isNull(etwsWarningTypeColumn)) { + int warningType = cursor.getInt(etwsWarningTypeColumn); + etwsInfo = new SmsCbEtwsInfo(warningType, false, false, false, null); + } else { + etwsInfo = null; + } + + SmsCbCmasInfo cmasInfo = null; + int cmasMessageClassColumn = cursor.getColumnIndex(CellBroadcasts.CMAS_MESSAGE_CLASS); + if (cmasMessageClassColumn != -1 && !cursor.isNull(cmasMessageClassColumn)) { + int messageClass = cursor.getInt(cmasMessageClassColumn); + + int cmasCategory; + int cmasCategoryColumn = cursor.getColumnIndex(CellBroadcasts.CMAS_CATEGORY); + if (cmasCategoryColumn != -1 && !cursor.isNull(cmasCategoryColumn)) { + cmasCategory = cursor.getInt(cmasCategoryColumn); + } else { + cmasCategory = SmsCbCmasInfo.CMAS_CATEGORY_UNKNOWN; + } + + int responseType; + int cmasResponseTypeColumn = cursor.getColumnIndex(CellBroadcasts.CMAS_RESPONSE_TYPE); + if (cmasResponseTypeColumn != -1 && !cursor.isNull(cmasResponseTypeColumn)) { + responseType = cursor.getInt(cmasResponseTypeColumn); + } else { + responseType = SmsCbCmasInfo.CMAS_RESPONSE_TYPE_UNKNOWN; + } + + int severity; + int cmasSeverityColumn = cursor.getColumnIndex(CellBroadcasts.CMAS_SEVERITY); + if (cmasSeverityColumn != -1 && !cursor.isNull(cmasSeverityColumn)) { + severity = cursor.getInt(cmasSeverityColumn); + } else { + severity = SmsCbCmasInfo.CMAS_SEVERITY_UNKNOWN; + } + + int urgency; + int cmasUrgencyColumn = cursor.getColumnIndex(CellBroadcasts.CMAS_URGENCY); + if (cmasUrgencyColumn != -1 && !cursor.isNull(cmasUrgencyColumn)) { + urgency = cursor.getInt(cmasUrgencyColumn); + } else { + urgency = SmsCbCmasInfo.CMAS_URGENCY_UNKNOWN; + } + + int certainty; + int cmasCertaintyColumn = cursor.getColumnIndex(CellBroadcasts.CMAS_CERTAINTY); + if (cmasCertaintyColumn != -1 && !cursor.isNull(cmasCertaintyColumn)) { + certainty = cursor.getInt(cmasCertaintyColumn); + } else { + certainty = SmsCbCmasInfo.CMAS_CERTAINTY_UNKNOWN; + } + + cmasInfo = new SmsCbCmasInfo(messageClass, cmasCategory, responseType, severity, + urgency, certainty); + } + + String geoStr = cursor.getString(cursor.getColumnIndex(CellBroadcasts.GEOMETRIES)); + List<Geometry> geometries = + geoStr != null ? CbGeoUtils.parseGeometriesFromString(geoStr) : null; + + long receivedTimeMillis = cursor.getLong( + cursor.getColumnIndexOrThrow(CellBroadcasts.RECEIVED_TIME)); + + int maximumWaitTimeSec = cursor.getInt( + cursor.getColumnIndexOrThrow(CellBroadcasts.MAXIMUM_WAIT_TIME)); + + return new SmsCbMessage(format, geoScope, serialNum, location, category, + language, body, priority, etwsInfo, cmasInfo, maximumWaitTimeSec, geometries, + receivedTimeMillis); + } + + /** + * @return {@code True} if this message needs geo-fencing check. + */ + public boolean needGeoFencingCheck() { + return mMaximumWaitTimeSec > 0 && mGeometries != null; + } } diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java index 8015b07fa024..6eea118787a7 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java @@ -22,58 +22,36 @@ import static android.telephony.SmsCbEtwsInfo.ETWS_WARNING_TYPE_OTHER_EMERGENCY; import static android.telephony.SmsCbEtwsInfo.ETWS_WARNING_TYPE_TEST_MESSAGE; import static android.telephony.SmsCbEtwsInfo.ETWS_WARNING_TYPE_TSUNAMI; +import android.annotation.NonNull; import android.content.Context; import android.content.res.Resources; import android.telephony.SmsCbLocation; import android.telephony.SmsCbMessage; import android.util.Pair; +import android.util.Slog; import com.android.internal.R; +import com.android.internal.telephony.CbGeoUtils; +import com.android.internal.telephony.CbGeoUtils.Circle; +import com.android.internal.telephony.CbGeoUtils.Geometry; +import com.android.internal.telephony.CbGeoUtils.LatLng; +import com.android.internal.telephony.CbGeoUtils.Polygon; import com.android.internal.telephony.GsmAlphabet; import com.android.internal.telephony.SmsConstants; +import com.android.internal.telephony.gsm.GsmSmsCbMessage.GeoFencingTriggerMessage.CellBroadcastIdentity; +import com.android.internal.telephony.gsm.SmsCbHeader.DataCodingScheme; import java.io.UnsupportedEncodingException; -import java.util.Locale; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; /** * Parses a GSM or UMTS format SMS-CB message into an {@link SmsCbMessage} object. The class is * public because {@link #createSmsCbMessage(SmsCbLocation, byte[][])} is used by some test cases. */ public class GsmSmsCbMessage { - - /** - * Languages in the 0000xxxx DCS group as defined in 3GPP TS 23.038, section 5. - */ - private static final String[] LANGUAGE_CODES_GROUP_0 = { - Locale.GERMAN.getLanguage(), // German - Locale.ENGLISH.getLanguage(), // English - Locale.ITALIAN.getLanguage(), // Italian - Locale.FRENCH.getLanguage(), // French - new Locale("es").getLanguage(), // Spanish - new Locale("nl").getLanguage(), // Dutch - new Locale("sv").getLanguage(), // Swedish - new Locale("da").getLanguage(), // Danish - new Locale("pt").getLanguage(), // Portuguese - new Locale("fi").getLanguage(), // Finnish - new Locale("nb").getLanguage(), // Norwegian - new Locale("el").getLanguage(), // Greek - new Locale("tr").getLanguage(), // Turkish - new Locale("hu").getLanguage(), // Hungarian - new Locale("pl").getLanguage(), // Polish - null - }; - - /** - * Languages in the 0010xxxx DCS group as defined in 3GPP TS 23.038, section 5. - */ - private static final String[] LANGUAGE_CODES_GROUP_2 = { - new Locale("cs").getLanguage(), // Czech - new Locale("he").getLanguage(), // Hebrew - new Locale("ar").getLanguage(), // Arabic - new Locale("ru").getLanguage(), // Russian - new Locale("is").getLanguage(), // Icelandic - null, null, null, null, null, null, null, null, null, null, null - }; + private static final String TAG = GsmSmsCbMessage.class.getSimpleName(); private static final char CARRIAGE_RETURN = 0x0d; @@ -114,8 +92,9 @@ public class GsmSmsCbMessage { * @param pdus PDU bytes */ public static SmsCbMessage createSmsCbMessage(Context context, SmsCbHeader header, - SmsCbLocation location, byte[][] pdus) + SmsCbLocation location, byte[][] pdus) throws IllegalArgumentException { + long receivedTimeMillis = System.currentTimeMillis(); if (header.isEtwsPrimaryNotification()) { // ETSI TS 23.041 ETWS Primary Notification message // ETWS primary message only contains 4 fields including serial number, @@ -125,12 +104,46 @@ public class GsmSmsCbMessage { header.getSerialNumber(), location, header.getServiceCategory(), null, getEtwsPrimaryMessage(context, header.getEtwsInfo().getWarningType()), SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY, header.getEtwsInfo(), - header.getCmasInfo()); + header.getCmasInfo(), 0, null /* geometries */, receivedTimeMillis); + } else if (header.isUmtsFormat()) { + // UMTS format has only 1 PDU + byte[] pdu = pdus[0]; + Pair<String, String> cbData = parseUmtsBody(header, pdu); + String language = cbData.first; + String body = cbData.second; + int priority = header.isEmergencyMessage() ? SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY + : SmsCbMessage.MESSAGE_PRIORITY_NORMAL; + int nrPages = pdu[SmsCbHeader.PDU_HEADER_LENGTH]; + int wacDataOffset = SmsCbHeader.PDU_HEADER_LENGTH + + 1 // number of pages + + (PDU_BODY_PAGE_LENGTH + 1) * nrPages; // cb data + + // Has Warning Area Coordinates information + List<Geometry> geometries = null; + int maximumWaitingTimeSec = 255; + if (pdu.length > wacDataOffset) { + try { + Pair<Integer, List<Geometry>> wac = parseWarningAreaCoordinates(pdu, + wacDataOffset); + maximumWaitingTimeSec = wac.first; + geometries = wac.second; + } catch (Exception ex) { + // Catch the exception here, the message will be considered as having no WAC + // information which means the message will be broadcasted directly. + Slog.e(TAG, "Can't parse warning area coordinates, ex = " + ex.toString()); + } + } + + return new SmsCbMessage(SmsCbMessage.MESSAGE_FORMAT_3GPP, + header.getGeographicalScope(), header.getSerialNumber(), location, + header.getServiceCategory(), language, body, priority, + header.getEtwsInfo(), header.getCmasInfo(), maximumWaitingTimeSec, geometries, + receivedTimeMillis); } else { String language = null; StringBuilder sb = new StringBuilder(); for (byte[] pdu : pdus) { - Pair<String, String> p = parseBody(header, pdu); + Pair<String, String> p = parseGsmBody(header, pdu); language = p.first; sb.append(p.second); } @@ -140,154 +153,208 @@ public class GsmSmsCbMessage { return new SmsCbMessage(SmsCbMessage.MESSAGE_FORMAT_3GPP, header.getGeographicalScope(), header.getSerialNumber(), location, header.getServiceCategory(), language, sb.toString(), priority, - header.getEtwsInfo(), header.getCmasInfo()); + header.getEtwsInfo(), header.getCmasInfo(), 0, null /* geometries */, + receivedTimeMillis); } } /** - * Parse and unpack the body text according to the encoding in the DCS. - * After completing successfully this method will have assigned the body - * text into mBody, and optionally the language code into mLanguage + * Parse WEA Handset Action Message(WHAM) a.k.a geo-fencing trigger message. * - * @param header the message header to use - * @param pdu the PDU to decode - * @return a Pair of Strings containing the language and body of the message + * WEA Handset Action Message(WHAM) is a cell broadcast service message broadcast by the network + * to direct devices to perform a geo-fencing check on selected alerts. + * + * WEA Handset Action Message(WHAM) requirements from ATIS-0700041 section 4 + * 1. The Warning Message contents of a WHAM shall be in Cell Broadcast(CB) data format as + * defined in TS 23.041. + * 2. The Warning Message Contents of WHAM shall be limited to one CB page(max 20 referenced + * WEA messages). + * 3. The broadcast area for a WHAM shall be the union of the broadcast areas of the referenced + * WEA message. + * @param pdu cell broadcast pdu, including the header + * @return {@link GeoFencingTriggerMessage} instance */ - private static Pair<String, String> parseBody(SmsCbHeader header, byte[] pdu) { - int encoding; - String language = null; - boolean hasLanguageIndicator = false; - int dataCodingScheme = header.getDataCodingScheme(); - - // Extract encoding and language from DCS, as defined in 3gpp TS 23.038, - // section 5. - switch ((dataCodingScheme & 0xf0) >> 4) { - case 0x00: - encoding = SmsConstants.ENCODING_7BIT; - language = LANGUAGE_CODES_GROUP_0[dataCodingScheme & 0x0f]; - break; - - case 0x01: - hasLanguageIndicator = true; - if ((dataCodingScheme & 0x0f) == 0x01) { - encoding = SmsConstants.ENCODING_16BIT; - } else { - encoding = SmsConstants.ENCODING_7BIT; - } - break; + public static GeoFencingTriggerMessage createGeoFencingTriggerMessage(byte[] pdu) { + try { + // Header length + 1(number of page). ATIS-0700041 define the number of page of + // geo-fencing trigger message is 1. + int whamOffset = SmsCbHeader.PDU_HEADER_LENGTH + 1; + + BitStreamReader bitReader = new BitStreamReader(pdu, whamOffset); + int type = bitReader.read(4); + int length = bitReader.read(7); + // Skip the remained 5 bits + bitReader.skip(); + + int messageIdentifierCount = (length - 2) * 8 / 32; + List<CellBroadcastIdentity> cbIdentifiers = new ArrayList<>(); + for (int i = 0; i < messageIdentifierCount; i++) { + // Both messageIdentifier and serialNumber are 16 bits integers. + // ATIS-0700041 Section 5.1.6 + int messageIdentifier = bitReader.read(16); + int serialNumber = bitReader.read(16); + cbIdentifiers.add(new CellBroadcastIdentity(messageIdentifier, serialNumber)); + } + return new GeoFencingTriggerMessage(type, cbIdentifiers); + } catch (Exception ex) { + Slog.e(TAG, "create geo-fencing trigger failed, ex = " + ex.toString()); + return null; + } + } - case 0x02: - encoding = SmsConstants.ENCODING_7BIT; - language = LANGUAGE_CODES_GROUP_2[dataCodingScheme & 0x0f]; - break; + /** + * Parse the broadcast area and maximum wait time from the Warning Area Coordinates TLV. + * + * @param pdu Warning Area Coordinates TLV. + * @param wacOffset the offset of Warning Area Coordinates TLV. + * @return a pair with the first element is maximum wait time and the second is the broadcast + * area. The default value of the maximum wait time is 255 which means use the device default + * value. + */ + private static Pair<Integer, List<Geometry>> parseWarningAreaCoordinates( + byte[] pdu, int wacOffset) { + // little-endian + int wacDataLength = (pdu[wacOffset + 1] << 8) | pdu[wacOffset]; + int offset = wacOffset + 2; + + if (offset + wacDataLength > pdu.length) { + throw new IllegalArgumentException("Invalid wac data, expected the length of pdu at" + + "least " + offset + wacDataLength + ", actual is " + pdu.length); + } - case 0x03: - encoding = SmsConstants.ENCODING_7BIT; - break; + BitStreamReader bitReader = new BitStreamReader(pdu, offset); - case 0x04: - case 0x05: - switch ((dataCodingScheme & 0x0c) >> 2) { - case 0x01: - encoding = SmsConstants.ENCODING_8BIT; - break; - - case 0x02: - encoding = SmsConstants.ENCODING_16BIT; - break; - - case 0x00: - default: - encoding = SmsConstants.ENCODING_7BIT; - break; - } - break; + int maximumWaitTimeSec = SmsCbMessage.MAXIMUM_WAIT_TIME_NOT_SET; - case 0x06: - case 0x07: - // Compression not supported - case 0x09: - // UDH structure not supported - case 0x0e: - // Defined by the WAP forum not supported - throw new IllegalArgumentException("Unsupported GSM dataCodingScheme " - + dataCodingScheme); - - case 0x0f: - if (((dataCodingScheme & 0x04) >> 2) == 0x01) { - encoding = SmsConstants.ENCODING_8BIT; - } else { - encoding = SmsConstants.ENCODING_7BIT; - } - break; + List<Geometry> geo = new ArrayList<>(); + int remainedBytes = wacDataLength; + while (remainedBytes > 0) { + int type = bitReader.read(4); + int length = bitReader.read(10); + remainedBytes -= length; + // Skip the 2 remained bits + bitReader.skip(); - default: - // Reserved values are to be treated as 7-bit - encoding = SmsConstants.ENCODING_7BIT; - break; + switch (type) { + case CbGeoUtils.GEO_FENCING_MAXIMUM_WAIT_TIME: + maximumWaitTimeSec = bitReader.read(8); + break; + case CbGeoUtils.GEOMETRY_TYPE_POLYGON: + List<LatLng> latLngs = new ArrayList<>(); + // Each coordinate is represented by 44 bits integer. + // ATIS-0700041 5.2.4 Coordinate coding + int n = (length - 2) * 8 / 44; + for (int i = 0; i < n; i++) { + latLngs.add(getLatLng(bitReader)); + } + // Skip the padding bits + bitReader.skip(); + geo.add(new Polygon(latLngs)); + break; + case CbGeoUtils.GEOMETRY_TYPE_CIRCLE: + LatLng center = getLatLng(bitReader); + // radius = (wacRadius / 2^6). The unit of wacRadius is km, we use meter as the + // distance unit during geo-fencing. + // ATIS-0700041 5.2.5 radius coding + double radius = (bitReader.read(20) * 1.0 / (1 << 6)) * 1000.0; + geo.add(new Circle(center, radius)); + break; + default: + throw new IllegalArgumentException("Unsupported geoType = " + type); + } } + return new Pair(maximumWaitTimeSec, geo); + } - if (header.isUmtsFormat()) { - // Payload may contain multiple pages - int nrPages = pdu[SmsCbHeader.PDU_HEADER_LENGTH]; - - if (pdu.length < SmsCbHeader.PDU_HEADER_LENGTH + 1 + (PDU_BODY_PAGE_LENGTH + 1) - * nrPages) { - throw new IllegalArgumentException("Pdu length " + pdu.length + " does not match " - + nrPages + " pages"); - } + /** + * The coordinate is (latitude, longitude), represented by a 44 bits integer. + * The coding is defined in ATIS-0700041 5.2.4 + * @param bitReader + * @return coordinate (latitude, longitude) + */ + private static LatLng getLatLng(BitStreamReader bitReader) { + // wacLatitude = floor(((latitude + 90) / 180) * 2^22) + // wacLongitude = floor(((longitude + 180) / 360) * 2^22) + int wacLat = bitReader.read(22); + int wacLng = bitReader.read(22); + + // latitude = wacLatitude * 180 / 2^22 - 90 + // longitude = wacLongitude * 360 / 2^22 -180 + return new LatLng((wacLat * 180.0 / (1 << 22)) - 90, (wacLng * 360.0 / (1 << 22) - 180)); + } - StringBuilder sb = new StringBuilder(); + /** + * Parse and unpack the UMTS body text according to the encoding in the data coding scheme. + * + * @param header the message header to use + * @param pdu the PDU to decode + * @return a pair of string containing the language and body of the message in order + */ + private static Pair<String, String> parseUmtsBody(SmsCbHeader header, byte[] pdu) { + // Payload may contain multiple pages + int nrPages = pdu[SmsCbHeader.PDU_HEADER_LENGTH]; + String language = header.getDataCodingSchemeStructedData().language; + + if (pdu.length < SmsCbHeader.PDU_HEADER_LENGTH + 1 + (PDU_BODY_PAGE_LENGTH + 1) + * nrPages) { + throw new IllegalArgumentException("Pdu length " + pdu.length + " does not match " + + nrPages + " pages"); + } - for (int i = 0; i < nrPages; i++) { - // Each page is 82 bytes followed by a length octet indicating - // the number of useful octets within those 82 - int offset = SmsCbHeader.PDU_HEADER_LENGTH + 1 + (PDU_BODY_PAGE_LENGTH + 1) * i; - int length = pdu[offset + PDU_BODY_PAGE_LENGTH]; + StringBuilder sb = new StringBuilder(); - if (length > PDU_BODY_PAGE_LENGTH) { - throw new IllegalArgumentException("Page length " + length - + " exceeds maximum value " + PDU_BODY_PAGE_LENGTH); - } + for (int i = 0; i < nrPages; i++) { + // Each page is 82 bytes followed by a length octet indicating + // the number of useful octets within those 82 + int offset = SmsCbHeader.PDU_HEADER_LENGTH + 1 + (PDU_BODY_PAGE_LENGTH + 1) * i; + int length = pdu[offset + PDU_BODY_PAGE_LENGTH]; - Pair<String, String> p = unpackBody(pdu, encoding, offset, length, - hasLanguageIndicator, language); - language = p.first; - sb.append(p.second); + if (length > PDU_BODY_PAGE_LENGTH) { + throw new IllegalArgumentException("Page length " + length + + " exceeds maximum value " + PDU_BODY_PAGE_LENGTH); } - return new Pair<String, String>(language, sb.toString()); - } else { - // Payload is one single page - int offset = SmsCbHeader.PDU_HEADER_LENGTH; - int length = pdu.length - offset; - return unpackBody(pdu, encoding, offset, length, hasLanguageIndicator, language); + Pair<String, String> p = unpackBody(pdu, offset, length, + header.getDataCodingSchemeStructedData()); + language = p.first; + sb.append(p.second); } + return new Pair(language, sb.toString()); + + } + + /** + * Parse and unpack the GSM body text according to the encoding in the data coding scheme. + * @param header the message header to use + * @param pdu the PDU to decode + * @return a pair of string containing the language and body of the message in order + */ + private static Pair<String, String> parseGsmBody(SmsCbHeader header, byte[] pdu) { + // Payload is one single page + int offset = SmsCbHeader.PDU_HEADER_LENGTH; + int length = pdu.length - offset; + return unpackBody(pdu, offset, length, header.getDataCodingSchemeStructedData()); } /** - * Unpack body text from the pdu using the given encoding, position and - * length within the pdu + * Unpack body text from the pdu using the given encoding, position and length within the pdu. * * @param pdu The pdu - * @param encoding The encoding, as derived from the DCS * @param offset Position of the first byte to unpack * @param length Number of bytes to unpack - * @param hasLanguageIndicator true if the body text is preceded by a - * language indicator. If so, this method will as a side-effect - * assign the extracted language code into mLanguage - * @param language the language to return if hasLanguageIndicator is false + * @param dcs data coding scheme * @return a Pair of Strings containing the language and body of the message */ - private static Pair<String, String> unpackBody(byte[] pdu, int encoding, int offset, int length, - boolean hasLanguageIndicator, String language) { + private static Pair<String, String> unpackBody(byte[] pdu, int offset, int length, + DataCodingScheme dcs) { String body = null; - switch (encoding) { + String language = dcs.language; + switch (dcs.encoding) { case SmsConstants.ENCODING_7BIT: body = GsmAlphabet.gsm7BitPackedToString(pdu, offset, length * 8 / 7); - if (hasLanguageIndicator && body != null && body.length() > 2) { + if (dcs.hasLanguageIndicator && body != null && body.length() > 2) { // Language is two GSM characters followed by a CR. // The actual body text is offset by 3 characters. language = body.substring(0, 2); @@ -296,7 +363,7 @@ public class GsmSmsCbMessage { break; case SmsConstants.ENCODING_16BIT: - if (hasLanguageIndicator && pdu.length >= offset + 2) { + if (dcs.hasLanguageIndicator && pdu.length >= offset + 2) { // Language is two GSM characters. // The actual body text is offset by 2 bytes. language = GsmAlphabet.gsm7BitPackedToString(pdu, offset, 2); @@ -330,4 +397,105 @@ public class GsmSmsCbMessage { return new Pair<String, String>(language, body); } + + /** A class use to facilitate the processing of bits stream data. */ + private static final class BitStreamReader { + /** The bits stream represent by a bytes array. */ + private final byte[] mData; + + /** The offset of the current byte. */ + private int mCurrentOffset; + + /** + * The remained bits of the current byte which have not been read. The most significant + * will be read first, so the remained bits are always the least significant bits. + */ + private int mRemainedBit; + + /** + * Constructor + * @param data bit stream data represent by byte array. + * @param offset the offset of the first byte. + */ + BitStreamReader(byte[] data, int offset) { + mData = data; + mCurrentOffset = offset; + mRemainedBit = 8; + } + + /** + * Read the first {@code count} bits. + * @param count the number of bits need to read + * @return {@code bits} represent by an 32-bits integer, therefore {@code count} must be no + * greater than 32. + */ + public int read(int count) throws IndexOutOfBoundsException { + int val = 0; + while (count > 0) { + if (count >= mRemainedBit) { + val <<= mRemainedBit; + val |= mData[mCurrentOffset] & ((1 << mRemainedBit) - 1); + count -= mRemainedBit; + mRemainedBit = 8; + ++mCurrentOffset; + } else { + val <<= count; + val |= (mData[mCurrentOffset] & ((1 << mRemainedBit) - 1)) + >> (mRemainedBit - count); + mRemainedBit -= count; + count = 0; + } + } + return val; + } + + /** + * Skip the current bytes if the remained bits is less than 8. This is useful when + * processing the padding or reserved bits. + */ + public void skip() { + if (mRemainedBit < 8) { + mRemainedBit = 8; + ++mCurrentOffset; + } + } + } + + static final class GeoFencingTriggerMessage { + /** + * Indicate the list of active alerts share their warning area coordinates which means the + * broadcast area is the union of the broadcast areas of the active alerts in this list. + */ + public static final int TYPE_ACTIVE_ALERT_SHARE_WAC = 2; + + public final int type; + public final List<CellBroadcastIdentity> cbIdentifiers; + + GeoFencingTriggerMessage(int type, @NonNull List<CellBroadcastIdentity> cbIdentifiers) { + this.type = type; + this.cbIdentifiers = cbIdentifiers; + } + + boolean shouldShareBroadcastArea() { + return type == TYPE_ACTIVE_ALERT_SHARE_WAC; + } + + static final class CellBroadcastIdentity { + public final int messageIdentifier; + public final int serialNumber; + CellBroadcastIdentity(int messageIdentifier, int serialNumber) { + this.messageIdentifier = messageIdentifier; + this.serialNumber = serialNumber; + } + } + + @Override + public String toString() { + String identifiers = cbIdentifiers.stream() + .map(cbIdentifier ->String.format("(msgId = %d, serial = %d)", + cbIdentifier.messageIdentifier, cbIdentifier.serialNumber)) + .collect(Collectors.joining(",")); + return "triggerType=" + type + " identifiers=" + identifiers; + } + } } diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java b/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java index 541ca8d1e5c0..5ad2b9d8f682 100644 --- a/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java +++ b/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java @@ -215,9 +215,11 @@ public class SmsCbConstants { public static final int MESSAGE_ID_CMAS_ALERT_STATE_LOCAL_TEST_LANGUAGE = 0x112F; // 4399 - /** End of CMAS Message Identifier range (including future extensions). */ - public static final int MESSAGE_ID_CMAS_LAST_IDENTIFIER - = 0x112F; // 4399 + /** CMAS Message Identifier for CMAS geo fencing trigger message. */ + public static final int MESSAGE_ID_CMAS_GEO_FENCING_TRIGGER = 0x1130; // 4440 + + /** End of CMAS Message Identifier range. */ + public static final int MESSAGE_ID_CMAS_LAST_IDENTIFIER = MESSAGE_ID_CMAS_GEO_FENCING_TRIGGER; /** End of PWS Message Identifier range (includes ETWS, CMAS, and future extensions). */ public static final int MESSAGE_ID_PWS_LAST_IDENTIFIER diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java b/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java index 0dbc186ef2cf..acdc83867d2f 100644 --- a/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java +++ b/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java @@ -19,7 +19,10 @@ package com.android.internal.telephony.gsm; import android.telephony.SmsCbCmasInfo; import android.telephony.SmsCbEtwsInfo; +import com.android.internal.telephony.SmsConstants; + import java.util.Arrays; +import java.util.Locale; /** * Parses a 3GPP TS 23.041 cell broadcast message header. This class is public for use by @@ -32,6 +35,39 @@ import java.util.Arrays; * The raw PDU is no longer sent to SMS CB applications. */ public class SmsCbHeader { + /** + * Languages in the 0000xxxx DCS group as defined in 3GPP TS 23.038, section 5. + */ + private static final String[] LANGUAGE_CODES_GROUP_0 = { + Locale.GERMAN.getLanguage(), // German + Locale.ENGLISH.getLanguage(), // English + Locale.ITALIAN.getLanguage(), // Italian + Locale.FRENCH.getLanguage(), // French + new Locale("es").getLanguage(), // Spanish + new Locale("nl").getLanguage(), // Dutch + new Locale("sv").getLanguage(), // Swedish + new Locale("da").getLanguage(), // Danish + new Locale("pt").getLanguage(), // Portuguese + new Locale("fi").getLanguage(), // Finnish + new Locale("nb").getLanguage(), // Norwegian + new Locale("el").getLanguage(), // Greek + new Locale("tr").getLanguage(), // Turkish + new Locale("hu").getLanguage(), // Hungarian + new Locale("pl").getLanguage(), // Polish + null + }; + + /** + * Languages in the 0010xxxx DCS group as defined in 3GPP TS 23.038, section 5. + */ + private static final String[] LANGUAGE_CODES_GROUP_2 = { + new Locale("cs").getLanguage(), // Czech + new Locale("he").getLanguage(), // Hebrew + new Locale("ar").getLanguage(), // Arabic + new Locale("ru").getLanguage(), // Russian + new Locale("is").getLanguage(), // Icelandic + null, null, null, null, null, null, null, null, null, null, null + }; /** * Length of SMS-CB header @@ -84,6 +120,8 @@ public class SmsCbHeader { private final int mFormat; + private DataCodingScheme mDataCodingSchemeStructedData; + /** ETWS warning notification info. */ private final SmsCbEtwsInfo mEtwsInfo; @@ -162,6 +200,10 @@ public class SmsCbHeader { mNrOfPages = 1; } + if (mDataCodingScheme != -1) { + mDataCodingSchemeStructedData = new DataCodingScheme(mDataCodingScheme); + } + if (isEtwsMessage()) { boolean emergencyUserAlert = isEtwsEmergencyUserAlert(); boolean activatePopup = isEtwsPopupAlert(); @@ -199,6 +241,10 @@ public class SmsCbHeader { return mDataCodingScheme; } + DataCodingScheme getDataCodingSchemeStructedData() { + return mDataCodingSchemeStructedData; + } + int getPageIndex() { return mPageIndex; } @@ -448,4 +494,93 @@ public class SmsCbHeader { + ", DCS=0x" + Integer.toHexString(mDataCodingScheme) + ", page " + mPageIndex + " of " + mNrOfPages + '}'; } + + /** + * CBS Data Coding Scheme. + * Reference: 3GPP TS 23.038 version 15.0.0 section #5, CBS Data Coding Scheme + */ + public static final class DataCodingScheme { + public final int encoding; + public final String language; + public final boolean hasLanguageIndicator; + + public DataCodingScheme(int dataCodingScheme) { + int encoding = 0; + String language = null; + boolean hasLanguageIndicator = false; + + // Extract encoding and language from DCS, as defined in 3gpp TS 23.038, + // section 5. + switch ((dataCodingScheme & 0xf0) >> 4) { + case 0x00: + encoding = SmsConstants.ENCODING_7BIT; + language = LANGUAGE_CODES_GROUP_0[dataCodingScheme & 0x0f]; + break; + + case 0x01: + hasLanguageIndicator = true; + if ((dataCodingScheme & 0x0f) == 0x01) { + encoding = SmsConstants.ENCODING_16BIT; + } else { + encoding = SmsConstants.ENCODING_7BIT; + } + break; + + case 0x02: + encoding = SmsConstants.ENCODING_7BIT; + language = LANGUAGE_CODES_GROUP_2[dataCodingScheme & 0x0f]; + break; + + case 0x03: + encoding = SmsConstants.ENCODING_7BIT; + break; + + case 0x04: + case 0x05: + switch ((dataCodingScheme & 0x0c) >> 2) { + case 0x01: + encoding = SmsConstants.ENCODING_8BIT; + break; + + case 0x02: + encoding = SmsConstants.ENCODING_16BIT; + break; + + case 0x00: + default: + encoding = SmsConstants.ENCODING_7BIT; + break; + } + break; + + case 0x06: + case 0x07: + // Compression not supported + case 0x09: + // UDH structure not supported + case 0x0e: + // Defined by the WAP forum not supported + throw new IllegalArgumentException("Unsupported GSM dataCodingScheme " + + dataCodingScheme); + + case 0x0f: + if (((dataCodingScheme & 0x04) >> 2) == 0x01) { + encoding = SmsConstants.ENCODING_8BIT; + } else { + encoding = SmsConstants.ENCODING_7BIT; + } + break; + + default: + // Reserved values are to be treated as 7-bit + encoding = SmsConstants.ENCODING_7BIT; + break; + } + + + this.encoding = encoding; + this.language = language; + this.hasLanguageIndicator = hasLanguageIndicator; + } + } }
\ No newline at end of file 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); + } } /** |